1 /* 2 * This file is part of libplacebo. 3 * 4 * libplacebo is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * libplacebo is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef LIBPLACEBO_SHADERS_COLORSPACE_H_ 19 #define LIBPLACEBO_SHADERS_COLORSPACE_H_ 20 21 // Color space transformation shaders. These all input and output a color 22 // value (PL_SHADER_SIG_COLOR). 23 24 #include <libplacebo/colorspace.h> 25 #include <libplacebo/shaders.h> 26 27 PL_API_BEGIN 28 29 // Decode the color into normalized RGB, given a specified color_repr. This 30 // also takes care of additional pre- and post-conversions requires for the 31 // "special" color systems (XYZ, BT.2020-C, etc.). If `params` is left as NULL, 32 // it defaults to &pl_color_adjustment_neutral. 33 // 34 // Note: This function always returns PC-range RGB with pre-multiplied alpha. 35 // It mutates the pl_color_repr to reflect the change. 36 void pl_shader_decode_color(pl_shader sh, struct pl_color_repr *repr, 37 const struct pl_color_adjustment *params); 38 39 // Encodes a color from normalized, PC-range, pre-multiplied RGB into a given 40 // representation. That is, this performs the inverse operation of 41 // `pl_shader_decode_color` (sans color adjustments). 42 void pl_shader_encode_color(pl_shader sh, const struct pl_color_repr *repr); 43 44 // Linearize (expand) `vec4 color`, given a specified color space. In essence, 45 // this corresponds to the ITU-R EOTF. 46 // 47 // Note: Unlike the ITU-R EOTF, it never includes the OOTF - even for systems 48 // where the EOTF includes the OOTF (such as HLG). 49 void pl_shader_linearize(pl_shader sh, struct pl_color_space csp); 50 51 // Delinearize (compress), given a color space as output. This loosely 52 // corresponds to the inverse EOTF (not the OETF) in ITU-R terminology, again 53 // assuming a reference monitor. 54 void pl_shader_delinearize(pl_shader sh, struct pl_color_space csp); 55 56 struct pl_sigmoid_params { 57 // The center (bias) of the sigmoid curve. Must be between 0.0 and 1.0. 58 // If left as NULL, defaults to 0.75 59 float center; 60 61 // The slope (steepness) of the sigmoid curve. Must be between 1.0 and 20.0. 62 // If left as NULL, defaults to 6.5. 63 float slope; 64 }; 65 66 extern const struct pl_sigmoid_params pl_sigmoid_default_params; 67 68 // Applies a sigmoidal color transform to all channels. This helps avoid 69 // ringing artifacts during upscaling by bringing the color information closer 70 // to neutral and away from the extremes. If `params` is NULL, it defaults to 71 // &pl_sigmoid_default_params. 72 // 73 // Warning: This function clamps the input to the interval [0,1]; and as such 74 // it should *NOT* be used on already-decoded high-dynamic range content. 75 void pl_shader_sigmoidize(pl_shader sh, const struct pl_sigmoid_params *params); 76 77 // This performs the inverse operation to `pl_shader_sigmoidize`. 78 void pl_shader_unsigmoidize(pl_shader sh, const struct pl_sigmoid_params *params); 79 80 struct pl_peak_detect_params { 81 // Smoothing coefficient for the detected values. This controls the time 82 // parameter (tau) of an IIR low pass filter. In other words, it represent 83 // the cutoff period (= 1 / cutoff frequency) in frames. Frequencies below 84 // this length will be suppressed. This helps block out annoying 85 // "sparkling" or "flickering" due to small variations in frame-to-frame 86 // brightness. 87 // 88 // If left unset, this defaults to 100.0. 89 float smoothing_period; 90 91 // In order to avoid reacting sluggishly on scene changes as a result of 92 // the low-pass filter, we disable it when the difference between the 93 // current frame brightness and the average frame brightness exceeds a 94 // given threshold difference. But rather than a single hard cutoff, which 95 // would lead to weird discontinuities on fades, we gradually disable it 96 // over a small window of brightness ranges. These parameters control the 97 // lower and upper bounds of this window, in dB. 98 // 99 // The default values are 5.5 and 10.0, respectively. To disable this logic 100 // entirely, set either one to a negative value. 101 float scene_threshold_low; 102 float scene_threshold_high; 103 104 // In order to avoid clipping on fade-ins or other sudden brightness 105 // increases, we always over-estimate the peak brightness (in percent) 106 // by this amount, as a percentage of the actual measured peak. If left 107 // as 0.0, this logic is disabled. The default value is 0.05. 108 float overshoot_margin; 109 110 // To avoid over-tone-mapping very dark scenes (or black frames), this 111 // imposes a hard lower bound on the detected peak. If left as 0.0, it 112 // instead defaults to a value of 1.0. 113 float minimum_peak; 114 }; 115 116 extern const struct pl_peak_detect_params pl_peak_detect_default_params; 117 118 // This function can be used to measure the `sig_peak` and `sig_avg` of a 119 // video source automatically, using a compute shader. The measured values 120 // are smoothed automatically (depending on the parameters), so to keep track 121 // of the measured results over time, a shader object is used to hold the state. 122 // Returns false on failure initializing the peak detection object, or if 123 // compute shaders are not supported. 124 // 125 // It's important that the same shader object is used for successive frames 126 // belonging to the same source. If the source changes (e.g. due to a file 127 // change or seek), the user should not re-use the same state object. 128 // 129 // The parameter `csp` holds the representation of the color values that are 130 // the input to this function. (They must already be in decoded RGB form, i.e. 131 // alternate color representations are not supported) 132 bool pl_shader_detect_peak(pl_shader sh, struct pl_color_space csp, 133 pl_shader_obj *state, 134 const struct pl_peak_detect_params *params); 135 136 // After dispatching the above shader, this function *may* be used to read out 137 // the detected `sig_peak` and `sig_avg` directly. If the shader has never been 138 // dispatched yet, i.e. no information is available, this will return false. 139 // 140 // Note: This function will block until the shader object is no longer in use 141 // by the GPU, so its use should be avoided due to performance reasons. This 142 // function is *not* needed when the user only wants to use `pl_shader_color_map`, 143 // since that can ingest the peak detection state object directly. It only 144 // serves as a utility/debugging function. 145 bool pl_get_detected_peak(const pl_shader_obj state, 146 float *out_peak, float *out_avg); 147 148 // A collection of various tone mapping algorithms supported by libplacebo. 149 enum pl_tone_mapping_algorithm { 150 // Performs no tone-mapping, just clips out-of-gamut colors. Retains perfect 151 // color accuracy for in-gamut colors but completely destroys out-of-gamut 152 // information. 153 PL_TONE_MAPPING_CLIP, 154 155 // Generalization of the reinhard tone mapping algorithm to support an 156 // additional linear slope near black. The tone mapping parameter indicates 157 // the trade-off between the linear section and the non-linear section. 158 // Essentially, for param=0.5, every color value below 0.5 will be mapped 159 // linearly, with the higher values being non-linearly tone mapped. Values 160 // near 1.0 make this curve behave like CLIP, and values near 0.0 make this 161 // curve behave like REINHARD. The default value is 0.3, which provides a 162 // good balance between colorimetric accuracy and preserving out-of-gamut 163 // details. The name is derived from its function shape (ax+b)/(cx+d), which 164 // is known as a Möbius transformation in mathematics. 165 // 166 // This is the recommended tone mapping function to use when stretching an 167 // SDR curve over an HDR display (i.e. `dst.sig_scale > 1.0`), which can 168 // come in handy when calibrating a true HDR display to an SDR curve 169 // for compatibility with legacy display stacks. 170 PL_TONE_MAPPING_MOBIUS, 171 172 // Simple non-linear, global tone mapping algorithm. Named after Erik 173 // Reinhard. The parameter specifies the local contrast coefficient at the 174 // display peak. Essentially, a value of param=0.5 implies that the 175 // reference white will be about half as bright as when clipping. Defaults 176 // to 0.5, which results in the simplest formulation of this function. 177 PL_TONE_MAPPING_REINHARD, 178 179 // Piece-wise, filmic tone-mapping algorithm developed by John Hable for 180 // use in Uncharted 2, inspired by a similar tone-mapping algorithm used by 181 // Kodak. Popularized by its use in video games with HDR rendering. 182 // Preserves both dark and bright details very well, but comes with the 183 // drawback of darkening the overall image quite significantly. Users are 184 // recommended to use HDR peak detection to compensate for the missing 185 // brightness. This is sort of similar to REINHARD tone-mapping + parameter 186 // 0.24. 187 PL_TONE_MAPPING_HABLE, 188 189 // Fits a gamma (power) function to transfer between the source and target 190 // color spaces. This preserves details at all scales fairly accurately, 191 // but can result in an image with a muted or dull appearance. Best when 192 // combined with peak detection. The parameter is used as the exponent of 193 // the gamma function, defaulting to 1.8. 194 PL_TONE_MAPPING_GAMMA, 195 196 // Linearly stretches the source gamut to the destination gamut. This will 197 // preserve all details accurately, but results in a significantly darker 198 // image. Best when combined with peak detection. The parameter can be used 199 // as an additional scaling coefficient to make the image (linearly) 200 // brighter or darker. Defaults to 1.0. 201 PL_TONE_MAPPING_LINEAR, 202 203 // EETF from the ITU-R Report BT.2390, a hermite spline roll-off with 204 // linear segment. Not configurable. 205 PL_TONE_MAPPING_BT_2390, 206 207 PL_TONE_MAPPING_ALGORITHM_COUNT, 208 }; 209 210 struct pl_color_map_params { 211 // The rendering intent to use for RGB->RGB primary conversions. 212 // Defaults to PL_INTENT_RELATIVE_COLORIMETRIC. 213 enum pl_rendering_intent intent; 214 215 // Algorithm and configuration used for tone-mapping. For non-tunable 216 // algorithms, the `param` is ignored. If the tone mapping parameter is 217 // left as 0.0, the tone-mapping curve's preferred default parameter will 218 // be used. The default algorithm is PL_TONE_MAPPING_BT_2390. 219 enum pl_tone_mapping_algorithm tone_mapping_algo; 220 float tone_mapping_param; 221 222 // The tone mapping algorithm can operate in two modes: The first is known 223 // as "desaturating" (per-channel) mode, aka "hollywood/TV" style tone 224 // mapping; and the second is called "saturating" (linear) mode, aka 225 // "chromatic/colorimetric" tone mapping. The saturating tone mapping 226 // algorithm preserves colors from the source faithfully, but can suffer 227 // from weird-looking, blown out highlights in very bright regions. To 228 // provide a trade-off between these two approaches, we mix the result 229 // between the two approaches based on the overall brightness of the pixel. 230 // 231 // These settings control the parameter of this mixing. The `strength` 232 // controls how much of the desaturating result is mixed into the pixel, 233 // with values ranging from 0.0 to 1.0 - while the `base` and `exponent` 234 // controls the placement and steepness of the mixing curve. 235 // 236 // If you want to always use the saturating/colorimetric tone mapping, set 237 // the strength to 0.0. If you want to always use the desaturating/hollywood 238 // tone mapping, set the strength to 1.0 and the exponent to 0.0. The 239 // default settings are strength 0.90, exponent 0.2 and base 0.18, which 240 // provide a fairly strong preset while nonetheless preserving some amount 241 // of colorimetric accuracy. 242 float desaturation_strength; 243 float desaturation_exponent; 244 float desaturation_base; 245 246 // When tone mapping, this represents the upper limit of how much the 247 // scene may be over-exposed in order to hit the `dst.sig_avg` target. 248 // If left unset, defaults to 1.0, which corresponds to no boost. 249 float max_boost; 250 251 // If true, enables the gamut warning feature. This will visibly highlight 252 // all out-of-gamut colors (by coloring them pink), if they would have been 253 // clipped as a result of gamut or tone mapping. 254 bool gamut_warning; 255 256 // If true, enables colorimetric clipping. This will colorimetrically clip 257 // out-of-gamut colors by desaturating them until they hit the boundary of 258 // the permissible color volume, rather than by hard-clipping. This mode of 259 // clipping preserves luminance between the source and the destination, at 260 // the cost of introducing some color distortion in the opposite direction. 261 bool gamut_clipping; 262 }; 263 264 extern const struct pl_color_map_params pl_color_map_default_params; 265 266 // Maps `vec4 color` from one color space to another color space according 267 // to the parameters (described in greater depth above). If `params` is left 268 // as NULL, it defaults to `&pl_color_map_default_params`. If `prelinearized` 269 // is true, the logic will assume the input has already been linearized by the 270 // caller (e.g. as part of a previous linear light scaling operation). 271 // 272 // If `peak_detect_state` is set to a valid peak detection state object (as 273 // created by `pl_shader_detect_peak`), the detected values will be used in 274 // place of `src.sig_peak` / `src.sig_avg`. 275 // 276 // Note: The peak detection state object is only updated after the shader is 277 // dispatched, so if `pl_shader_detect_peak` is called as part of the same 278 // shader as `pl_shader_color_map`, the results will end up delayed by one 279 // frame. If frame-level accuracy is desired, then users should call 280 // `pl_shader_detect_peak` separately and dispatch the resulting shader 281 // *before* dispatching this one. 282 void pl_shader_color_map(pl_shader sh, 283 const struct pl_color_map_params *params, 284 struct pl_color_space src, struct pl_color_space dst, 285 pl_shader_obj *peak_detect_state, 286 bool prelinearized); 287 288 // Applies a set of cone distortion parameters to `vec4 color` in a given color 289 // space. This can be used to simulate color blindness. See `pl_cone_params` 290 // for more information. 291 void pl_shader_cone_distort(pl_shader sh, struct pl_color_space csp, 292 const struct pl_cone_params *params); 293 294 enum pl_dither_method { 295 // Dither with blue noise. Very high quality, but requires the use of a 296 // LUT. Warning: Computing a blue noise texture with a large size can be 297 // very slow, however this only needs to be performed once. Even so, using 298 // this with a `lut_size` greater than 6 is generally ill-advised. This is 299 // the preferred/default dither method. 300 PL_DITHER_BLUE_NOISE, 301 302 // Dither with an ordered (bayer) dither matrix, using a LUT. Low quality, 303 // and since this also uses a LUT, there's generally no advantage to picking 304 // this instead of `PL_DITHER_BLUE_NOISE`. It's mainly there for testing. 305 PL_DITHER_ORDERED_LUT, 306 307 // The same as `PL_DITHER_ORDERED_LUT`, but uses fixed function math instead 308 // of a LUT. This is faster, but only supports a fixed dither matrix size 309 // of 16x16 (equal to a `lut_size` of 4). Requires GLSL 130+. 310 PL_DITHER_ORDERED_FIXED, 311 312 // Dither with white noise. This does not require a LUT and is fairly cheap 313 // to compute. Unlike the other modes it doesn't show any repeating 314 // patterns either spatially or temporally, but the downside is that this 315 // is visually fairly jarring due to the presence of low frequencies in the 316 // noise spectrum. Used as a fallback when the above methods are not 317 // available. 318 PL_DITHER_WHITE_NOISE, 319 320 PL_DITHER_METHOD_COUNT, 321 }; 322 323 struct pl_dither_params { 324 // The source of the dither noise to use. 325 enum pl_dither_method method; 326 327 // For the dither methods which require the use of a LUT, this controls 328 // the size of the LUT (base 2). If left as NULL, this defaults to 6, which 329 // is equivalent to a 64x64 dither matrix. Must not be larger than 8. 330 int lut_size; 331 332 // Enables temporal dithering. This reduces the persistence of dithering 333 // artifacts by perturbing the dithering matrix per frame. 334 // Warning: This can cause nasty aliasing artifacts on some LCD screens. 335 bool temporal; 336 }; 337 338 extern const struct pl_dither_params pl_dither_default_params; 339 340 // Dither the colors to a lower depth, given in bits. This can be used on input 341 // colors of any precision. Basically, this rounds the colors to only linear 342 // multiples of the stated bit depth. The average intensity of the result 343 // will not change (i.e., the dither noise is balanced in both directions). 344 // If `params` is NULL, it defaults to &pl_dither_default_params. 345 // 346 // For the dither methods which require the use of a LUT, `dither_state` must 347 // be set to a valid pointer. To avoid thrashing the resource, users should 348 // avoid trying to re-use the same LUT for different dither configurations. If 349 // passed as NULL, libplacebo will automatically fall back to dither algorithms 350 // that don't require the use of a LUT. 351 // 352 // Warning: This dithering algorithm is not gamma-invariant; so using it for 353 // very low bit depths (below 4 or so) will noticeably increase the brightness 354 // of the resulting image. When doing low bit depth dithering for aesthetic 355 // purposes, it's recommended that the user explicitly (de)linearize the colors 356 // before and after this algorithm. 357 void pl_shader_dither(pl_shader sh, int new_depth, 358 pl_shader_obj *dither_state, 359 const struct pl_dither_params *params); 360 361 PL_API_END 362 363 #endif // LIBPLACEBO_SHADERS_COLORSPACE_H_ 364