// Number of outer filter taps #define NUM_DOF_TAPS 12 float2 filterTaps[NUM_DOF_TAPS]; #define SAMPLER_LINEAR(g_samplerMap, g_txMap); \ sampler2D g_samplerMap = sampler_state { \ Texture = ; \ MinFilter = Linear; \ MagFilter = Linear; \ MipFilter = Linear; \ AddressU = WRAP; \ AddressV = WRAP; \ }; texture ColorMap; SAMPLER_LINEAR(ColorMapSampler, ColorMap); texture DepthMap; SAMPLER_LINEAR(DepthMapSampler, DepthMap); struct VS_INPUT { float3 Position : POSITION; }; struct VS_OUTPUT { float4 hPosition : POSITION; // point in normalized device space before homogeneous division float2 TexCoord : TEXCOORD0; }; VS_OUTPUT DepthVS(VS_INPUT IN) { VS_OUTPUT output; output.hPosition = half4(IN.Position, 1); output.TexCoord = IN.Position.xy * 0.5f + 0.5f; output.TexCoord.y *= -1; return output; } //------------------------------------------------------------------------------------ // // // //------------------------------------------------------------------------------------ const float maxCoC = 5; float4 DepthPS(VS_OUTPUT IN) : COLOR { // Get center sample float4 colorSum = tex2D(ColorMapSampler, IN.TexCoord); float2 centerDepthBlur = tex2D(DepthMapSampler, IN.TexCoord); // Compute CoC size based on blurriness float sizeCoC = centerDepthBlur.y * maxCoC; float totalContribution = 1.0f; // Run through all taps for (int i = 0; i < NUM_DOF_TAPS; i++) { // Compute tap coordinates float2 tapCoord = IN.TexCoord + filterTaps[i] * sizeCoC; // Fetch tap sample float4 tapColor = tex2D(ColorMapSampler, tapCoord); float2 tapDepthBlur = tex2D(DepthMapSampler, tapCoord); // Compute tap contribution float tapContribution = (tapDepthBlur.x > centerDepthBlur.x) ? 1.0f : tapDepthBlur.y; // Accumulate color and contribution colorSum += tapColor * tapContribution; totalContribution += tapContribution; } // Normalize to get proper luminance float4 finalColor = colorSum / totalContribution; return finalColor; } //------------------------------------------------------------------------------------ // Technique definitions //------------------------------------------------------------------------------------ technique DepthOfField { pass p0 { VertexShader = compile vs_3_0 DepthVS(); PixelShader = compile ps_3_0 DepthPS(); } }