From 6eea2188d50a63d21f9a738940b26b82879e4ff2 Mon Sep 17 00:00:00 2001 From: FiniteSingularity <72580859+FiniteSingularity@users.noreply.github.com> Date: Sat, 16 Dec 2023 12:26:03 -0600 Subject: [PATCH] Bugfix/macos pixelate mod (#97) * Fixes issue with difference in fmod vs mod in GLSL/HLSL * Moves pixelate origin check to video tick. --- data/shaders/pixelate_circle.effect | 16 +++++++++------ data/shaders/pixelate_square.effect | 8 ++++++-- src/obs-composite-blur-filter.c | 30 ++++++++++++++++------------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/data/shaders/pixelate_circle.effect b/data/shaders/pixelate_circle.effect index 3e6ca35..ca30acc 100644 --- a/data/shaders/pixelate_circle.effect +++ b/data/shaders/pixelate_circle.effect @@ -1,3 +1,8 @@ +// Create MOD function that acts like glsl mod, rather than HLSL's fmod. +// Necessary to have consistent pattern tiling in both OGL systems (mac/linux) +// and DirectX systems (windows) +#define MOD(x, y) (x - y * floor(x / y)) + uniform float4x4 ViewProj; uniform texture2d image; @@ -30,15 +35,14 @@ VertData mainTransform(VertData v_in) float4 mainImage(VertData v_in) : TARGET { - // 1. Sample incoming pixel + // 1. Sample incoming pixel float2 coord = v_in.uv * uv_size; float2 coord_p = coord - tess_origin; // Shifted box coordinate coord_p = float2(coord_p.x * cos_theta - coord_p.y * sin_theta, coord_p.x * sin_theta + coord_p.y * cos_theta); - float2 coord_grid = (coord_p - fmod(coord_p, pixel_size)) + sign(coord_p) * - float2(pixel_size, pixel_size) / 2.0f; - - float2 uv_prime = (float2(coord_grid.x * cos_rtheta - coord_grid.y * sin_rtheta, coord_grid.x * sin_rtheta + coord_grid.y * cos_rtheta) + tess_origin) / uv_size; - return distance(coord_grid, coord_p) <= pixel_size/2.0f ? image.Sample(textureSampler, uv_prime) : float4(0.0, 0.0, 0.0, 0.0); + float2 coord_grid = (coord_p - MOD(coord_p, pixel_size) + + float2(pixel_size, pixel_size) / 2.0f); + float2 uv_prime = (float2(coord_grid.x * cos_rtheta - coord_grid.y * sin_rtheta, coord_grid.x * sin_rtheta + coord_grid.y * cos_rtheta) + tess_origin)/uv_size; + return distance(coord_grid, coord_p) <= pixel_size/2.0f ? image.Sample(textureSampler, uv_prime) : float4(0.0f, 0.0f, 0.0f, 0.0f); } technique Draw diff --git a/data/shaders/pixelate_square.effect b/data/shaders/pixelate_square.effect index f5effd5..2134c3e 100644 --- a/data/shaders/pixelate_square.effect +++ b/data/shaders/pixelate_square.effect @@ -1,3 +1,8 @@ +// Create MOD function that acts like glsl mod, rather than HLSL's fmod. +// Necessary to have consistent pattern tiling in both OGL systems (mac/linux) +// and DirectX systems (windows) +#define MOD(x, y) (x - y * floor(x / y)) + uniform float4x4 ViewProj; uniform texture2d image; @@ -34,9 +39,8 @@ float4 mainImage(VertData v_in) : TARGET float2 coord = v_in.uv * uv_size; float2 coord_p = coord - tess_origin; // Shifted box coordinate coord_p = float2(coord_p.x * cos_theta - coord_p.y * sin_theta, coord_p.x * sin_theta + coord_p.y * cos_theta); - float2 coord_grid = (coord_p - fmod(coord_p, pixel_size) + sign(coord_p) * + float2 coord_grid = (coord_p - MOD(coord_p, pixel_size) + sign(coord_p) * float2(pixel_size, pixel_size) / 2.0f); - //float2 uv_prime = (coord_grid + tess_origin) / uv_size; float2 uv_prime = (float2(coord_grid.x * cos_rtheta - coord_grid.y * sin_rtheta, coord_grid.x * sin_rtheta + coord_grid.y * cos_rtheta) + tess_origin)/uv_size; return image.Sample(textureSampler, uv_prime); } diff --git a/src/obs-composite-blur-filter.c b/src/obs-composite-blur-filter.c index 53203ba..aaadd90 100644 --- a/src/obs-composite-blur-filter.c +++ b/src/obs-composite-blur-filter.c @@ -282,15 +282,6 @@ static void composite_blur_update(void *data, obs_data_t *settings) { struct composite_blur_filter_data *filter = data; - if (filter->width > 0 && - (float)obs_data_get_double(settings, "pixelate_origin_x") < -1.e8) { - double width = (double)obs_source_get_width(filter->context); - double height = (double)obs_source_get_height(filter->context); - obs_data_set_double(settings, "pixelate_origin_x", width / 2.0); - obs_data_set_double(settings, "pixelate_origin_y", - height / 2.0); - } - filter->blur_algorithm = (int)obs_data_get_int(settings, "blur_algorithm"); @@ -1731,11 +1722,24 @@ static void composite_blur_video_tick(void *data, float seconds) dstr_free(&disable); } } + const uint32_t width = (uint32_t)obs_source_get_base_width(target); + const uint32_t height = (uint32_t)obs_source_get_base_height(target); + if(filter->width != width || filter->height != height) { + filter->width = (uint32_t)obs_source_get_base_width(target); + filter->height = (uint32_t)obs_source_get_base_height(target); + filter->uv_size.x = (float)filter->width; + filter->uv_size.y = (float)filter->height; + obs_data_t *settings = obs_source_get_settings(filter->context); + if (filter->width > 0 && + (float)obs_data_get_double(settings, "pixelate_origin_x") < -1.e8) { + obs_data_set_double(settings, "pixelate_origin_x", (double)width / 2.0); + obs_data_set_double(settings, "pixelate_origin_y", + (double)height / 2.0); + filter->pixelate_tessel_center.x = (float)width / 2.0f; + filter->pixelate_tessel_center.y = (float)height / 2.0f; + } + } - filter->width = (uint32_t)obs_source_get_base_width(target); - filter->height = (uint32_t)obs_source_get_base_height(target); - filter->uv_size.x = (float)filter->width; - filter->uv_size.y = (float)filter->height; filter->rendered = false; }