Jump to content
  • Advertisement
Sign in to follow this  
Juliean

Storing D3DMATRIX-data

This topic is 2607 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

Hi,

I wonder if there is anything I have to consult when storing matrix data? Especially talking about world-view-projection matrices. As I'm writing a motion-blur-shader for my postprocessing-framework, I need to store the world-view-projection-matrix of last frame. However, I'm running into some weird behaviour here.

void CMesh::Render(D3DXVECTOR3 Position, D3DXVECTOR3 Rotation, D3DXVECTOR3 Scale)
{
SetWorldTransformation(Position, Rotation, Scale);

UINT NumPasses = 1;
m_Effect->Begin(&NumPasses, D3DXFX_DONOTSAVESTATE);

D3DXMATRIX matWorld, matView, matProj;
m_lpDevice->GetTransform(D3DTS_WORLD, &matWorld);
HRESULT hr = m_Effect->SetMatrix("World", &matWorld);

m_lpDevice->GetTransform(D3DTS_VIEW, &matView);
m_lpDevice->GetTransform(D3DTS_PROJECTION, &matProj);

D3DXMATRIX matWorldViewProj = matWorld * matView * matProj;

m_Effect->SetMatrix("WorldViewProj", &matWorldViewProj);
m_Effect->SetMatrix("LastWorldViewProj", &m_LastWorld);

m_LastWorld = matWorldViewProj;

for(DWORD i=0;i<m_NumMaterials;i++)
{
m_Effect->SetTexture("DiffuseMap",m_lpTextures);
D3DMATERIAL9 Diffuse = {1.0, 1.0, 1.0, 1.0};
m_Effect->SetVector("MaterialDiffuse", (D3DXVECTOR4*)&(Diffuse));
m_Effect->SetVector("MaterialSpecular", (D3DXVECTOR4*)&(Diffuse));
m_Effect->SetFloat("SpecularPower", 1.0);
/*m_Effect->SetVector("MaterialDiffuse", (D3DXVECTOR4*)&(m_lpMaterials.Diffuse));
m_Effect->SetVector("MaterialSpecular", (D3DXVECTOR4*)&(m_lpMaterials.Specular));
m_Effect->SetFloat("SpecularPower", m_lpMaterials.Power);*/
if(m_Bump!= NULL)
m_Effect->SetTexture("BumpMap", m_Bump);
for(unsigned int j=0;j<NumPasses;j++)
{

m_Effect->BeginPass(j);
m_lpDevice->SetMaterial(&m_lpMaterials);

m_lpMesh->DrawSubset(i);
m_Effect->EndPass();
}
}

m_Effect->End();
}


This is my code for rendering a mesh. Pay attention to these lines:

D3DXMATRIX matWorldViewProj = matWorld * matView * matProj;

m_Effect->SetMatrix("WorldViewProj", &matWorldViewProj);
m_Effect->SetMatrix("LastWorldViewProj", &m_LastWorld);

m_LastWorld = matWorldViewProj;


If I use it this way, my motion blur does that: Nothing at all as long as meshs stay in position (no matter if origin or not, it only has to be their very first position after getting loaded). If I move any mesh, the blur gets gradually stronge the further away the mesh moves from it's first position. What is going on? I made sure that there is basically nothing wrong with my shader, so I did 3 things:

1. put "m_LastWorld = matWorldViewProj;" before the set of "LastWorldViewProj". No blur at all, as both matrices are identical. Not my shaders fault.

2. Changed this line to "m_Effect->SetMatrix("LastWorldViewProj", &matWorldViewProj);" again, no blur. fine.

3. Finally I said f*** it and changed my shader to use both the last matrix as well as the present matrix to calculate both values for motion-distance, to exclude the remote change that there'd ever be any calculation issue (I had some of these before..) Quess what: no blur.

Let' sum up: Blur is working correctly in case the mesh is not on it's very first position (where the fuck does my program knows where the original position of my meshs was??), also with camera movement, but even if the camera is standing still. Blur is increasing with distance.

Does anyone has a idea whats going on here? Talking about my points 1.-3. I can only assume that there is some problem with storing the matrix data..

Just for completition, here is my blur-shader (I'm using the directx-sdk-example as a basis):

This shader outputs the velocity:
VS_OUTPUT_BUILD vsBuild(VS_INPUT_BUILD i)
{
VS_OUTPUT_BUILD o;

float4 vWVPPos = mul(i.vPos, WorldViewProj);
float4 vPosLast = mul(i.vPos, LastWorldViewProj);

vWVPPos /= 50000.0f;
vPosLast /= 50000.0f;

o.vVelocity = vWVPPos - vPosLast;
o.vVelocity /= 2.0f;

return o;
};


And here is the motion calcuation:

#define PixelBlurConst 1.0f
#define NumberOfPostProcessSamples 12.0f

texture ColorMap;
texture NormalMap;
texture PositionMap;
texture ShadowMap;
texture ImageMap;

texture LastColorMap;
texture LastNormalMap;
texture LastPositionMap;
texture LastShadowMap;

sampler2D ColorSampler =
sampler_state
{
Texture = <ColorMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D NormalSampler =
sampler_state
{
Texture = <NormalMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D PositionSampler =
sampler_state
{
Texture = <PositionMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D ShadowSampler =
sampler_state
{
Texture = <ShadowMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};

sampler2D LastColorSampler =
sampler_state
{
Texture = <LastColorMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D LastNormalSampler =
sampler_state
{
Texture = <LastNormalMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D LastPositionSampler =
sampler_state
{
Texture = <LastPositionMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D LastShadowSampler =
sampler_state
{
Texture = <LastShadowMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};


sampler2D ImageSampler =
sampler_state
{
Texture = <ImageMap>;
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Point;
MagFilter = Linear;
MipFilter = Linear;
};

//-----------------------------------------------------------------------------
// Pixel Shader: Combine
// Desc: Combine the source image with the original image.
//-----------------------------------------------------------------------------
float4 Combine( float2 Tex : TEXCOORD0) : COLOR0
{
float2 pixelVelocity;

float2 curFramePixelVelocity = float2(tex2D(ShadowSampler, Tex).b, tex2D(NormalSampler, Tex).a);
float2 lastFramePixelVelocity = float2(tex2D(LastShadowSampler, Tex).b, tex2D(LastNormalSampler, Tex).a);

float curVelocitySqMag = curFramePixelVelocity.x * curFramePixelVelocity.x +
curFramePixelVelocity.y * curFramePixelVelocity.y;
float lastVelocitySqMag = lastFramePixelVelocity.x * lastFramePixelVelocity.x +
lastFramePixelVelocity.y * lastFramePixelVelocity.y;

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

// 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 + Tex;

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

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

//return float4(pixelVelocity, 1, 1);
//return float4(curFramePixelVelocity, 1, 1);
// Return the average color of all the samples
return float4(Blurred / NumberOfPostProcessSamples, 1.0f);
}




//-----------------------------------------------------------------------------
// Technique: PostProcess
// Desc: Performs post-processing effect that down-filters.
//-----------------------------------------------------------------------------
technique PostProcess
{
pass p0
{
VertexShader = null;
PixelShader = compile ps_2_0 Combine();
ZEnable = false;
}
}


Any ideas? I've tried 2 hours figuring out whats going on, first I had a problem because of differnt texture formats, only know I don't have any ideas..

Share this post


Link to post
Share on other sites
Advertisement
Have you tried debugging your velocity-outputting shader in PIX? It sounds like it's getting identity for the LastWorldViewProj matrix, but PIX would tell you for sure. You may also want to put a break point right on the line where you set that variable on the Effect, and make sure that the member is what you expect it to be.

Share this post


Link to post
Share on other sites
Have you tried debugging your velocity-outputting shader in PIX? [/quote]

Yeah, I tried. Like always, it just keeps crashing my app. I think I'll open a seperate thread for this problem, as it's really annoying not being able to use PIX, for reasons I don't really understand (as already mentioned somewhere else PIX just crahes after a successful call of a function with an unhandled exception in it's output log).

It sounds like it's getting identity for the LastWorldViewProj matrix, but PIX would tell you for sure. You may also want to put a break point right on the line where you set that variable on the Effect, and make sure that the member is what you expect it to be. [/quote]

Using breakpoints, like I already did (this time more intensive), I found out a pattern: two of my 6 loaded meshes would not get any velocity applied at all, my other 4 got velocity based on the relative position to their original position. Quess what: The 4 objects where all based on the same mesh, therefor drawn more times. Additionally, I had a shading-pass, so all meshes would get drawn more then once. However, I didn't think of that before and just stored the world matrices inside of the meshes, rather than my logical objects containing position, rotation and scalation of the meshes. So rendering the meshes more than once would obviously cause wrong results. I changed the storage of the last worldviewprojection-matrix to the objects themselfs, and made a condition whether to update the matrix or not. So now it's working. Thanks both of you for your suggestions!

Btw.

I would try changing this line
m_Effect->Begin(&NumPasses, D3DXFX_DONOTSAVESTATE);

to

m_Effect->Begin(&NumPasses, 0);[/quote]

Is there any real difference? D3DXFX_DONOTSAVESTATE should discard all state changes made in this effect, right? So what do I get from using/not using it?

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!