//sampler tSource //full res image
//sampler tSourceLow // downsampled image
texture postTex1;
texture postTex2;
sampler tSource = sampler_state
{
texture = (postTex1);
MinFilter = linear;
MagFilter = linear;
MipFilter = linear;
AddressU = Clamp;
AddressV = Clamp;
};
sampler tSourceLow = sampler_state
{
texture = (postTex1);
MinFilter = linear;
MagFilter = linear;
MipFilter = linear;
AddressU = Clamp;
AddressV = Clamp;
};
//downsample-----------------------------------------------------------------------------------------------------------------------------------------------
float4x4 matMVP;
float PixelOffset = 10;
float Kd = 1.1;
struct VS_OUT
{
float4 Pos: POSITION;
float2 Tex: TEXCOORD0;
};
VS_OUT vs_down_main( float3 inPos: POSITION, float2 inTex: TEXCOORD0 )
{
VS_OUT OUT;
// Output the transformed vertex
OUT.Pos = mul( matMVP, float4( inPos, 1 ) );
// Output the texture coordinates
OUT.Tex = inTex + ( PixelOffset * 0.5 );
return OUT;
}
float4 SuppressLDR( float4 c )
{
if( c.r > 1.0f || c.g > 1.0f || c.b > 1.0f )
{return c;}
else
{return float4( 0.0f, 0.0f, 0.0f, 0.0f );}
}
float4 ps_down_main( float2 inTex: TEXCOORD0 ) : COLOR0
{
float4 color = tex2D(tSourceLow, inTex) * Kd;
return SuppressLDR( color );
}
//depth alpha-----------------------------------------------------------------------------------------------------------------------------------------------
/*
float4 vDofParams;
float ComputeDepthBlur(float depth){
float f;
if (depth < vDofParams.y){
f = (depth - vDofParams.y)/(vDofParams.y - vDofParams.x);
}
else{
f = (depth - vDofParams.y)/(vDofParams.z - vDofParams.y);
f = clamp(f, 0, vDofParams.w);
}
return f * 0.5f + 0.5f;
}
*/
//DoF---------------------------------------------------------------------------------------------------------------------------------------------
float2 poisson[12] = {
-0.326212, -0.405805,
-0.840144, -0.073580,
-0.695914, 0.457137,
-0.203345, 0.620716,
0.962340, -0.194983,
0.473434, -0.480026,
0.519456, 0.767022,
0.185461, -0.893124,
0.507431, 0.064425,
0.896420, 0.412458,
-0.321940, -0.932615,
-0.791559, -0.597705,
};
float2 pixelSizeHigh = {512, 512}; //pixel size of high res image
float2 pixelSizeLow = {4, 4}; //pixel size of low res image
float2 vMaxCoC = float2(5.0, 10.0);
float radiusScale = 0.0004;
float4 PoissonDOFFilter (float2 texCoord: TEXCOORD0, float2 Tex : TEXCOORD0) : COLOR0{
float4 cOut;
float discRadius, discRadiusLow, centerDepth;
cOut = tex2D (tSource, texCoord); //fetch center tap
centerDepth = cOut.a;
//convert depth into blur radius in pixels
discRadius = abs (cOut.a * vMaxCoC.y - vMaxCoC.x);
discRadiusLow = discRadius * radiusScale; //compute radius on low-res image reusing cOut to accumulate samples
for (int t = 0; t < 12; t++){
//compute tap texture coordinates
float2 coordLow = texCoord + (pixelSizeLow * poisson[t] * discRadiusLow);
float2 coordHigh = texCoord + (pixelSizeHigh * poisson[t] * discRadius);
//fetch high-res tap
float4 tapLow = tex2D(tSource, coordLow);
float4 tapHigh = tex2D(tSource, coordHigh);
//mix low- and high-res taps based on tap blurriness
float tapBlur = abs(tapHigh.a * 2.0 - 1.0); //put blurriness into [0,1]
float4 tap = lerp(tapHigh, tapLow, tapBlur);
//"smart" blur ignores taps that are closer than the center tap and in focus
tap.a = (tap.a >= centerDepth) ? 1.0 : abs (tap.a * 2.0 - 1.0);
cOut.rgb += tap.rgb * tap.a; //accumulate
cOut.a += tap.a;
}
return (cOut / cOut.a);
}
technique PostProcess {
pass p1 {
VertexShader = compile vs_1_1 vs_down_main();
PixelShader = compile ps_2_0 ps_down_main();
}
pass p2 {
VertexShader = null;
PixelShader = compile ps_3_0 PoissonDOFFilter();
}
}