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
					
				|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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 New Issue