diff options
author | Michael Kowalski <makowalski@nvidia.com> | 2022-09-23 23:56:14 +0300 |
---|---|---|
committer | Michael Kowalski <makowalski@nvidia.com> | 2022-09-23 23:56:14 +0300 |
commit | b2ad97ba97f3e55d1dd463e29ca0b2ec6fe761e1 (patch) | |
tree | f94394835c6b731e4e379f4ef48fb78b4af4b9ca /source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl | |
parent | b31807c75f0c18c43ac6979e6da57dc9d420167a (diff) | |
parent | 7e980f2b8cb96aa6d04dc72899d08473367eeeb9 (diff) |
Merge branch 'master' into tmp-usd-alab-v2-T100452tmp-usd-alab-v2-T100452
Diffstat (limited to 'source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl')
-rw-r--r-- | source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl index db8e114ec7a..e68c173c055 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl @@ -26,9 +26,29 @@ vec3 extrapolate_if_needed(vec3 parameters, vec3 values, vec3 start_slopes, vec3 return values + parameters * slopes; } -/* Curve maps are stored in sampler objects that are evaluated in the [0, 1] range, so normalize - * parameters accordingly. */ -#define NORMALIZE_PARAMETER(parameter, minimum, range) ((parameter - minimum) * range) +/* Curve maps are stored in texture samplers that are evaluated in the [0, 1] range, so normalize + * the parameters accordingly. Additionally, ensure that the parameters evaluate the sampler at the + * center of the pixels, because samplers are evaluated using linear interpolation. */ +float normalize_parameter(float parameter, float minimum, float range_divider) +{ + float normalized_parameter = (parameter - minimum) * range_divider; + + /* Curve maps have a fixed width of 257. We offset by the equivalent of half a pixel and scale + * down such that the normalized parameter 1.0 corresponds to the center of the last pixel. */ + float sampler_offset = 0.5 / 257.0; + float sampler_scale = 1.0 - (1.0 / 257.0); + return normalized_parameter * sampler_scale + sampler_offset; +} + +/* Same as normalize_parameter but vectorized. */ +vec3 normalize_parameters(vec3 parameters, vec3 minimums, vec3 range_dividers) +{ + vec3 normalized_parameters = (parameters - minimums) * range_dividers; + + float sampler_offset = 0.5 / 257.0; + float sampler_scale = 1.0 - (1.0 / 257.0); + return normalized_parameters * sampler_scale + sampler_offset; +} void curves_combined_rgb(float factor, vec4 color, @@ -46,7 +66,7 @@ void curves_combined_rgb(float factor, /* First, evaluate alpha curve map at all channels. The alpha curve is the Combined curve in the * UI. */ - vec3 parameters = NORMALIZE_PARAMETER(balanced.rgb, range_minimums.aaa, range_dividers.aaa); + vec3 parameters = normalize_parameters(balanced.rgb, range_minimums.aaa, range_dividers.aaa); result.r = texture(curve_map, vec2(parameters.x, layer)).a; result.g = texture(curve_map, vec2(parameters.y, layer)).a; result.b = texture(curve_map, vec2(parameters.z, layer)).a; @@ -55,13 +75,14 @@ void curves_combined_rgb(float factor, result.rgb = extrapolate_if_needed(parameters, result.rgb, start_slopes.aaa, end_slopes.aaa); /* Then, evaluate each channel on its curve map. */ - parameters = NORMALIZE_PARAMETER(result.rgb, range_minimums.rgb, range_dividers.rgb); + parameters = normalize_parameters(result.rgb, range_minimums.rgb, range_dividers.rgb); result.r = texture(curve_map, vec2(parameters.r, layer)).r; result.g = texture(curve_map, vec2(parameters.g, layer)).g; result.b = texture(curve_map, vec2(parameters.b, layer)).b; /* Then, extrapolate again if needed. */ result.rgb = extrapolate_if_needed(parameters, result.rgb, start_slopes.rgb, end_slopes.rgb); + result.a = color.a; result = mix(color, result, factor); @@ -83,13 +104,14 @@ void curves_combined_only(float factor, /* Evaluate alpha curve map at all channels. The alpha curve is the Combined curve in the * UI. */ - vec3 parameters = NORMALIZE_PARAMETER(balanced.rgb, range_minimum, range_divider); + vec3 parameters = normalize_parameters(balanced.rgb, vec3(range_minimum), vec3(range_divider)); result.r = texture(curve_map, vec2(parameters.x, layer)).a; result.g = texture(curve_map, vec2(parameters.y, layer)).a; result.b = texture(curve_map, vec2(parameters.z, layer)).a; /* Then, extrapolate if needed. */ result.rgb = extrapolate_if_needed(parameters, result.rgb, vec3(start_slope), vec3(end_slope)); + result.a = color.a; result = mix(color, result, factor); @@ -147,8 +169,8 @@ void curves_film_like(float factor, /* Evaluate alpha curve map at the maximum and minimum channels. The alpha curve is the Combined * curve in the UI. */ - float min_parameter = NORMALIZE_PARAMETER(minimum, range_minimum, range_divider); - float max_parameter = NORMALIZE_PARAMETER(maximum, range_minimum, range_divider); + float min_parameter = normalize_parameter(minimum, range_minimum, range_divider); + float max_parameter = normalize_parameter(maximum, range_minimum, range_divider); float new_min = texture(curve_map, vec2(min_parameter, layer)).a; float new_max = texture(curve_map, vec2(max_parameter, layer)).a; @@ -165,6 +187,7 @@ void curves_film_like(float factor, vec3 median_or_min = mix(vec3(new_median), vec3(new_min), channel_is_min); bvec3 channel_is_max = equal(balanced.rgb, vec3(maximum)); result.rgb = mix(median_or_min, vec3(new_max), channel_is_max); + result.a = color.a; result = mix(color, result, clamp(factor, 0.0, 1.0)); @@ -180,7 +203,7 @@ void curves_vector(vec3 vector, out vec3 result) { /* Evaluate each component on its curve map. */ - vec3 parameters = NORMALIZE_PARAMETER(vector, range_minimums, range_dividers); + vec3 parameters = normalize_parameters(vector, range_minimums, range_dividers); result.x = texture(curve_map, vec2(parameters.x, layer)).x; result.y = texture(curve_map, vec2(parameters.y, layer)).y; result.z = texture(curve_map, vec2(parameters.z, layer)).z; @@ -214,7 +237,7 @@ void curves_float(float value, out float result) { /* Evaluate the normalized value on the first curve map. */ - float parameter = NORMALIZE_PARAMETER(value, range_minimum, range_divider); + float parameter = normalize_parameter(value, range_minimum, range_divider); result = texture(curve_map, vec2(parameter, layer)).x; /* Then, extrapolate if needed. */ |