   Need some help w/ motion blur junk
  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 // Type: Pixel shader   // 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.    float2 finalGrads = abs(pixelVelocity);    float3 Blurred = tex2Dgrad(RenderTargetSampler, OriginalUV, finalGrads.x, finalGrads.y).xyz;    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    { PixelShader = compile ps_3_0 PostProcessMotionBlurPS();    }}and sampler junk:sampler RenderTargetSampler = sampler_state{    Texture = <RenderTargetTexture>;    MipFilter = LINEAR;    MinFilter = ANISOTROPIC;  // was point    MagFilter = ANISOTROPIC;    MaxAnisotropy = 16;    AddressU = Clamp;    AddressV = Clamp;};[Edited by - InvalidPointer on June 8, 2009 8:27:56 PM]
  Nothing? Does anyone at least have info on the behavior of tex2Dgrad? The MSDN documentation is rather... vague.   