135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| // AUTOGENERATED COPYRIGHT HEADER START
 | |
| // Copyright (C) 2019-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
 | |
| // AUTOGENERATED COPYRIGHT HEADER END
 | |
| 
 | |
| #include "common.effect"
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Uniforms
 | |
| //------------------------------------------------------------------------------
 | |
| // This shader requires that pSize is the number of samples, not the size of the
 | |
| // kernel. That way oversampling can be performed, which is much more accurate than
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Defines
 | |
| //------------------------------------------------------------------------------
 | |
| #define MAX_SAMPLES 128u
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Technique: Directional / Area
 | |
| //------------------------------------------------------------------------------
 | |
| float4 PSBlur1D(VertexInformation vtx) : TARGET {
 | |
| 	float2 uvstep = pImageTexel * pStepScale;
 | |
| 	float weights = 0;
 | |
| 
 | |
| 	// Move to texel center.
 | |
| 	vtx.uv.xy += pImageTexel.xy / 2.;
 | |
| 
 | |
| 	// Calculate the actual Gaussian Blur
 | |
| 	// 1. Sample the center immediately.
 | |
| 	float kernel = kernelAt(0u);
 | |
| 	weights += kernel;
 | |
| 	float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernel;
 | |
| 
 | |
| 	// 2. Then sample both + and - coordinates in one go to reduce code iterations.
 | |
| 	for (uint step = 1u; (step < uint(pSize)) && (step < MAX_SAMPLES); step++) {
 | |
| 		float2 offset = uvstep * float2(step, step);
 | |
| 		kernel = kernelAt(step);
 | |
| 		weights += kernel * 2.;
 | |
| 
 | |
| 		final += pImage.Sample(LinearClampSampler, vtx.uv + offset) * kernel;
 | |
| 		final += pImage.Sample(LinearClampSampler, vtx.uv - offset) * kernel;
 | |
| 	}
 | |
| 
 | |
| 	// 3. Ensure we always have a total of 1.0, even if the kernel is bad.
 | |
| 	final /= weights;
 | |
| 
 | |
| 	return final;
 | |
| }
 | |
| 
 | |
| technique Draw {
 | |
| 	pass {
 | |
| 		vertex_shader = VSDefault(vtx);
 | |
| 		pixel_shader  = PSBlur1D(vtx);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Technique: Rotate
 | |
| //------------------------------------------------------------------------------
 | |
| float4 PSRotate(VertexInformation vtx) : TARGET {
 | |
| 	float angstep = pAngle * pStepScale.x;
 | |
| 	float weights = 0.;
 | |
| 
 | |
| 	// Move to texel center.
 | |
| 	vtx.uv.xy += pImageTexel.xy / 2.;
 | |
| 
 | |
| 	// Calculate the actual Gaussian Blur
 | |
| 	// 1. Sample the center immediately.
 | |
| 	float kernel = kernelAt(0u);
 | |
| 	weights += kernel;
 | |
| 	float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernel;
 | |
| 
 | |
| 	// 2. Then sample both + and - coordinates in one go to reduce code iterations.
 | |
| 	for (uint step = 1u; (step < uint(pSize)) && (step < MAX_SAMPLES); step++) {
 | |
| 		float offset = angstep * step;
 | |
| 		kernel = kernelAt(step);
 | |
| 		weights += kernel * 2.;
 | |
| 
 | |
| 		final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, offset)) * kernel;
 | |
| 		final += pImage.Sample(LinearClampSampler, rotateAround(vtx.uv, pCenter, -offset)) * kernel;
 | |
| 	}
 | |
| 
 | |
| 	// 3. Ensure we always have a total of 1.0, even if the kernel is bad.
 | |
| 	final /= weights;
 | |
| 
 | |
| 	return final;
 | |
| }
 | |
| 
 | |
| technique Rotate {
 | |
| 	pass {
 | |
| 		vertex_shader = VSDefault(vtx);
 | |
| 		pixel_shader  = PSRotate(vtx);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Technique: Zoom
 | |
| //------------------------------------------------------------------------------
 | |
| float4 PSZoom(VertexInformation vtx) : TARGET {
 | |
| 	float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel;
 | |
| 	float dist = distance(vtx.uv, pCenter);
 | |
| 	float weights = 0.;
 | |
| 
 | |
| 	// Move to texel center.
 | |
| 	vtx.uv.xy += pImageTexel.xy / 2.;
 | |
| 
 | |
| 	// Calculate the actual Gaussian Blur
 | |
| 	// 1. Sample the center immediately.
 | |
| 	float kernel = kernelAt(0u);
 | |
| 	weights += kernel;
 | |
| 	float4 final = pImage.Sample(LinearClampSampler, vtx.uv) * kernel;
 | |
| 
 | |
| 	// 2. Then sample both + and - coordinates in one go to reduce code iterations.
 | |
| 	for (uint step = 1u; (step < uint(pSize)) && (step < MAX_SAMPLES); step++) {
 | |
| 		float2 offset = dir * step * dist;
 | |
| 		kernel = kernelAt(step);
 | |
| 		weights += kernel * 2.;
 | |
| 
 | |
| 		final += pImage.Sample(LinearClampSampler, vtx.uv + offset) * kernel;
 | |
| 		final += pImage.Sample(LinearClampSampler, vtx.uv - offset) * kernel;
 | |
| 	}
 | |
| 
 | |
| 	// 3. Ensure we always have a total of 1.0, even if the kernel is bad.
 | |
| 	final /= weights;
 | |
| 
 | |
| 	return final;
 | |
| }
 | |
| 
 | |
| technique Zoom {
 | |
| 	pass {
 | |
| 		vertex_shader = VSDefault(vtx);
 | |
| 		pixel_shader  = PSZoom(vtx);
 | |
| 	}
 | |
| }
 |