Jump to content
  • Advertisement
Sign in to follow this  
VISQI

[DX9] Velocity Mapping

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

[color="#1C2837"]So i am trying to do a pixel motion blur using the same way that nVidia & DX SDK used. Render the scene on surface, calculate the velocity and output it as color info, then render the scene again with motion blur
But the problem is that the Velocity map is not getting any info for some reason.
Here is the code:
[color="#1c2837"]
//Velocity Calculation Shaders
void VelocityVShader(float3 PosL : POSITION0,
out float4 oPosH: POSITION0,
out float2 oVel : TEXCOORD0)
{
//Velocity
float4 CurrVel = mul(float4(PosL,1.0f),gMatWVP);
float4 PrevVel = mul(float4(PosL,1.0f),gMatPrevWVP);

CurrVel /= CurrVel.w;
PrevVel /= PrevVel.w;

oVel = CurrVel - PrevVel;
oVel /= 2.0f;

oPosH = CurrVel;
}

float4 VelocityPShader(float2 Vel : TEXCOORD0):COLOR
{
return float4(Vel,1.0f,1.0f);
}

[color="#1c2837"]Any help on the subject will be really appreciated.

Share this post


Link to post
Share on other sites
Advertisement
1. Where do you calculate gMatWVP and gMatPrevWVP? In shader or in software? And how (like gMatWVP = world x view x projection and gMatPrevWVP = prevWorld x prevView x Projection) ?
2. Can you provide your software code and screenshot(s) ?

Share this post


Link to post
Share on other sites

1. Where do you calculate gMatWVP and gMatPrevWVP? In shader or in software? And how (like gMatWVP = world x view x projection and gMatPrevWVP = prevWorld x prevView x Projection) ?
2. Can you provide your software code and screenshot(s) ?



Both gMatWVP and gMatPrevWVP are calculated in software and passes on to the shaders
gMatPrevWVP = PrevWorld x View x Proj;
i assign gMatPrevWVP to be equal to gMatWVP, and the in the update function, i move gMatWVP accordingly(the scene are 8 rotating spheres rotating in a wheel).

Here is the code:
- RenderVelocityTech() is where i output the velocity map
- UpdateMovement() is where the movement gets updated :)
- RenderToSurface is a class that uses a ID3DXRenderToSurface interface to render to the textures


void BlurApp::Update(float dt)
{
gDI->poll();
gCamera->Update(dt, 0);
gFPS->Update(dt);

if(gDI->Kdown(DIK_ESCAPE))
KillMe();

UpdateMovement(dt);
}

void BlurApp::Render()
{
mCurrVelRTS->Swap(mPrevVelRTS);

RenderVelocityTech();

V(gd3dDev->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000,
1.0f, 0));

if(SUCCEEDED(gd3dDev->BeginScene()))
{
V(BlurFX->SetTechnique(HSceneTech));

UINT NumPasses;
V(BlurFX->Begin(&NumPasses, 0));
V(BlurFX->BeginPass(0));

for(int i = 0; i < NUM_OBJECTS; ++i)
{
V(BlurFX->SetMatrix(HMatWVP, &(mSpheres->World * gCamera->VP())));
V(BlurFX->SetMatrix(HMatPrevWVP, &(mSpheres->PrevWorld * gCamera->VP())));
D3DXMATRIX Inv;
D3DXMatrixTranspose(&Inv, &mSpheres->World);
D3DXMatrixInverse(&Inv, 0, &Inv);
V(BlurFX->SetMatrix(HMatITW, &Inv));

V(BlurFX->SetTexture(HTex, mSpheres->Tex));

V(BlurFX->CommitChanges());
V(mSpheres->Mesh->DrawSubset(0));
}

V(BlurFX->EndPass());
V(BlurFX->End());

gFPS->Render();

V(gd3dDev->EndScene());
}

V(gd3dDev->Present(0, 0, 0, 0));


}

void BlurApp::UpdateMovement(float dt)
{
for(int i = 0; i < NUM_OBJECTS; ++i)
{
float& theta = mSpheres->Theta;
float& r = mSpheres->R;

theta += Speed * dt;

float x = r*cosf(theta);
float z = r*sinf(theta);

mSpheres->PrevWorld = mSpheres->World;

D3DXMatrixTranslation(&mSpheres->World, x, 0.0f, z);
}
}

void BlurApp::RenderVelocityTech()
{
mCurrVelRTS->BeginScene();

//No Z-Buffer
V(gd3dDev->Clear(0, 0, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0));

V(BlurFX->SetTechnique(HVelTech));

UINT NumPasses = 0;
V(BlurFX->Begin(&NumPasses, 0));
V(BlurFX->BeginPass(0));

for(int i = 0; i < NUM_OBJECTS; ++i)
{
V(BlurFX->SetMatrix(HMatWVP, &(mSpheres->World * gCamera->VP())));
V(BlurFX->SetMatrix(HMatPrevWVP, &(mSpheres->PrevWorld * gCamera->VP())));

V(BlurFX->CommitChanges());
V(mSpheres->Mesh->DrawSubset(0));
}

V(BlurFX->EndPass());
V(BlurFX->End());

mCurrVelRTS->EndScene();
}

Share this post


Link to post
Share on other sites
Are you getting any output (e.g. a purple-blue mixed screen)? If so, you've a problem with swapping previous and current velocity maps. If not (i.e. you're getting a black screen or something like that) you've a problem with your render-to-surface thing. Are you sure you can render to that texture-like-class?

Share this post


Link to post
Share on other sites

Are you getting any output (e.g. a purple-blue mixed screen)? If so, you've a problem with swapping previous and current velocity maps. If not (i.e. you're getting a black screen or something like that) you've a problem with your render-to-surface thing. Are you sure you can render to that texture-like-class?


i missed with it a bit and i was able to get a little out of it. Now i do get some blur, but not much.

My RenderToSurface class is solid, i tried it with a Shadow Mapping demo before and it worked, plus it does work now.
Here is a picture of the velocity map from PIX
and here is a screenshot of the demo
As you can see, the blur is barely visible. It is there if you see it moving, but it is BARELY visible.
So i am guessing it is a problem with the Pixel Shader that calculates the lighting(and interpolates the velocity) on the scene
If you want to take a look at it


float4 ScenePShader(float4 PosH : POSITION0,
float3 NormW: TEXCOORD0,
float2 TexC : TEXCOORD1):COLOR0
{
//Velocity
float4 CurrVel = tex2D(sCurrVelTex, TexC);
float4 PrevVel = tex2D(sPrevVelTex, TexC);

float SqCurrVel = CurrVel.r * CurrVel.r +
CurrVel.g * CurrVel.g;
float SqPrevVel = PrevVel.r * PrevVel.r +
PrevVel.g * PrevVel.g;

float2 Velocity;
if(SqCurrVel > SqPrevVel)
{
Velocity.x = CurrVel.x * gBlurConst;
Velocity.y = -CurrVel.y * gBlurConst;
}

else
{
Velocity.x = PrevVel.x * gBlurConst;
Velocity.y = -PrevVel.y * gBlurConst;
}

//Lighting
float d = max(dot(NormW, -gLight.DirW), 0.0f);

float3 Diff = d * (gMtrl.Diff.rgb + gLight.Diff.rgb);
float3 Amb = (gMtrl.Amb + gLight.Amb).rgb;

float4 Blurred = 0;

for(int i = 0; i < 12; ++i)
{
float2 LookUp = Velocity*(i/12) + TexC;
float4 Value = tex2D(sTex, LookUp);

Blurred += Value;
}

Blurred /= 12.0f;

float3 FinalColor = (Diff+Amb) * Blurred.rgb;

return float4(FinalColor,1.0f);

}

In this build, gBlurConst = 2.0f
gCurrVelTex is the current velocity texture and the one that i use with RenderToSurface
gPrevVelTex is the previous velocity texture and the one that i swap with gCurrVelTex before i update gCurrVelTex

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!