# Need some help w/ motion blur junk

This topic is 3329 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I was going through my big pile o' graphics papers again today, and rediscovered this underappreciated gem. I got to thinking, (and although they don't explicitly mention this usage) it turns out you can use the same trick for the post-processing variant pretty easily. Or so I thought. Seeing as my personal framework is currently down for the count, I did my best to hack together an implementation in the DirectX SDK. It worked, sorta. The quality of the blur is *great* at 16x-level aniso, and it performs slightly faster too (around ~550-600FPS using new method, ~480-500FPS using naive sampling) The downside is that for some unexplained reason, the tex2Dgrad appears to selectively reinterpret the derivatives as (AFAIK) {1.0, -1.0} with no apparent rhyme or reason. I've goofed with the math w/ no useful results, same problem. I remember reading somewhere that if the derivatives grow too high, it screws over the filtering. I distantly suspect this is the problem, though I can't imagine why values in the range [-1...1] would screw it up so. Here's a pitcher. Note the slick blurring. Does anyone have any ideas? EDIT: I just realized how enormously useless this is without code. Here. Have lots.
//-----------------------------------------------------------------------------
// Name: PostProcessMotionBlurPS
// Desc: Uses the pixel's velocity to sum up and average pixel in that direction
//       to create a blur effect based on the velocity in a fullscreen
//       post process pass.
//-----------------------------------------------------------------------------
float4 PostProcessMotionBlurPS( float2 OriginalUV : TEXCOORD0 ) : COLOR
{
float2 pixelVelocity;

// Get this pixel's current velocity and this pixel's last frame velocity
// The velocity is stored in .r & .g channels
float4 curFramePixelVelocity = tex2D(CurFramePixelVelSampler, OriginalUV);
float4 lastFramePixelVelocity = tex2D(LastFramePixelVelSampler, OriginalUV);

// If this pixel's current velocity is zero, then use its last frame velocity
// otherwise use its current velocity.  We don't want to add them because then
// you would get double the current velocity in the center.
// If you just use the current velocity, then it won't blur where the object
// was last frame because the current velocity at that point would be 0.  Instead
// you could do a filter to find if any neighbors are non-zero, but that requires a lot
// of texture lookups which are limited and also may not work if the object moved too
// far, but could be done multi-pass.
float curVelocitySqMag = curFramePixelVelocity.r * curFramePixelVelocity.r +
curFramePixelVelocity.g * curFramePixelVelocity.g;
float lastVelocitySqMag = lastFramePixelVelocity.r * lastFramePixelVelocity.r +
lastFramePixelVelocity.g * lastFramePixelVelocity.g;

if( lastVelocitySqMag > curVelocitySqMag )
{
pixelVelocity.x =  lastFramePixelVelocity.r * PixelBlurConst;
pixelVelocity.y = -lastFramePixelVelocity.g * PixelBlurConst;
}
else
{
pixelVelocity.x =  curFramePixelVelocity.r * PixelBlurConst;
pixelVelocity.y = -curFramePixelVelocity.g * PixelBlurConst;
}

// META-COMMENT: The old code
// For each sample, sum up each sample's color in "Blurred" and then divide
// to average the color after all the samples are added.
/*
float3 Blurred = 0;
for(float i = 0; i < NumberOfPostProcessSamples; i++)
{
// Sample texture in a new spot based on pixelVelocity vector
// and average it with the other samples
float2 lookup = pixelVelocity * i / NumberOfPostProcessSamples + OriginalUV;

// Lookup the color at this new spot
float4 Current = tex2D(RenderTargetSampler, lookup);

// Add it with the other samples
Blurred += Current.rgb;
}

// Return the average color of all the samples
return float4(Blurred / NumberOfPostProcessSamples, 1.0f);
*/
// META-COMMENT: My new stuff.
return float4(Blurred, 1.0f);
}


Extra bits:
//-----------------------------------------------------------------------------
// Name: PostProcessMotionBlur
// Type: Technique
// Desc: Renders a full screen quad and uses velocity information stored in
//       the textures to blur image.
//-----------------------------------------------------------------------------
technique PostProcessMotionBlur
{
pass P0
{
}
}


and sampler junk:
sampler RenderTargetSampler =
sampler_state
{
Texture = <RenderTargetTexture>;
MipFilter = LINEAR;
MinFilter = ANISOTROPIC;  // was point
MagFilter = ANISOTROPIC;
MaxAnisotropy = 16;

};


[Edited by - InvalidPointer on June 8, 2009 8:27:56 PM]

##### Share on other sites
Nothing? Does anyone at least have info on the behavior of tex2Dgrad? The MSDN documentation is rather... vague.

1. 1
2. 2
Rutin
22
3. 3
4. 4
JoeJ
16
5. 5

• 14
• 29
• 9
• 11
• 11
• ### Forum Statistics

• Total Topics
631775
• Total Posts
3002278
×