diff --git a/plugins/obs-filters/color-grade-filter.c b/plugins/obs-filters/color-grade-filter.c index 7daf39111..839e82a45 100644 --- a/plugins/obs-filters/color-grade-filter.c +++ b/plugins/obs-filters/color-grade-filter.c @@ -8,9 +8,11 @@ #define SETTING_IMAGE_PATH "image_path" #define SETTING_CLUT_AMOUNT "clut_amount" +#define SETTING_PASSTHROUGH_ALPHA "passthrough_alpha" #define TEXT_IMAGE_PATH obs_module_text("Path") #define TEXT_AMOUNT obs_module_text("Amount") +#define TEXT_PASSTHROUGH_ALPHA obs_module_text("PassthroughAlpha") /* clang-format on */ @@ -33,11 +35,12 @@ struct lut_filter_data { char *file; float clut_amount; - enum clut_dimension clut_dim; struct vec3 clut_scale; struct vec3 clut_offset; struct vec3 domain_min; struct vec3 domain_max; + const char *clut_texture_name; + const char *tech_name; }; static const char *color_grade_filter_get_name(void *unused) @@ -253,6 +256,8 @@ static void color_grade_filter_update(void *data, obs_data_t *settings) const double clut_amount = obs_data_get_double(settings, SETTING_CLUT_AMOUNT); + const bool passthrough_alpha = + obs_data_get_bool(settings, SETTING_PASSTHROUGH_ALPHA); bfree(filter->file); if (path) @@ -269,6 +274,10 @@ static void color_grade_filter_update(void *data, obs_data_t *settings) filter->target = NULL; obs_leave_graphics(); + enum clut_dimension clut_dim = CLUT_3D; + const char *clut_texture_name = "clut_3d"; + const char *tech_name = "Draw3D"; + if (path) { vec3_set(&filter->domain_min, 0.0f, 0.0f, 0.0f); vec3_set(&filter->domain_max, 1.0f, 1.0f, 1.0f); @@ -277,11 +286,26 @@ static void color_grade_filter_update(void *data, obs_data_t *settings) if (ext && astrcmpi(ext, ".cube") == 0) { filter->cube_data = load_cube_file( path, &filter->cube_width, &filter->domain_min, - &filter->domain_max, &filter->clut_dim); + &filter->domain_max, &clut_dim); } else { gs_image_file_init(&filter->image, path); filter->cube_width = LUT_WIDTH; - filter->clut_dim = CLUT_3D; + } + + if (clut_dim == CLUT_1D) { + clut_texture_name = "clut_1d"; + tech_name = "Draw1D"; + } else if ((filter->domain_min.x > 0.f) || + (filter->domain_min.y > 0.f) || + (filter->domain_min.z > 0.f) || + (filter->domain_max.x < 1.f) || + (filter->domain_max.y < 1.f) || + (filter->domain_max.z < 1.f)) { + tech_name = "DrawDomain3D"; + } else if (clut_amount < 1.0) { + tech_name = "DrawAmount3D"; + } else if (!passthrough_alpha) { + tech_name = "DrawAlpha3D"; } } @@ -300,7 +324,7 @@ static void color_grade_filter_update(void *data, obs_data_t *settings) vec3_set(&filter->clut_offset, offset, offset, offset); } else if (filter->cube_data) { const uint32_t width = filter->cube_width; - if (filter->clut_dim == CLUT_1D) { + if (clut_dim == CLUT_1D) { filter->target = gs_texture_create( width, 1, GS_RGBA16F, 1, (const uint8_t **)&filter->cube_data, @@ -337,6 +361,8 @@ static void color_grade_filter_update(void *data, obs_data_t *settings) } filter->clut_amount = (float)clut_amount; + filter->clut_texture_name = clut_texture_name; + filter->tech_name = tech_name; char *effect_path = obs_module_file("color_grade_filter.effect"); gs_effect_destroy(filter->effect); @@ -348,7 +374,8 @@ static void color_grade_filter_update(void *data, obs_data_t *settings) static void color_grade_filter_defaults(obs_data_t *settings) { - obs_data_set_default_double(settings, SETTING_CLUT_AMOUNT, 1); + obs_data_set_default_double(settings, SETTING_CLUT_AMOUNT, 1.0); + obs_data_set_default_bool(settings, SETTING_PASSTHROUGH_ALPHA, false); } static obs_properties_t *color_grade_filter_properties(void *data) @@ -380,6 +407,8 @@ static obs_properties_t *color_grade_filter_properties(void *data) OBS_PATH_FILE, filter_str.array, path.array); obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT, TEXT_AMOUNT, 0, 1, 0.0001); + obs_properties_add_bool(props, SETTING_PASSTHROUGH_ALPHA, + TEXT_PASSTHROUGH_ALPHA); dstr_free(&filter_str); dstr_free(&path); @@ -426,17 +455,12 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect) } if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) { return; - - const char *clut_texture_name = "clut_3d"; - const char *tech_name = "Draw3D"; - if (filter->clut_dim == CLUT_1D) { - clut_texture_name = "clut_1d"; - tech_name = "Draw1D"; } - param = gs_effect_get_param_by_name(filter->effect, clut_texture_name); + param = gs_effect_get_param_by_name(filter->effect, + filter->clut_texture_name); gs_effect_set_texture_srgb(param, filter->target); param = gs_effect_get_param_by_name(filter->effect, "clut_amount"); @@ -458,7 +482,7 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect) gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); obs_source_process_filter_tech_end(filter->context, filter->effect, 0, - 0, tech_name); + 0, filter->tech_name); gs_blend_state_pop(); diff --git a/plugins/obs-filters/data/color_grade_filter.effect b/plugins/obs-filters/data/color_grade_filter.effect index f265be338..2b902d7d4 100644 --- a/plugins/obs-filters/data/color_grade_filter.effect +++ b/plugins/obs-filters/data/color_grade_filter.effect @@ -72,6 +72,44 @@ float4 LUT1D(VertDataOut v_in) : TARGET } float4 LUT3D(VertDataOut v_in) : TARGET +{ + float4 textureColor = image.Sample(textureSampler, v_in.uv); + float3 nonlinear = srgb_linear_to_nonlinear(textureColor.rgb); + + float3 clut_uvw = nonlinear * clut_scale + clut_offset; + textureColor.rgb = clut_3d.Sample(textureSampler, clut_uvw).rgb; + + return textureColor; +} + +float4 LUTAlpha3D(VertDataOut v_in) : TARGET +{ + float4 textureColor = image.Sample(textureSampler, v_in.uv); + textureColor.rgb = max(float3(0.0, 0.0, 0.0), textureColor.rgb / textureColor.a); + float3 nonlinear = srgb_linear_to_nonlinear(textureColor.rgb); + + float3 clut_uvw = nonlinear * clut_scale + clut_offset; + textureColor.rgb = clut_3d.Sample(textureSampler, clut_uvw).rgb; + + textureColor.rgb *= textureColor.a; + return textureColor; +} + +float4 LUTAmount3D(VertDataOut v_in) : TARGET +{ + float4 textureColor = image.Sample(textureSampler, v_in.uv); + textureColor.rgb = max(float3(0.0, 0.0, 0.0), textureColor.rgb / textureColor.a); + float3 nonlinear = srgb_linear_to_nonlinear(textureColor.rgb); + + float3 clut_uvw = nonlinear * clut_scale + clut_offset; + float3 luttedColor = clut_3d.Sample(textureSampler, clut_uvw).rgb; + textureColor.rgb = lerp(textureColor.rgb, luttedColor, clut_amount); + + textureColor.rgb *= textureColor.a; + return textureColor; +} + +float4 LUTDomain3D(VertDataOut v_in) : TARGET { float4 textureColor = image.Sample(textureSampler, v_in.uv); textureColor.rgb = max(float3(0.0, 0.0, 0.0), textureColor.rgb / textureColor.a); @@ -110,3 +148,30 @@ technique Draw3D pixel_shader = LUT3D(v_in); } } + +technique DrawAlpha3D +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = LUTAlpha3D(v_in); + } +} + +technique DrawAmount3D +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = LUTAmount3D(v_in); + } +} + +technique DrawDomain3D +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = LUTDomain3D(v_in); + } +} diff --git a/plugins/obs-filters/data/locale/en-US.ini b/plugins/obs-filters/data/locale/en-US.ini index 64ff2b811..c869d239a 100644 --- a/plugins/obs-filters/data/locale/en-US.ini +++ b/plugins/obs-filters/data/locale/en-US.ini @@ -79,6 +79,7 @@ NoiseSuppress.Method.nvafx="NVIDIA Noise Removal (good quality, no CPU usage)" Saturation="Saturation" HueShift="Hue Shift" Amount="Amount" +PassthroughAlpha="Passthrough Alpha" Compressor="Compressor" Compressor.Ratio="Ratio" Compressor.Threshold="Threshold"