From 22a7fd1cf3b9cd6b2c306e234f22885b9ddcc40f Mon Sep 17 00:00:00 2001 From: jpark37 Date: Tue, 19 Jan 2021 11:17:50 -0800 Subject: [PATCH] obs-filters: Apply color grade filter in linear space --- plugins/obs-filters/color-grade-filter.c | 2 ++ .../data/color_grade_filter.effect | 28 ++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/plugins/obs-filters/color-grade-filter.c b/plugins/obs-filters/color-grade-filter.c index 8d814e69b..d7849063d 100644 --- a/plugins/obs-filters/color-grade-filter.c +++ b/plugins/obs-filters/color-grade-filter.c @@ -452,8 +452,10 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect) param = gs_effect_get_param_by_name(filter->effect, "cube_width_i"); gs_effect_set_float(param, 1.0f / filter->cube_width); + const bool previous = gs_set_linear_srgb(true); obs_source_process_filter_tech_end(filter->context, filter->effect, 0, 0, tech_name); + gs_set_linear_srgb(previous); UNUSED_PARAMETER(effect); } diff --git a/plugins/obs-filters/data/color_grade_filter.effect b/plugins/obs-filters/data/color_grade_filter.effect index 426009de1..ba05bc409 100644 --- a/plugins/obs-filters/data/color_grade_filter.effect +++ b/plugins/obs-filters/data/color_grade_filter.effect @@ -35,9 +35,29 @@ VertDataOut VSDefault(VertDataIn v_in) return vert_out; } +float srgb_linear_to_nonlinear_channel(float u) +{ + return (u <= 0.0031308) ? (12.92 * u) : ((1.055 * pow(u, 1.0 / 2.4)) - 0.055); +} + +float4 srgb_linear_to_nonlinear(float4 v) +{ + return float4(srgb_linear_to_nonlinear_channel(v.r), srgb_linear_to_nonlinear_channel(v.g), srgb_linear_to_nonlinear_channel(v.b), v.a); +} + +float srgb_nonlinear_to_linear_channel(float u) +{ + return (u <= 0.04045) ? (u / 12.92) : pow((u + 0.055) / 1.055, 2.4); +} + +float4 srgb_nonlinear_to_linear(float4 v) +{ + return float4(srgb_nonlinear_to_linear_channel(v.r), srgb_nonlinear_to_linear_channel(v.g), srgb_nonlinear_to_linear_channel(v.b), v.a); +} + float4 LUT1D(VertDataOut v_in) : TARGET { - float4 textureColor = image.Sample(textureSampler, v_in.uv); + float4 textureColor = srgb_linear_to_nonlinear(image.Sample(textureSampler, v_in.uv)); if (textureColor.r >= domain_min.r && textureColor.r <= domain_max.r) { float u = textureColor.r * clut_scale.r + clut_offset.r; @@ -57,12 +77,12 @@ float4 LUT1D(VertDataOut v_in) : TARGET textureColor.b = lerp(textureColor.b, channel, clut_amount); } - return textureColor; + return srgb_nonlinear_to_linear(textureColor); } float4 LUT3D(VertDataOut v_in) : TARGET { - float4 textureColor = image.Sample(textureSampler, v_in.uv); + float4 textureColor = srgb_linear_to_nonlinear(image.Sample(textureSampler, v_in.uv)); float r = textureColor.r; float g = textureColor.g; float b = textureColor.b; @@ -145,7 +165,7 @@ float4 LUT3D(VertDataOut v_in) : TARGET textureColor.rgb = lerp(textureColor.rgb, luttedColor, clut_amount); } - return textureColor; + return srgb_nonlinear_to_linear(textureColor); } technique Draw1D