//**************************************************************************/ // 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 motion vectors in the direction of motion. // AUTHOR: Kells Elmquist // CREATED: November 2010 //**************************************************************************/ #include "Common.cgh" ///////////////////////////////////////////////////////////////////////////// // // Spread motion vectors to affected pixels // // The source velocity texure uniform texture sourceVelocity; uniform sampler2D velocitySamp = sampler_state { Texture = ; }; uniform int filterRadius = 16; // in pixels, radius 4 = 9x9 samples; 8 = 17x17; side=2*radius+1 uniform float2 filterDirection; // (0,1) for V pass or (1,0) for H pass uniform int filterScale = 3; // stride between pixel samples in motion spreading, 2x2 default // Pixel shader. // NOTE: This expects screen quad vertex shader output. float4 spreadMotionBlur( VS_TO_PS_ScreenQuad In ) : COLOR0 { // Compute the offset between samples in uv space float2 offset = (float)filterScale * filterDirection * gTexelSize; // get start uv float2 UV = In.UV - offset * filterRadius; float4 v0 = tex2D(velocitySamp, In.UV); // center pix, for pass thru v0.zw // Get the velocoty value in each qualified sample point and average them float2 avgVelocity = (float2)0; float weightSum = 0.0f; for (int i = 0; i < (2*filterRadius+1); i++) { float4 vn = tex2D(velocitySamp, UV); float2 duv = (UV - In.UV); // H or V vector from center to sample float duv2 = dot( duv, duv); // square of length of duv float vn2 = 2.0f * dot( vn.xy, vn.xy); // square of length of vn // if the sample is a moving pixel this frame... if( (vn.w > 0 ||( dot((float2)1, abs(vn.xy)) > 0.001f )) && (vn2 >= duv2) // affects in length && (dot( vn.xy, duv) > -0.01f) // non-opposite directions ){ avgVelocity += vn.xy; weightSum += 1.0f; } // Increment the texture coordinates by the offset. UV += offset; } if( weightSum != 0.0f ) avgVelocity /= weightSum; return float4( avgVelocity.x, avgVelocity.y, v0.z, v0.w ); // preserve z & w from original } // shader for either pass of the 2 pass h/v spreading technique. technique spreadMotionPass { pass p0 { VertexShader = compile glslv VS_ScreenQuad(); // A horizontal blur direction is specified as an argument above. PixelShader = compile glslf spreadMotionBlur(); } }