//**************************************************************************/ // Copyright (c) 2010 Autodesk, Inc. // All rights reserved. // // These coded instructions, statements, and computer programs contain // unpublished proprietary information written by Autodesk, Inc., and are // protected by Federal copyright law. They may not be disclosed to third // parties or copied or duplicated in any form, in whole or in part, without // the prior written consent of Autodesk, Inc. //**************************************************************************/ // DESCRIPTION: Spread the influence of DOF to neighboring pixels. // AUTHOR: Kells Elmquist // CREATED: November 2010 //**************************************************************************/ #include "Common.cgh" ///////////////////////////////////////////////////////////////////////////// // // Spread DOF vectors to affected pixels // // The source image texure uniform texture source; uniform sampler2D sourceSamp = sampler_state { Texture = ; }; uniform texture cocDepth; uniform sampler2D cocDepthSamp = sampler_state { Texture = ; }; uniform int searchRadius = 8; // in pixels, radius 4 = 9x9 samples; 8 = 17x17; side=2*radius+1 uniform float2 searchDirection; // (0,1) for V pass or (1,0) for H pass uniform int sampleSpacing = 1; // stride between pixel samples in motion spreading, 2x2 default // filter kernel, return value of kernel of radius r at a distance x from the filter center // both x & r must be positive float filter( float r, float x, float widthInv ) { //// box filter // return 1.0f; // test for sharp if( r <= 0.00001f ) r = 0.00001f; // unit linear (triangle) kernel //return saturate( 1.0f - x/r ); // normalized linear (triangle) kernel: 1/(r*w) * (1 - x/r) float h = ( widthInv / r ); return saturate( h * (1.0f - x/r) ); // unit gaussian kernel //return 0.79788f * exp( -x*x/(0.375 * r*r) ) / r; } // Pixel shader. // NOTE: This expects screen quad vertex shader output. float4 spreadNearDOFBlur( VS_TO_PS_ScreenQuad In ) : COLOR0 { // Compute the offset between samples in uv space float2 offset = searchDirection * gTexelSize; // size of one pixel in the search direction in uv space float pixelInv = dot( offset, (float2)1 ); offset *= (float)sampleSpacing; // center pixel //float4 s0 = tex2D(sourceSamp, In.UV); float4 c0 = tex2D(cocDepthSamp, In.UV); //c0.x = min( abs( c0.x ), maxCoc ); float coc0 = abs( c0.x ); // get start uv, clr & weight sums float2 UV = In.UV - offset * searchRadius; float4 clrSum = (float4)0; //float wSum = 0.0f; //float hits = 0.0f; // collect each qualified sample point, then weight & average them for (int i = 0; i < (2*searchRadius+1); i++) { float4 cn = tex2D(cocDepthSamp, UV); // fixup the coc for bgnd pixels, buffer is cleared to 10e6 //if( cn.y > 999990 ) // cn.x = cocAtInfinity; //float coc = min( abs( cn.x ), maxCoc ); float coc = abs( cn.x ); float d = dot( UV - In.UV, (float2)1 ); // H or V distance from center to sample in uv space // qualify samples by z, note z is stored in y field of float2 // & see if coc's overlap if( ( coc > d ) && ( cn.x <= -0.001f ) // in near out-of-focus zone only ){ // yes, coc of sample overlaps this pixel, get it's weight & add it //hits += 1.0f; float w = filter( coc, d, pixelInv ); //wSum += w; clrSum += w * tex2D(sourceSamp, UV); } // Increment the texture coordinates by the offset. UV += offset; } // if( wSum != 0.0f ) //clrSum.xyz /= wSum; return clrSum; //* hits / (float)(2*searchRadius+1); } // shader for either pass of the 2 pass h/v spreading technique. technique spreadNearDOFPass { pass p0 { VertexShader = compile glslv VS_ScreenQuad(); PixelShader = compile glslf spreadNearDOFBlur(); } }