Skip to content

Instantly share code, notes, and snippets.

@ion1
Last active November 8, 2022 02:17
Show Gist options
  • Save ion1/0e028ad096aa6f375bc9a97334639fa3 to your computer and use it in GitHub Desktop.
Save ion1/0e028ad096aa6f375bc9a97334639fa3 to your computer and use it in GitHub Desktop.
Censor a part of the screen (such as a chat window) by pixelation in obs-shaderfilter
// Censor a part of the screen (such as a chat window) by pixelation in
// obs-shaderfilter.
// https://obsproject.com/forum/resources/obs-shaderfilter.775/
// https://creativecommons.org/publicdomain/zero/1.0/
// To the extent possible under law, ion has waived all copyright and related
// or neighboring rights to obs-pixelate-rectangle. This work is published
// from: Suomi.
// https://gist.github.com/ion1/0e028ad096aa6f375bc9a97334639fa3
uniform int Square_Size = 8;
uniform int Left = 40;
uniform int Top = 40;
uniform int Width = 632;
uniform int Height = 152;
// Very rough approximations.
float3 to_linear(float3 col) {
return col * col;
}
float3 from_linear(float3 col) {
return sqrt(col);
}
float3 sample(float2 square_top_left, uint sx, uint sy, float2 dx, float2 dy)
{
float2 pos = square_top_left + (float2(sx, sy) + 0.5) * Square_Size / 8.0;
// OBS doesn't seem to generate mipmaps, this will just sample the unscaled
// texture for now.
return to_linear(image.SampleGrad(textureSampler, pos * uv_pixel_interval, dx, dy).rgb);
}
float3 square(VertData v_in)
{
uint2 pixel = floor(v_in.uv / uv_pixel_interval);
uint2 square_top_left = pixel - (pixel % Square_Size);
// Sample 8 points from each square following this 8x MSAA pattern:
// https://docs.microsoft.com/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels
float2 dx = ddx(v_in.uv) * Square_Size / 8.0;
float2 dy = ddy(v_in.uv) * Square_Size / 8.0;
float3 col = 0;
col += sample(square_top_left, 7, 0, dx, dy);
col += sample(square_top_left, 2, 1, dx, dy);
col += sample(square_top_left, 4, 2, dx, dy);
col += sample(square_top_left, 0, 3, dx, dy);
col += sample(square_top_left, 6, 4, dx, dy);
col += sample(square_top_left, 3, 5, dx, dy);
col += sample(square_top_left, 1, 6, dx, dy);
col += sample(square_top_left, 5, 7, dx, dy);
col /= 8;
return col;
}
float4 mainImage(VertData v_in) : TARGET
{
if (v_in.uv.x >= Left * uv_pixel_interval.x &&
v_in.uv.x < (Left + Width) * uv_pixel_interval.x &&
v_in.uv.y >= Top * uv_pixel_interval.y &&
v_in.uv.y < (Top + Height) * uv_pixel_interval.y) {
return float4(from_linear(square(v_in)), 1.0);
} else {
return image.Sample(textureSampler, v_in.uv);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment