obs-StreamFX/data/effects/blur/box.effect

138 lines
3.1 KiB
Text
Raw Normal View History

// Parameters:
/// OBS Default
uniform float4x4 ViewProj;
/// Texture
uniform texture2d pImage;
uniform float2 pImageTexel;
/// Blur
uniform float pSize;
uniform float pSizeInverseMul;
uniform float pAngle;
uniform float2 pCenter;
uniform float2 pStepScale;
#define MAX_BLUR_SIZE 128
// Sampler
sampler_state linearSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
MinLOD = 0;
MaxLOD = 0;
};
// Default Vertex Shader and Data
struct VertDataIn {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VertDataOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertDataOut VSDefault(VertDataIn vtx) {
VertDataOut vert_out;
vert_out.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj);
vert_out.uv = vtx.uv;
return vert_out;
}
// Blur 1 Dimensional
float4 PSBlur1D(VertDataOut vtx) : TARGET {
float4 final = pImage.Sample(linearSampler, vtx.uv);
// Loop unrolling is only possible with a fixed known maximum.
// Some compilers may unroll up to x iterations, but most will not.
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
float2 nstep = (pImageTexel * pStepScale) * n;
final += pImage.Sample(linearSampler, vtx.uv + nstep);
final += pImage.Sample(linearSampler, vtx.uv - nstep);
if (n >= pSize) {
break;
}
}
final *= pSizeInverseMul;
return final;
}
technique Draw {
pass {
vertex_shader = VSDefault(vtx);
pixel_shader = PSBlur1D(vtx);
}
}
// Blur Rotation
float2 rotate(float2 pt, float angle) {
float cp = cos(angle);
float sp = sin(angle);
float sn = -sp;
return float2((pt.x * cp) + (pt.y * sn), (pt.x * sp) + (pt.y * cp));
}
float2 rotateAround(float2 pt, float2 cpt, float angle) {
return rotate(pt - cpt, angle) + cpt;
}
float4 PSRotate(VertDataOut vtx) : TARGET {
float4 final = pImage.Sample(linearSampler, vtx.uv);
float angstep = pAngle * pStepScale.x;
// Loop unrolling is only possible with a fixed known maximum.
// Some compilers may unroll up to x iterations, but most will not.
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * n));
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * -n));
if (n >= pSize) {
break;
}
}
final *= pSizeInverseMul;
return final;
}
technique Rotate {
pass {
vertex_shader = VSDefault(vtx);
pixel_shader = PSRotate(vtx);
}
}
// Blur Zoom
float4 PSZoom(VertDataOut vtx) : TARGET {
float4 final = pImage.Sample(linearSampler, vtx.uv);
// step is calculated from the direction relative to the center
float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel;
float dist = distance(vtx.uv, pCenter);
// Loop unrolling is only possible with a fixed known maximum.
// Some compilers may unroll up to x iterations, but most will not.
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
final += pImage.Sample(linearSampler, vtx.uv + (dir * n) * dist);
final += pImage.Sample(linearSampler, vtx.uv + (dir * -n) * dist);
if (n >= pSize) {
break;
}
}
final *= pSizeInverseMul;
return final;
}
technique Zoom {
pass {
vertex_shader = VSDefault(vtx);
pixel_shader = PSZoom(vtx);
}
}