mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-27 22:03:01 +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
1fcd141f10
commit
5d4f88e614
7 changed files with 193 additions and 297 deletions
|
@ -1151,6 +1151,7 @@ is_feature_enabled(FILTER_BLUR T_CHECK)
|
||||||
if(T_CHECK)
|
if(T_CHECK)
|
||||||
list(APPEND PROJECT_DATA
|
list(APPEND PROJECT_DATA
|
||||||
"data/effects/mask.effect"
|
"data/effects/mask.effect"
|
||||||
|
"data/effects/blur/common.effect"
|
||||||
"data/effects/blur/box.effect"
|
"data/effects/blur/box.effect"
|
||||||
"data/effects/blur/box-linear.effect"
|
"data/effects/blur/box-linear.effect"
|
||||||
"data/effects/blur/dual-filtering.effect"
|
"data/effects/blur/dual-filtering.effect"
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
// Parameters:
|
#include "common.effect"
|
||||||
/// 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
|
|
||||||
|
|
||||||
// # Linear Optimization
|
// # Linear Optimization
|
||||||
// While the normal way is to sample every texel in the pSize, 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
|
// faster alternatives than linear sampling with Gaussian Blur, such as
|
||||||
// Dual Filtering ("Dual Kawase").
|
// Dual Filtering ("Dual Kawase").
|
||||||
|
|
||||||
// Sampler
|
//------------------------------------------------------------------------------
|
||||||
sampler_state linearSampler {
|
// Defines
|
||||||
Filter = Linear;
|
//------------------------------------------------------------------------------
|
||||||
AddressU = Clamp;
|
#define MAX_BLUR_SIZE 128
|
||||||
AddressV = Clamp;
|
|
||||||
MinLOD = 0;
|
|
||||||
MaxLOD = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Default Vertex Shader and Data
|
//------------------------------------------------------------------------------
|
||||||
struct VertDataIn {
|
// Technique: Directional / Area
|
||||||
float4 pos : POSITION;
|
//------------------------------------------------------------------------------
|
||||||
float2 uv : TEXCOORD0;
|
float4 PSBlur1D(VertexInformation vtx) : TARGET {
|
||||||
};
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv);
|
||||||
|
bool is_odd = ((uint(round(pSize)) % 2) == 1);
|
||||||
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);
|
|
||||||
|
|
||||||
// y = yes, s = skip, b = break
|
// y = yes, s = skip, b = break
|
||||||
// Size-> | 1| 2| 3| 4| 5| 6| 7|
|
// Size-> | 1| 2| 3| 4| 5| 6| 7|
|
||||||
|
@ -100,13 +67,13 @@ float4 PSBlur1D(VertDataOut vtx) : TARGET {
|
||||||
}
|
}
|
||||||
|
|
||||||
float2 nstep = (pImageTexel * pStepScale) * (n + 0.5);
|
float2 nstep = (pImageTexel * pStepScale) * (n + 0.5);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + nstep) * 2.;
|
final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * 2.;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - nstep) * 2.;
|
final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * 2.;
|
||||||
}
|
}
|
||||||
if (is_odd) {
|
if (is_odd) {
|
||||||
float2 nstep = (pImageTexel * pStepScale) * pSize;
|
float2 nstep = (pImageTexel * pStepScale) * pSize;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + nstep);
|
final += pImage.Sample(LinearClampSampler, vtx.uv + nstep);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - nstep);
|
final += pImage.Sample(LinearClampSampler, vtx.uv - nstep);
|
||||||
}
|
}
|
||||||
|
|
||||||
final *= pSizeInverseMul;
|
final *= pSizeInverseMul;
|
||||||
|
|
|
@ -1,55 +1,22 @@
|
||||||
// Parameters:
|
#include "common.effect"
|
||||||
/// 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;
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Defines
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
#define MAX_BLUR_SIZE 128
|
#define MAX_BLUR_SIZE 128
|
||||||
|
|
||||||
// Sampler
|
//------------------------------------------------------------------------------
|
||||||
sampler_state linearSampler {
|
// Technique: Directional / Area
|
||||||
Filter = Linear;
|
//------------------------------------------------------------------------------
|
||||||
AddressU = Clamp;
|
float4 PSBlur1D(VertexInformation vtx) : TARGET {
|
||||||
AddressV = Clamp;
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv);
|
||||||
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);
|
|
||||||
|
|
||||||
// Loop unrolling is only possible with a fixed known maximum.
|
// Loop unrolling is only possible with a fixed known maximum.
|
||||||
// Some compilers may unroll up to x iterations, but most will not.
|
// Some compilers may unroll up to x iterations, but most will not.
|
||||||
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
||||||
float2 nstep = (pImageTexel * pStepScale) * n;
|
float2 nstep = (pImageTexel * pStepScale) * n;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + nstep);
|
final += pImage.Sample(LinearClampSampler, vtx.uv + nstep);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - nstep);
|
final += pImage.Sample(LinearClampSampler, vtx.uv - nstep);
|
||||||
|
|
||||||
if (n >= pSize) {
|
if (n >= pSize) {
|
||||||
break;
|
break;
|
||||||
|
@ -67,28 +34,19 @@ technique Draw {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur Rotation
|
//------------------------------------------------------------------------------
|
||||||
float2 rotate(float2 pt, float angle) {
|
// Technique: Rotate
|
||||||
float cp = cos(angle);
|
//------------------------------------------------------------------------------
|
||||||
float sp = sin(angle);
|
float4 PSRotate(VertexInformation vtx) : TARGET {
|
||||||
float sn = -sp;
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv);
|
||||||
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);
|
|
||||||
|
|
||||||
float angstep = pAngle * pStepScale.x;
|
float angstep = pAngle * pStepScale.x;
|
||||||
|
|
||||||
// Loop unrolling is only possible with a fixed known maximum.
|
// Loop unrolling is only possible with a fixed known maximum.
|
||||||
// Some compilers may unroll up to x iterations, but most will not.
|
// Some compilers may unroll up to x iterations, but most will not.
|
||||||
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
||||||
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * n));
|
final += pImage.Sample(LinearClampSampler, 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));
|
||||||
|
|
||||||
if (n >= pSize) {
|
if (n >= pSize) {
|
||||||
break;
|
break;
|
||||||
|
@ -106,9 +64,11 @@ technique Rotate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur Zoom
|
//------------------------------------------------------------------------------
|
||||||
float4 PSZoom(VertDataOut vtx) : TARGET {
|
// Technique: Zoom
|
||||||
float4 final = pImage.Sample(linearSampler, vtx.uv);
|
//------------------------------------------------------------------------------
|
||||||
|
float4 PSZoom(VertexInformation vtx) : TARGET {
|
||||||
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv);
|
||||||
|
|
||||||
// step is calculated from the direction relative to the center
|
// step is calculated from the direction relative to the center
|
||||||
float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel;
|
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.
|
// Loop unrolling is only possible with a fixed known maximum.
|
||||||
// Some compilers may unroll up to x iterations, but most will not.
|
// Some compilers may unroll up to x iterations, but most will not.
|
||||||
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + (dir * n) * dist);
|
final += pImage.Sample(LinearClampSampler, vtx.uv + (dir * n) * dist);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + (dir * -n) * dist);
|
final += pImage.Sample(LinearClampSampler, vtx.uv + (dir * -n) * dist);
|
||||||
|
|
||||||
if (n >= pSize) {
|
if (n >= pSize) {
|
||||||
break;
|
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:
|
#include "common.effect"
|
||||||
/// OBS Default
|
|
||||||
uniform float4x4 ViewProj;
|
|
||||||
/// Texture
|
|
||||||
uniform texture2d pImage;
|
|
||||||
uniform float2 pImageSize;
|
|
||||||
uniform float2 pImageTexel;
|
|
||||||
uniform float2 pImageHalfTexel;
|
|
||||||
|
|
||||||
// Sampler
|
//------------------------------------------------------------------------------
|
||||||
sampler_state linearSampler {
|
// Technique: Down
|
||||||
Filter = Linear;
|
//------------------------------------------------------------------------------
|
||||||
AddressU = Clamp;
|
float4 PSDown(VertexInformation vtx) : TARGET {
|
||||||
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 {
|
|
||||||
//vtx.uv = ((floor(vtx.uv * pImageSize) + float2(0.5, 0.5)) * pImageTexel);
|
//vtx.uv = ((floor(vtx.uv * pImageSize) + float2(0.5, 0.5)) * pImageTexel);
|
||||||
|
|
||||||
float4 pxCC = pImage.Sample(linearSampler, vtx.uv) * 4.0;
|
float4 pxCC = pImage.Sample(LinearClampSampler, vtx.uv) * 4.0;
|
||||||
float4 pxTL = pImage.Sample(linearSampler, vtx.uv - pImageHalfTexel);
|
float4 pxTL = pImage.Sample(LinearClampSampler, vtx.uv - pImageHalfTexel);
|
||||||
float4 pxTR = pImage.Sample(linearSampler, vtx.uv + pImageHalfTexel);
|
float4 pxTR = pImage.Sample(LinearClampSampler, vtx.uv + pImageHalfTexel);
|
||||||
float4 pxBL = pImage.Sample(linearSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y));
|
float4 pxBL = pImage.Sample(LinearClampSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y));
|
||||||
float4 pxBR = pImage.Sample(linearSampler, 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;
|
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);
|
//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 pxL = pImage.Sample(LinearClampSampler, vtx.uv - float2(pImageHalfTexel.x * 2.0, 0.));
|
||||||
float4 pxBL = pImage.Sample(linearSampler, vtx.uv - float2(pImageHalfTexel.x, -pImageHalfTexel.y));
|
float4 pxBL = pImage.Sample(LinearClampSampler, vtx.uv - float2(pImageHalfTexel.x, -pImageHalfTexel.y));
|
||||||
float4 pxB = pImage.Sample(linearSampler, vtx.uv + float2(0., pImageHalfTexel.y * 2.0));
|
float4 pxB = pImage.Sample(LinearClampSampler, vtx.uv + float2(0., pImageHalfTexel.y * 2.0));
|
||||||
float4 pxBR = pImage.Sample(linearSampler, vtx.uv + pImageHalfTexel);
|
float4 pxBR = pImage.Sample(LinearClampSampler, vtx.uv + pImageHalfTexel);
|
||||||
float4 pxR = pImage.Sample(linearSampler, vtx.uv + float2(pImageHalfTexel.x * 2.0, 0.));
|
float4 pxR = pImage.Sample(LinearClampSampler, vtx.uv + float2(pImageHalfTexel.x * 2.0, 0.));
|
||||||
float4 pxTR = pImage.Sample(linearSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y));
|
float4 pxTR = pImage.Sample(LinearClampSampler, vtx.uv + float2(pImageHalfTexel.x, -pImageHalfTexel.y));
|
||||||
float4 pxT = pImage.Sample(linearSampler, vtx.uv - float2(0., pImageHalfTexel.y * 2.0));
|
float4 pxT = pImage.Sample(LinearClampSampler, vtx.uv - float2(0., pImageHalfTexel.y * 2.0));
|
||||||
float4 pxTL = pImage.Sample(linearSampler, vtx.uv - pImageHalfTexel);
|
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) * 0.083333333333;
|
||||||
// return (((pxTL + pxTR + pxBL + pxBR) * 2.0) + pxL + pxR + pxT + pxB) / 12;
|
// return (((pxTL + pxTR + pxBL + pxBR) * 2.0) + pxL + pxR + pxT + pxB) / 12;
|
||||||
|
|
|
@ -1,18 +1,4 @@
|
||||||
// Parameters:
|
#include "common.effect"
|
||||||
/// 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
|
|
||||||
|
|
||||||
// # Linear Optimization
|
// # Linear Optimization
|
||||||
// While the normal way is to sample every texel in the pSize, 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
|
// faster alternatives than linear sampling with Gaussian Blur, such as
|
||||||
// Dual Filtering ("Dual Kawase").
|
// Dual Filtering ("Dual Kawase").
|
||||||
|
|
||||||
// Sampler
|
//------------------------------------------------------------------------------
|
||||||
sampler_state linearSampler {
|
// Defines
|
||||||
Filter = Linear;
|
//------------------------------------------------------------------------------
|
||||||
AddressU = Clamp;
|
#define MAX_BLUR_SIZE 128
|
||||||
AddressV = Clamp;
|
|
||||||
MinLOD = 0;
|
|
||||||
MaxLOD = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Default Vertex Shader and Data
|
//------------------------------------------------------------------------------
|
||||||
struct VertDataIn {
|
// Technique: Directional / Area
|
||||||
float4 pos : POSITION;
|
//------------------------------------------------------------------------------
|
||||||
float2 uv : TEXCOORD0;
|
float4 PSBlur1D(VertexInformation vtx) : TARGET {
|
||||||
};
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * GetKernelAt(0);
|
||||||
|
|
||||||
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);
|
|
||||||
bool is_odd = ((int(round(pSize)) % 2) == 1);
|
bool is_odd = ((int(round(pSize)) % 2) == 1);
|
||||||
|
|
||||||
// y = yes, s = skip, b = break
|
// 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.
|
// TODO: Determine better position than 0.5 for gaussian approximation.
|
||||||
float2 nstep = (pImageTexel * pStepScale) * (n + 0.5);
|
float2 nstep = (pImageTexel * pStepScale) * (n + 0.5);
|
||||||
float kernel = GetKernelAt(n) + GetKernelAt(n + 1);
|
float kernel = kernelAt(n) + kernelAt(n + 1);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + nstep) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * kernel;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - nstep) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * kernel;
|
||||||
}
|
}
|
||||||
if (is_odd) {
|
if (is_odd) {
|
||||||
float kernel = GetKernelAt(pSize);
|
float kernel = kernelAt(pSize);
|
||||||
float2 nstep = (pImageTexel * pStepScale) * pSize;
|
float2 nstep = (pImageTexel * pStepScale) * pSize;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + nstep) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * kernel;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - nstep) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return final;
|
return final;
|
||||||
|
|
|
@ -1,63 +1,23 @@
|
||||||
// Parameters:
|
#include "common.effect"
|
||||||
/// 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];
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Defines
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
#define MAX_BLUR_SIZE 128
|
#define MAX_BLUR_SIZE 128
|
||||||
|
|
||||||
// Sampler
|
//------------------------------------------------------------------------------
|
||||||
sampler_state linearSampler {
|
// Technique: Directional / Area
|
||||||
Filter = Linear;
|
//------------------------------------------------------------------------------
|
||||||
AddressU = Clamp;
|
float4 PSBlur1D(VertexInformation vtx) : TARGET {
|
||||||
AddressV = Clamp;
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernelAt(0);
|
||||||
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.
|
// Loop unrolling is only possible with a fixed known maximum.
|
||||||
// Some compilers may unroll up to x iterations, but most will not.
|
// Some compilers may unroll up to x iterations, but most will not.
|
||||||
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
||||||
float2 nstep = (pImageTexel * pStepScale) * n;
|
float2 nstep = (pImageTexel * pStepScale) * n;
|
||||||
float kernel = GetKernelAt(n);
|
float kernel = kernelAt(n);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + nstep) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv + nstep) * kernel;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - nstep) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv - nstep) * kernel;
|
||||||
|
|
||||||
if (n >= pSize) {
|
if (n >= pSize) {
|
||||||
break;
|
break;
|
||||||
|
@ -74,30 +34,20 @@ technique Draw {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur Rotation
|
//------------------------------------------------------------------------------
|
||||||
float2 rotate(float2 pt, float angle) {
|
// Technique: Rotate
|
||||||
float cp = cos(angle);
|
//------------------------------------------------------------------------------
|
||||||
float sp = sin(angle);
|
float4 PSRotate(VertexInformation vtx) : TARGET {
|
||||||
float sn = -sp;
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernelAt(0);
|
||||||
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;
|
float angstep = pAngle * pStepScale.x;
|
||||||
|
|
||||||
// Loop unrolling is only possible with a fixed known maximum.
|
// Loop unrolling is only possible with a fixed known maximum.
|
||||||
// Some compilers may unroll up to x iterations, but most will not.
|
// Some compilers may unroll up to x iterations, but most will not.
|
||||||
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
||||||
float kernel = GetKernelAt(n);
|
float kernel = kernelAt(n);
|
||||||
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * n)) * kernel;
|
final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, angstep * n)) * kernel;
|
||||||
final += pImage.Sample(linearSampler, rotateAround(vtx.uv, pCenter, angstep * -n)) * kernel;
|
final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, angstep * -n)) * kernel;
|
||||||
|
|
||||||
if (n >= pSize) {
|
if (n >= pSize) {
|
||||||
break;
|
break;
|
||||||
|
@ -114,10 +64,11 @@ technique Rotate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur Zoom
|
//------------------------------------------------------------------------------
|
||||||
float4 PSZoom(VertDataOut vtx) : TARGET {
|
// Technique: Zoom
|
||||||
float4 final = pImage.Sample(linearSampler, vtx.uv)
|
//------------------------------------------------------------------------------
|
||||||
* GetKernelAt(0);
|
float4 PSZoom(VertexInformation vtx) : TARGET {
|
||||||
|
float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernelAt(0);
|
||||||
|
|
||||||
// step is calculated from the direction relative to the center
|
// step is calculated from the direction relative to the center
|
||||||
float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel;
|
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.
|
// Loop unrolling is only possible with a fixed known maximum.
|
||||||
// Some compilers may unroll up to x iterations, but most will not.
|
// Some compilers may unroll up to x iterations, but most will not.
|
||||||
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
for (int n = 1; n <= MAX_BLUR_SIZE; n++) {
|
||||||
float kernel = GetKernelAt(n);
|
float kernel = kernelAt(n);
|
||||||
final += pImage.Sample(linearSampler, vtx.uv + (dir * n) * dist) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv + (dir * n) * dist) * kernel;
|
||||||
final += pImage.Sample(linearSampler, vtx.uv - (dir * n) * dist) * kernel;
|
final += pImage.Sample(LinearClampSampler, vtx.uv - (dir * n) * dist) * kernel;
|
||||||
|
|
||||||
if (n >= pSize) {
|
if (n >= pSize) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue