obs-filters: Reduced GPU work for common LUT cases
Add "Passthrough Alpha" checkbox where alpha doesn't need sanitization. Remove domain checks, Intel UHD Graphics 750: 591 µs -> 532 µs Alpha passthrough, Intel UHD Graphics 750: 532 µs -> 486 µs
This commit is contained in:
parent
873e3a0aae
commit
6eec19771a
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user