From edd1162a4876ac21724f569054ad1abf16956a47 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Tue, 8 Jun 2021 06:08:07 +0200 Subject: [PATCH] gfx/blur: Reduce code duplication with shared file A lot of the blur effects share quite a bit of code, which can be offloaded into a single include. --- CMakeLists.txt | 1 + data/effects/blur/box-linear.effect | 63 ++++---------- data/effects/blur/box.effect | 90 ++++++------------- data/effects/blur/common.effect | 86 +++++++++++++++++++ data/effects/blur/dual-filtering.effect | 74 +++++----------- data/effects/blur/gaussian-linear.effect | 71 ++++----------- data/effects/blur/gaussian.effect | 105 ++++++----------------- 7 files changed, 193 insertions(+), 297 deletions(-) create mode 100644 data/effects/blur/common.effect diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c960607..a6611c81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1151,6 +1151,7 @@ is_feature_enabled(FILTER_BLUR T_CHECK) if(T_CHECK) list(APPEND PROJECT_DATA "data/effects/mask.effect" + "data/effects/blur/common.effect" "data/effects/blur/box.effect" "data/effects/blur/box-linear.effect" "data/effects/blur/dual-filtering.effect" diff --git a/data/effects/blur/box-linear.effect b/data/effects/blur/box-linear.effect index 9ac809e9..8b2fce45 100644 --- a/data/effects/blur/box-linear.effect +++ b/data/effects/blur/box-linear.effect @@ -1,17 +1,4 @@ -// 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 +#include "common.effect" // # Linear Optimization // While the normal way is to sample every texel in the pSize, linear optimization @@ -47,37 +34,17 @@ uniform float2 pStepScale; // faster alternatives than linear sampling with Gaussian Blur, such as // Dual Filtering ("Dual Kawase"). -// Sampler -sampler_state linearSampler { - Filter = Linear; - AddressU = Clamp; - AddressV = Clamp; - MinLOD = 0; - MaxLOD = 0; -}; +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ +#define MAX_BLUR_SIZE 128 -// 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); - bool is_odd = ((int(round(pSize)) % 2) == 1); +//------------------------------------------------------------------------------ +// Technique: Directional / Area +//------------------------------------------------------------------------------ +float4 PSBlur1D(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, vtx.uv); + bool is_odd = ((uint(round(pSize)) % 2) == 1); // y = yes, s = skip, b = break // Size-> | 1| 2| 3| 4| 5| 6| 7| @@ -100,13 +67,13 @@ float4 PSBlur1D(VertDataOut vtx) : TARGET { } float2 nstep = (pImageTexel * pStepScale) * (n + 0.5); - final += pImage.Sample(linearSampler, vtx.uv + nstep) * 2.; - final += pImage.Sample(linearSampler, vtx.uv - nstep) * 2.; + final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * 2.; + final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * 2.; } if (is_odd) { float2 nstep = (pImageTexel * pStepScale) * pSize; - final += pImage.Sample(linearSampler, vtx.uv + nstep); - final += pImage.Sample(linearSampler, vtx.uv - nstep); + final += pImage.Sample(LinearClampSampler, vtx.uv + nstep); + final += pImage.Sample(LinearClampSampler, vtx.uv - nstep); } final *= pSizeInverseMul; diff --git a/data/effects/blur/box.effect b/data/effects/blur/box.effect index a7ff6392..73e3da57 100644 --- a/data/effects/blur/box.effect +++ b/data/effects/blur/box.effect @@ -1,55 +1,22 @@ -// 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; +#include "common.effect" +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ #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); +//------------------------------------------------------------------------------ +// Technique: Directional / Area +//------------------------------------------------------------------------------ +float4 PSBlur1D(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, 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); + final += pImage.Sample(LinearClampSampler, vtx.uv + nstep); + final += pImage.Sample(LinearClampSampler, vtx.uv - nstep); if (n >= pSize) { break; @@ -67,28 +34,19 @@ technique Draw { } } -// 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); +//------------------------------------------------------------------------------ +// Technique: Rotate +//------------------------------------------------------------------------------ +float4 PSRotate(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, 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)); + final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, angstep * n)); + final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, angstep * -n)); if (n >= pSize) { break; @@ -106,9 +64,11 @@ technique Rotate { } } -// Blur Zoom -float4 PSZoom(VertDataOut vtx) : TARGET { - float4 final = pImage.Sample(linearSampler, vtx.uv); +//------------------------------------------------------------------------------ +// Technique: Zoom +//------------------------------------------------------------------------------ +float4 PSZoom(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, vtx.uv); // step is calculated from the direction relative to the center float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel; @@ -117,8 +77,8 @@ float4 PSZoom(VertDataOut vtx) : TARGET { // 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); + final += pImage.Sample(LinearClampSampler, vtx.uv + (dir * n) * dist); + final += pImage.Sample(LinearClampSampler, vtx.uv + (dir * -n) * dist); if (n >= pSize) { break; diff --git a/data/effects/blur/common.effect b/data/effects/blur/common.effect new file mode 100644 index 00000000..dda51cce --- /dev/null +++ b/data/effects/blur/common.effect @@ -0,0 +1,86 @@ +// Copyright 2021 Michael Fabian Dirks +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ +// Kernel size as sequential float4's. +#define KERNEL_SIZE 32 + +//------------------------------------------------------------------------------ +// Uniforms +//------------------------------------------------------------------------------ +uniform float4x4 ViewProj; +uniform texture2d pImage; +uniform float2 pImageSize; +uniform float2 pImageTexel; +uniform float2 pImageHalfTexel; +uniform float pSize; +uniform float pSizeInverseMul; +uniform float pAngle; +uniform float2 pCenter; +uniform float2 pStepScale; +uniform float4 pKernel[KERNEL_SIZE]; + +//------------------------------------------------------------------------------ +// Structures +//------------------------------------------------------------------------------ +struct VertexInformation { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +sampler_state LinearClampSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; + MinLOD = 0; + MaxLOD = 0; +}; + +//------------------------------------------------------------------------------ +// Functions +//------------------------------------------------------------------------------ + +VertexInformation VSDefault(VertexInformation vtx) { + vtx.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj); + return vtx; +} + +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; +} + +float kernelAt(uint i) { + return ((float[4])(pKernel[floor(i/4)]))[i%4]; +} diff --git a/data/effects/blur/dual-filtering.effect b/data/effects/blur/dual-filtering.effect index e123e725..bd537734 100644 --- a/data/effects/blur/dual-filtering.effect +++ b/data/effects/blur/dual-filtering.effect @@ -1,48 +1,16 @@ -// Parameters: -/// OBS Default -uniform float4x4 ViewProj; -/// Texture -uniform texture2d pImage; -uniform float2 pImageSize; -uniform float2 pImageTexel; -uniform float2 pImageHalfTexel; +#include "common.effect" -// 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; -} - -// Downsample -float4 PSDown(VertDataOut vtx) : TARGET { +//------------------------------------------------------------------------------ +// Technique: Down +//------------------------------------------------------------------------------ +float4 PSDown(VertexInformation vtx) : TARGET { //vtx.uv = ((floor(vtx.uv * pImageSize) + float2(0.5, 0.5)) * pImageTexel); - float4 pxCC = pImage.Sample(linearSampler, vtx.uv) * 4.0; - float4 pxTL = pImage.Sample(linearSampler, vtx.uv - pImageHalfTexel); - float4 pxTR = pImage.Sample(linearSampler, vtx.uv + pImageHalfTexel); - float4 pxBL = pImage.Sample(linearSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y)); - float4 pxBR = pImage.Sample(linearSampler, vtx.uv - float2(pImageHalfTexel.x, -pImageHalfTexel.y)); + float4 pxCC = pImage.Sample(LinearClampSampler, vtx.uv) * 4.0; + float4 pxTL = pImage.Sample(LinearClampSampler, vtx.uv - pImageHalfTexel); + float4 pxTR = pImage.Sample(LinearClampSampler, vtx.uv + pImageHalfTexel); + float4 pxBL = pImage.Sample(LinearClampSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y)); + float4 pxBR = pImage.Sample(LinearClampSampler, vtx.uv - float2(pImageHalfTexel.x, -pImageHalfTexel.y)); return (pxCC + pxTL + pxTR + pxBL + pxBR) * 0.125; } @@ -54,18 +22,20 @@ technique Down { } } -// Upsample -float4 PSUp(VertDataOut vtx) : TARGET { +//------------------------------------------------------------------------------ +// Technique: Up +//------------------------------------------------------------------------------ +float4 PSUp(VertexInformation vtx) : TARGET { //vtx.uv = ((floor(vtx.uv * pImageSize) + float2(0.5, 0.5)) * pImageTexel); - float4 pxL = pImage.Sample(linearSampler, vtx.uv - float2(pImageHalfTexel.x * 2.0, 0.)); - float4 pxBL = pImage.Sample(linearSampler, vtx.uv - float2(pImageHalfTexel.x, -pImageHalfTexel.y)); - float4 pxB = pImage.Sample(linearSampler, vtx.uv + float2(0., pImageHalfTexel.y * 2.0)); - float4 pxBR = pImage.Sample(linearSampler, vtx.uv + pImageHalfTexel); - float4 pxR = pImage.Sample(linearSampler, vtx.uv + float2(pImageHalfTexel.x * 2.0, 0.)); - float4 pxTR = pImage.Sample(linearSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y)); - float4 pxT = pImage.Sample(linearSampler, vtx.uv - float2(0., pImageHalfTexel.y * 2.0)); - float4 pxTL = pImage.Sample(linearSampler, vtx.uv - pImageHalfTexel); + float4 pxL = pImage.Sample(LinearClampSampler, vtx.uv - float2(pImageHalfTexel.x * 2.0, 0.)); + float4 pxBL = pImage.Sample(LinearClampSampler, vtx.uv - float2(pImageHalfTexel.x, -pImageHalfTexel.y)); + float4 pxB = pImage.Sample(LinearClampSampler, vtx.uv + float2(0., pImageHalfTexel.y * 2.0)); + float4 pxBR = pImage.Sample(LinearClampSampler, vtx.uv + pImageHalfTexel); + float4 pxR = pImage.Sample(LinearClampSampler, vtx.uv + float2(pImageHalfTexel.x * 2.0, 0.)); + float4 pxTR = pImage.Sample(LinearClampSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y)); + float4 pxT = pImage.Sample(LinearClampSampler, vtx.uv - float2(0., pImageHalfTexel.y * 2.0)); + float4 pxTL = pImage.Sample(LinearClampSampler, vtx.uv - pImageHalfTexel); return (((pxTL + pxTR + pxBL + pxBR) * 2.0) + pxL + pxR + pxT + pxB) * 0.083333333333; // return (((pxTL + pxTR + pxBL + pxBR) * 2.0) + pxL + pxR + pxT + pxB) / 12; diff --git a/data/effects/blur/gaussian-linear.effect b/data/effects/blur/gaussian-linear.effect index 63c885c5..f2eb43ca 100644 --- a/data/effects/blur/gaussian-linear.effect +++ b/data/effects/blur/gaussian-linear.effect @@ -1,18 +1,4 @@ -// 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 +#include "common.effect" // # Linear Optimization // While the normal way is to sample every texel in the pSize, linear optimization @@ -53,41 +39,16 @@ uniform float4 pKernel[32]; // faster alternatives than linear sampling with Gaussian Blur, such as // Dual Filtering ("Dual Kawase"). -// Sampler -sampler_state linearSampler { - Filter = Linear; - AddressU = Clamp; - AddressV = Clamp; - MinLOD = 0; - MaxLOD = 0; -}; +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ +#define MAX_BLUR_SIZE 128 -// 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); +//------------------------------------------------------------------------------ +// Technique: Directional / Area +//------------------------------------------------------------------------------ +float4 PSBlur1D(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * GetKernelAt(0); bool is_odd = ((int(round(pSize)) % 2) == 1); // y = yes, s = skip, b = break @@ -112,15 +73,15 @@ float4 PSBlur1D(VertDataOut vtx) : TARGET { // TODO: Determine better position than 0.5 for gaussian approximation. float2 nstep = (pImageTexel * pStepScale) * (n + 0.5); - float kernel = GetKernelAt(n) + GetKernelAt(n + 1); - final += pImage.Sample(linearSampler, vtx.uv + nstep) * kernel; - final += pImage.Sample(linearSampler, vtx.uv - nstep) * kernel; + float kernel = kernelAt(n) + kernelAt(n + 1); + final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * kernel; + final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * kernel; } if (is_odd) { - float kernel = GetKernelAt(pSize); + float kernel = kernelAt(pSize); float2 nstep = (pImageTexel * pStepScale) * pSize; - final += pImage.Sample(linearSampler, vtx.uv + nstep) * kernel; - final += pImage.Sample(linearSampler, vtx.uv - nstep) * kernel; + final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * kernel; + final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * kernel; } return final; diff --git a/data/effects/blur/gaussian.effect b/data/effects/blur/gaussian.effect index 6e9c76da..ea9dca0d 100644 --- a/data/effects/blur/gaussian.effect +++ b/data/effects/blur/gaussian.effect @@ -1,63 +1,23 @@ -// 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]; +#include "common.effect" +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ #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); +//------------------------------------------------------------------------------ +// Technique: Directional / Area +//------------------------------------------------------------------------------ +float4 PSBlur1D(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernelAt(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; + float kernel = kernelAt(n); + final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * kernel; + final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * kernel; if (n >= pSize) { break; @@ -74,30 +34,20 @@ technique Draw { } } -// 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); +//------------------------------------------------------------------------------ +// Technique: Rotate +//------------------------------------------------------------------------------ +float4 PSRotate(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernelAt(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; + float kernel = kernelAt(n); + final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, angstep * n)) * kernel; + final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, angstep * -n)) * kernel; if (n >= pSize) { break; @@ -114,10 +64,11 @@ technique Rotate { } } -// Blur Zoom -float4 PSZoom(VertDataOut vtx) : TARGET { - float4 final = pImage.Sample(linearSampler, vtx.uv) - * GetKernelAt(0); +//------------------------------------------------------------------------------ +// Technique: Zoom +//------------------------------------------------------------------------------ +float4 PSZoom(VertexInformation vtx) : TARGET { + float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernelAt(0); // step is calculated from the direction relative to the center float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel; @@ -126,9 +77,9 @@ float4 PSZoom(VertDataOut vtx) : TARGET { // 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; + float kernel = kernelAt(n); + final += pImage.Sample(LinearClampSampler, vtx.uv + (dir * n) * dist) * kernel; + final += pImage.Sample(LinearClampSampler, vtx.uv - (dir * n) * dist) * kernel; if (n >= pSize) { break;