147 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| // 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
 | |
| 
 | |
| // 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);
 | |
| 
 | |
| 	// 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;
 | |
| 
 | |
| 		if (n >= pSize) {
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return final;
 | |
| }
 | |
| 
 | |
| technique Draw {
 | |
| 	pass {
 | |
| 		vertex_shader = VSDefault(vtx);
 | |
| 		pixel_shader  = PSBlur1D(vtx);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // 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);
 | |
| 	
 | |
| 	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;
 | |
| 
 | |
| 		if (n >= pSize) {
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	return final;
 | |
| }
 | |
| 
 | |
| technique Rotate {
 | |
| 	pass {
 | |
| 		vertex_shader = VSDefault(vtx);
 | |
| 		pixel_shader  = PSRotate(vtx);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Blur Zoom
 | |
| float4 PSZoom(VertDataOut vtx) : TARGET {
 | |
| 	float4 final = pImage.Sample(linearSampler, vtx.uv)
 | |
| 		* GetKernelAt(0);
 | |
| 
 | |
| 	// step is calculated from the direction relative to the center
 | |
| 	float2 dir = normalize(vtx.uv - pCenter) * pStepScale * pImageTexel;
 | |
| 	float dist = distance(vtx.uv, pCenter);
 | |
| 
 | |
| 	// 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;
 | |
| 
 | |
| 		if (n >= pSize) {
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return final;
 | |
| }
 | |
| 
 | |
| technique Zoom {
 | |
| 	pass {
 | |
| 		vertex_shader = VSDefault(vtx);
 | |
| 		pixel_shader  = PSZoom(vtx);
 | |
| 	}
 | |
| }
 |