mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-12-04 17:17:25 +00:00
147 lines
3.3 KiB
Text
147 lines
3.3 KiB
Text
|
// Parameters:
|
||
|
/// OBS Default
|
||
|
uniform float4x4 ViewProj;
|
||
|
/// Texture
|
||
|
uniform texture2d pImage;
|
||
|
uniform float2 pImageTexel;
|
||
|
/// Blur
|
||
|
uniform float pSize;
|
||
|
uniform float pAngle;
|
||
|
uniform float2 pCenter;
|
||
|
uniform float2 pStepScale;
|
||
|
/// Gaussian
|
||
|
uniform float4 pKernel[32];
|
||
|
|
||
|
#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;
|
||
|
}
|
||
|
|
||
|
// Functions
|
||
|
float GetKernelAt(int i) {
|
||
|
return ((float[4])(pKernel[floor(i/4)]))[i%4];
|
||
|
}
|
||
|
|
||
|
// Blur 1 Dimensional
|
||
|
float4 PSBlur1D(VertDataOut vtx) : TARGET {
|
||
|
float4 final = pImage.Sample(linearSampler, vtx.uv)
|
||
|
* GetKernelAt(0);
|
||
|
|
||
|
// 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;
|
||
|
float kernel = GetKernelAt(n);
|
||
|
final += pImage.Sample(linearSampler, vtx.uv + nstep) * kernel;
|
||
|
final += pImage.Sample(linearSampler, vtx.uv - nstep) * kernel;
|
||
|
|
||
|
if (n >= pSize) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
* GetKernelAt(0);
|
||
|
|
||
|
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++) {
|
||
|
float kernel = GetKernelAt(n);
|
||
|
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * n)) * kernel;
|
||
|
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * -n)) * kernel;
|
||
|
|
||
|
if (n >= pSize) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
* GetKernelAt(0);
|
||
|
|
||
|
// 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++) {
|
||
|
float kernel = GetKernelAt(n);
|
||
|
final += pImage.Sample(linearSampler, vtx.uv + (dir * n) * dist) * kernel;
|
||
|
final += pImage.Sample(linearSampler, vtx.uv - (dir * n) * dist) * kernel;
|
||
|
|
||
|
if (n >= pSize) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return final;
|
||
|
}
|
||
|
|
||
|
technique Zoom {
|
||
|
pass {
|
||
|
vertex_shader = VSDefault(vtx);
|
||
|
pixel_shader = PSZoom(vtx);
|
||
|
}
|
||
|
}
|