Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to fix the color consistency issue #93

Merged
merged 7 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions data/shaders/render_output.effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
uniform float4x4 ViewProj;
uniform texture2d image;
uniform texture2d output_image;

sampler_state textureSampler{
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
MinLOD = 0;
MaxLOD = 0;
};

struct VertData
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};

VertData mainTransform(VertData v_in)
{
v_in.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
return v_in;
}

float srgb_nonlinear_to_linear_channel(float u)
{
return (u <= 0.04045) ? (u / 12.92) : pow((u + 0.055) / 1.055, 2.4);
}

float3 srgb_nonlinear_to_linear(float3 v)
{
return float3(srgb_nonlinear_to_linear_channel(v.r), srgb_nonlinear_to_linear_channel(v.g), srgb_nonlinear_to_linear_channel(v.b));
}

float4 mainImage(VertData v_in) : TARGET
{
float4 px = output_image.Sample(textureSampler, v_in.uv);
px.xyz = srgb_nonlinear_to_linear(px.xyz);
return px;
}

technique Draw
{
pass
{
vertex_shader = mainTransform(v_in);
pixel_shader = mainImage(v_in);
}
}
134 changes: 113 additions & 21 deletions src/obs-composite-blur-filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
struct obs_source_info obs_composite_blur = {
.id = "obs_composite_blur",
.type = OBS_SOURCE_TYPE_FILTER,
.output_flags = OBS_SOURCE_VIDEO,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_SRGB,
.get_name = composite_blur_name,
.create = composite_blur_create,
.destroy = composite_blur_destroy,
Expand Down Expand Up @@ -135,6 +135,8 @@ static void *composite_blur_create(obs_data_t *settings, obs_source_t *source)
filter->mask_source_source = NULL;
filter->mask_source_invert = false;

filter->param_output_image = NULL;

da_init(filter->kernel);
//composite_blur_defaults(settings);
obs_source_update(source, settings);
Expand Down Expand Up @@ -167,6 +169,9 @@ static void composite_blur_destroy(void *data)
if (filter->effect_mask_effect) {
gs_effect_destroy(filter->effect_mask_effect);
}
if (filter->output_effect) {
gs_effect_destroy(filter->output_effect);
}
if (filter->render) {
gs_texrender_destroy(filter->render);
}
Expand Down Expand Up @@ -405,14 +410,28 @@ static void get_input_source(composite_blur_filter_data_t *filter)
{
gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT);

const enum gs_color_space preferred_spaces[] = {
GS_CS_SRGB,
GS_CS_SRGB_16F,
GS_CS_709_EXTENDED,
};

const enum gs_color_space source_space = obs_source_get_color_space(
obs_filter_get_target(filter->context),
OBS_COUNTOF(preferred_spaces), preferred_spaces);

const enum gs_color_format format = gs_get_format_from_space(source_space);

filter->input_texrender =
create_or_reset_texrender(filter->input_texrender);
if (obs_source_process_filter_begin(filter->context, GS_RGBA,
if (obs_source_process_filter_begin_with_color_space(
filter->context, format, source_space,
OBS_ALLOW_DIRECT_RENDERING) &&
gs_texrender_begin(filter->input_texrender, filter->width,
filter->height)) {

set_blending_parameters();
//gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
gs_ortho(0.0f, (float)filter->width, 0.0f,
(float)filter->height, -100.0f, 100.0f);
obs_source_process_filter_end(filter->context, pass_through,
Expand All @@ -421,17 +440,30 @@ static void get_input_source(composite_blur_filter_data_t *filter)
gs_blend_state_pop();
}
}
//static void get_input_source(composite_blur_filter_data_t *filter)
//{
// gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT);
//
// filter->input_texrender =
// create_or_reset_texrender(filter->input_texrender);
// if (obs_source_process_filter_begin(filter->context, GS_RGBA,
// OBS_ALLOW_DIRECT_RENDERING) &&
// gs_texrender_begin(filter->input_texrender, filter->width,
// filter->height)) {
//
// set_blending_parameters();
// gs_ortho(0.0f, (float)filter->width, 0.0f,
// (float)filter->height, -100.0f, 100.0f);
// obs_source_process_filter_end(filter->context, pass_through,
// filter->width, filter->height);
// gs_texrender_end(filter->input_texrender);
// gs_blend_state_pop();
// }
//}


static void draw_output_to_source(composite_blur_filter_data_t *filter)
{
gs_texture_t *texture =
gs_texrender_get_texture(filter->output_texrender);
gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT);
gs_eparam_t *param = gs_effect_get_param_by_name(pass_through, "image");
gs_effect_set_texture(param, texture);
//while (gs_effect_loop(effect, "Draw")) {
// gs_draw_sprite(texture, 0, filter->width, filter->height);
//}
const enum gs_color_space preferred_spaces[] = {
GS_CS_SRGB,
GS_CS_SRGB_16F,
Expand All @@ -444,17 +476,27 @@ static void draw_output_to_source(composite_blur_filter_data_t *filter)

const enum gs_color_format format =
gs_get_format_from_space(source_space);
if (obs_source_process_filter_begin_with_color_space(

if (!obs_source_process_filter_begin_with_color_space(
filter->context, format, source_space,
OBS_ALLOW_DIRECT_RENDERING)) {
return;
}

set_blending_parameters();
gs_ortho(0.0f, (float)filter->width, 0.0f,
(float)filter->height, -100.0f, 100.0f);
obs_source_process_filter_end(filter->context, pass_through,
filter->width, filter->height);
gs_blend_state_pop();
gs_texture_t *texture =
gs_texrender_get_texture(filter->output_texrender);
gs_effect_t *pass_through = filter->output_effect;

if (filter->param_output_image) {
gs_effect_set_texture(filter->param_output_image, texture);
}

gs_blend_state_push();
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);

obs_source_process_filter_end(filter->context, pass_through,
filter->width, filter->height);
gs_blend_state_pop();
}

static void composite_blur_video_render(void *data, gs_effect_t *effect)
Expand Down Expand Up @@ -482,10 +524,15 @@ static void composite_blur_video_render(void *data, gs_effect_t *effect)
// 2. Apply effect to texture, and render texture to video
filter->video_render(filter);

if (filter->mask_type != EFFECT_MASK_TYPE_NONE) {
// Swap output and render
apply_effect_mask(filter);
}
//if (filter->mask_type != EFFECT_MASK_TYPE_NONE) {
// // Swap output and render
// apply_effect_mask(filter);
//}

//gs_texrender_t *tmp = filter->output_texrender;
//filter->output_texrender = filter->input_texrender;
//filter->input_texrender = tmp;


// 3. Draw result (filter->output_texrender) to source
draw_output_to_source(filter);
Expand Down Expand Up @@ -1547,6 +1594,7 @@ static void composite_blur_reload_effect(composite_blur_filter_data_t *filter)
filter->load_effect(filter);
load_composite_effect(filter);
load_mix_effect(filter);
load_output_effect(filter);
}

obs_data_release(settings);
Expand Down Expand Up @@ -1803,6 +1851,50 @@ static void load_mix_effect(composite_blur_filter_data_t *filter)
}
}

static void load_output_effect(composite_blur_filter_data_t *filter)
{
if (filter->output_effect != NULL) {
obs_enter_graphics();
gs_effect_destroy(filter->output_effect);
filter->output_effect = NULL;
obs_leave_graphics();
}

char *shader_text = NULL;
struct dstr filename = {0};
dstr_cat(&filename, obs_get_module_data_path(obs_current_module()));
dstr_cat(&filename, "/shaders/render_output.effect");
shader_text = load_shader_from_file(filename.array);
char *errors = NULL;
dstr_free(&filename);

obs_enter_graphics();
filter->output_effect = gs_effect_create(shader_text, NULL, &errors);
obs_leave_graphics();

bfree(shader_text);
if (filter->output_effect == NULL) {
blog(LOG_WARNING,
"[obs-composite-blur] Unable to load output.effect file. Errors:\n%s",
(errors == NULL || strlen(errors) == 0 ? "(None)"
: errors));
bfree(errors);
} else {
size_t effect_count =
gs_effect_get_num_params(filter->output_effect);
for (size_t effect_index = 0; effect_index < effect_count;
effect_index++) {
gs_eparam_t *param = gs_effect_get_param_by_idx(
filter->output_effect, effect_index);
struct gs_effect_param_info info;
gs_effect_get_param_info(param, &info);
if (strcmp(info.name, "output_image") == 0) {
filter->param_output_image = param;
}
}
}
}

gs_texture_t *blend_composite(gs_texture_t *texture,
composite_blur_filter_data_t *data)
{
Expand Down
5 changes: 5 additions & 0 deletions src/obs-composite-blur-filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ struct composite_blur_filter_data {
gs_effect_t *composite_effect;
gs_effect_t *mix_effect;
gs_effect_t *effect_mask_effect;
gs_effect_t *output_effect;

// Render pipeline
bool input_rendered;
Expand Down Expand Up @@ -210,6 +211,9 @@ struct composite_blur_filter_data {
float mask_rect_inv;
gs_image_file_t *mask_image;

// Output Effect Parameters
gs_eparam_t *param_output_image;

uint32_t width;
uint32_t height;

Expand All @@ -234,6 +238,7 @@ static obs_properties_t *composite_blur_properties(void *data);
static void composite_blur_reload_effect(composite_blur_filter_data_t *filter);
static void load_composite_effect(composite_blur_filter_data_t *filter);
static void load_mix_effect(composite_blur_filter_data_t *filter);
static void load_output_effect(composite_blur_filter_data_t *filter);
extern gs_texture_t *blend_composite(gs_texture_t *texture,
composite_blur_filter_data_t *data);

Expand Down