mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-11 14:25:05 +00:00
130 lines
4.1 KiB
Text
130 lines
4.1 KiB
Text
#include "common.effect"
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Uniforms
|
|
//------------------------------------------------------------------------------
|
|
// This shader requires that pSize is the number of samples, not the size of the
|
|
// kernel. That way oversampling can be performed, which is much more accurate than
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Defines
|
|
//------------------------------------------------------------------------------
|
|
#define MAX_SAMPLES 128u
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Technique: Directional / Area
|
|
//------------------------------------------------------------------------------
|
|
float4 PSBlur1D(VertexInformation vtx) : TARGET {
|
|
float2 uvstep = pImageTexel * pStepScale;
|
|
float weights = 0;
|
|
|
|
// Move to texel center.
|
|
vtx.uv.xy += pImageTexel.xy / 2.;
|
|
|
|
// Calculate the actual Gaussian Blur
|
|
// 1. Sample the center immediately.
|
|
float kernel = kernelAt(0u);
|
|
weights += kernel;
|
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernel;
|
|
|
|
// 2. Then sample both + and - coordinates in one go to reduce code iterations.
|
|
for (uint step = 1u; (step < uint(pSize)) && (step < MAX_SAMPLES); step++) {
|
|
float2 offset = uvstep * float2(step, step);
|
|
kernel = kernelAt(step);
|
|
weights += kernel * 2.;
|
|
|
|
final += pImage.Sample(LinearClampSampler, vtx.uv + offset) * kernel;
|
|
final += pImage.Sample(LinearClampSampler, vtx.uv - offset) * kernel;
|
|
}
|
|
|
|
// 3. Ensure we always have a total of 1.0, even if the kernel is bad.
|
|
final /= weights;
|
|
|
|
return final;
|
|
}
|
|
|
|
technique Draw {
|
|
pass {
|
|
vertex_shader = VSDefault(vtx);
|
|
pixel_shader = PSBlur1D(vtx);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Technique: Rotate
|
|
//------------------------------------------------------------------------------
|
|
float4 PSRotate(VertexInformation vtx) : TARGET {
|
|
float angstep = pAngle * pStepScale.x;
|
|
float weights = 0.;
|
|
|
|
// Move to texel center.
|
|
vtx.uv.xy += pImageTexel.xy / 2.;
|
|
|
|
// Calculate the actual Gaussian Blur
|
|
// 1. Sample the center immediately.
|
|
float kernel = kernelAt(0u);
|
|
weights += kernel;
|
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernel;
|
|
|
|
// 2. Then sample both + and - coordinates in one go to reduce code iterations.
|
|
for (uint step = 1u; (step < uint(pSize)) && (step < MAX_SAMPLES); step++) {
|
|
float offset = angstep * step;
|
|
kernel = kernelAt(step);
|
|
weights += kernel * 2.;
|
|
|
|
final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, offset)) * kernel;
|
|
final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, -offset)) * kernel;
|
|
}
|
|
|
|
// 3. Ensure we always have a total of 1.0, even if the kernel is bad.
|
|
final /= weights;
|
|
|
|
return final;
|
|
}
|
|
|
|
technique Rotate {
|
|
pass {
|
|
vertex_shader = VSDefault(vtx);
|
|
pixel_shader = PSRotate(vtx);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Technique: Zoom
|
|
//------------------------------------------------------------------------------
|
|
float4 PSZoom(VertexInformation vtx) : TARGET {
|
|
float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel;
|
|
float dist = distance(vtx.uv, pCenter);
|
|
float weights = 0.;
|
|
|
|
// Move to texel center.
|
|
vtx.uv.xy += pImageTexel.xy / 2.;
|
|
|
|
// Calculate the actual Gaussian Blur
|
|
// 1. Sample the center immediately.
|
|
float kernel = kernelAt(0u);
|
|
weights += kernel;
|
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernel;
|
|
|
|
// 2. Then sample both + and - coordinates in one go to reduce code iterations.
|
|
for (uint step = 1u; (step < uint(pSize)) && (step < MAX_SAMPLES); step++) {
|
|
float2 offset = dir * step * dist;
|
|
kernel = kernelAt(step);
|
|
weights += kernel * 2.;
|
|
|
|
final += pImage.Sample(LinearClampSampler, vtx.uv + offset) * kernel;
|
|
final += pImage.Sample(LinearClampSampler, vtx.uv - offset) * kernel;
|
|
}
|
|
|
|
// 3. Ensure we always have a total of 1.0, even if the kernel is bad.
|
|
final /= weights;
|
|
|
|
return final;
|
|
}
|
|
|
|
technique Zoom {
|
|
pass {
|
|
vertex_shader = VSDefault(vtx);
|
|
pixel_shader = PSZoom(vtx);
|
|
}
|
|
}
|