// AUTOGENERATED COPYRIGHT HEADER START // Copyright (C) 2019-2023 Michael Fabian 'Xaymar' Dirks // AUTOGENERATED COPYRIGHT HEADER END #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); } }