MotionBlur use DepthBuffer problems
I want to add the MotionBlur effect to my project.I tried the way using velocity buffer in DX9 demo, that works well. Then I read "MotionBlur as a Post-Processing Effect" in GPU Gems3.There is a smart idea to use depth buffer instead which looks obviously better.So I tried that way using the same scene in DX9 demo...I found ugly artifacts ,that blur distort largely when u moving the camera...
Is my Depth Buffer not accurate enough?
I use D3DFMT_R32F to restore the z-vlue multipled by viewprojmatrix...and I calculate it in pixel shader?
Frgive my poor English....Any suggestion is welcome!!!
I doubt it's due to depth buffer precision....I use the same technique in my game and it works quite well. However I do clamp the velocity vector I get to a certain range, in order to prevent artifacts that occur from not using a enough texture samples. Here's my HLSL, in case it helps...
float g_fBlurAmount = 1.0f;float4x4 g_matInvView;float4x4 g_matLastViewProj;float4 MotionBlurPS ( in float2 in_vTexCoord : TEXCOORD0, in float3 in_vFrustumPlaneVS : TEXCOORD1, uniform int iNumSamples ) : COLOR0 { // Reconstruct view-space position from the depth buffer float fPixelDepthVS = tex2D(PointSampler1, in_vTexCoord).x; float3 vPixelPositionVS = fPixelDepthVS * in_vFrustumPlaneVS; // Convert to world-space, then determine the the clip-space // position of the pixel in the previous frame. float4 vPixelPositionWS = mul(float4(vPixelPositionVS, 1.0f), g_matInvView); float4 vLastPixelPosCS = mul(vPixelPositionWS, g_matLastViewProj); // Find the corresponding texture coordinate float2 vLastTexCoord = vLastPixelPosCS.xy / vLastPixelPosCS.w; vLastTexCoord = (vLastTexCoord / 2.0f) + 0.5f; vLastTexCoord.y = 1.0f - vLastTexCoord.y; vLastTexCoord += 1.0f / g_vDestinationDimensions; float2 vPixelVelocity = in_vTexCoord - vLastTexCoord; // Clamp to a max velocity. The max we can go without artifacts os // is 1.4f * iNumSamples...but we can fudge things a little. float2 maxVelocity = (2.0f * iNumSamples) / g_vSourceDimensions; vPixelVelocity = clamp(vPixelVelocity, -maxVelocity, maxVelocity); float2 vFinalSamplePos = in_vTexCoord + vPixelVelocity; // For each sample, sum up each sample's color in "vSum" and then divide // to average the color after all the samples are added. float4 vSum = 0; for(int i = 0; i < iNumSamples; i++) { // Sample texture in a new spot based on vPixelVelocity vector // and average it with the other samples float2 vTexCoord = lerp(in_vTexCoord, vFinalSamplePos, (i / (float)iNumSamples)); // Lookup the color at this new spot float4 vSample = tex2D(PointSampler0, vTexCoord); // Add it with the other samples vSum += vSample; } // Return the average color of all the samples return vSum / (float)iNumSamples;}
Quote:Original post by MJP
I doubt it's due to depth buffer precision....I use the same technique in my game and it works quite well. However I do clamp the velocity vector I get to a certain range, in order to prevent artifacts that occur from not using a enough texture samples. Here's my HLSL, in case it helps...
*** Source Snippet Removed ***
Thanks for your help...I've made a mistake.The value in DepthBuffer should be the one divided by w-vlue. Now the effect seems to be right. :-)
And your "clamp velocity" way works nice. Also I advice to set the final sampler's address to be "Mirror" not "Clamp"...Because when u turn around your camera , the screen posion might not always in [-1,1].
There is still slight artifacts at the screen edge, but they are tolerable.
Quote:Original post by ZoBuzz
Also I advice to set the final sampler's address to be "Mirror" not "Clamp"...Because when u turn around your camera , the screen posion might not always in [-1,1].
There is still slight artifacts at the screen edge, but they are tolerable.
Not a bad idea. I'll try that, thanks. [smile]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement