-
-
Save agrif/c9ec6d161611cb2257be9d7c5ef14250 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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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. | |
// originally from | |
// https://gist.github.com/ion1/0e028ad096aa6f375bc9a97334639fa3 | |
// modified to work with StreamFX | |
// https://github.com/Xaymar/obs-StreamFX/ | |
// https://gist.github.com/agrif/c9ec6d161611cb2257be9d7c5ef14250 | |
uniform float4x4 ViewProj<bool automatic = true;>; | |
uniform float4 ViewSize<bool automatic = true;>; | |
uniform texture2d InputA<bool automatic = true;>; | |
uniform int Square_Size<string name = "Square Size"; int minimum = 0;> = 8; | |
uniform float Left<float minimum = 0; float maximum = 100; string field_type = "slider";> = 0; | |
uniform float Right<float minimum = 0; float maximum = 100; string field_type = "slider";> = 0; | |
uniform float Top<float minimum = 0; float maximum = 100; string field_type = "slider";> = 0; | |
uniform float Bottom<float minimum = 0; float maximum = 100; string field_type = "slider";> = 0; | |
sampler_state textureSampler { | |
AddressU = Clamp; | |
AddressV = Clamp; | |
Filter = Linear; | |
}; | |
struct VertData { | |
float4 pos : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
// 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(InputA.SampleGrad(textureSampler, pos * ViewSize.zw, dx, dy).rgb); | |
} | |
float3 square(VertData v_in) | |
{ | |
uint2 pixel = floor(v_in.uv * ViewSize.xy); | |
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; | |
} | |
VertData VSDefault(VertData v_in) { | |
VertData vert_out; | |
vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); | |
vert_out.uv = v_in.uv; | |
return vert_out; | |
} | |
float4 PSDefault(VertData v_in) : TARGET { | |
if (v_in.uv.x >= Left * 0.01 && | |
v_in.uv.x < 1.0 - Right * 0.01 && | |
v_in.uv.y >= Top * 0.01 && | |
v_in.uv.y < 1.0 - Bottom * 0.01) { | |
return float4(from_linear(square(v_in)), 1.0); | |
} else { | |
return InputA.Sample(textureSampler, v_in.uv); | |
} | |
} | |
technique Draw | |
{ | |
pass | |
{ | |
vertex_shader = VSDefault(v_in); | |
pixel_shader = PSDefault(v_in); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment