mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-30 23:33:02 +00:00
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.
This commit is contained in:
parent
f6b662ff21
commit
edd1162a48
7 changed files with 193 additions and 297 deletions
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
86
data/effects/blur/common.effect
Normal file
86
data/effects/blur/common.effect
Normal file
|
@ -0,0 +1,86 @@
|
|||
// Copyright 2021 Michael Fabian Dirks <info@xaymar.com>
|
||||
//
|
||||
// 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];
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue