# Artefacts from different matrix multiplications in HLSL

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

## Recommended Posts

Hello, yeah I know, the title might be a bit extreme, but I really have a strange shader bug;) In my VertexShader I just want to transform the vertex positions of my skydome from object to clipspace, so I did the following:
output.pos = mul( float4(vertexPos, 1.0f), worldViewProj);


It kinda worked, but I got strange artefacts on the skydome (holes). So I changed the code to this:
float4x4 wv = mul(world, view);
float4x4 wvp = mul(wv, proj);
float4 vPos = mul( float4(vertexPos, 1.0f), wvp);
output.pos = vPos;


As you can see basically its the same code - I just decomposed the worldViewProj Matrix into 3 matrices. Again this code doesnt work (same artefacts). Being really desperate I tried the following:
float4 vPos = mul( float4(vertexPos, 1.0f), world);
vPos = mul(vPos, view);
vPos = mul(vPos, proj);
output.pos = vPos;


Again its actually the same (at least I think so!) but with these lines my skydome has no artefacts! WTF? Is there anybody who understands why this code works and the 2 snippets above dont work?? Thanks! [Edited by - jollyjeffers on January 15, 2008 4:26:41 AM]

##### Share on other sites
Some how your matrix multiplications are losing precision, at least that's my best guess. Your first shader snippet only shows usage of worldViewProj. Was that value computed on the cpu and passed into the constants, or was it computed in the shader? The other non-working snippet shows the matrix multiplication happening in the shader. If both are happening in the shader, then for some reason the vertex shader floating point precision is lower than the cpu's. If the matrix used in your first snippet is computed on the cpu, then that does seem a bit odd; maybe the values of your matrices are very extreme, or your matrix multiplication code is somehow not preserving precision correctly? Compiler settings (there are settings for precise, fast, and strict)?

The reason the last one works is because there is apparently less precision loss when multiplying the vector by each matrix separately. I'm not sure I could prove that though.

I'm not sure what the rules are for vertex shader floating point precision, I believe different gpus handle it differently. Nvidia has 32-bit and 16-bit floating point, I believe some ATIs have a 24-bit float type.

##### Share on other sites
Quote:
 yeah I know, the title might be a bit extreme
No, just go for "crap" instead of "extreme". Consider your post edited for the benefit of your fellow community members - the ones you're trying to get the help from [wink]

Quote:
 I got strange artefacts on the skydome (holes).
Any chance of a more detailed analysis? Pictures including any debug output maybe?

Quote:
 float4x4 wv = mul(world, view);float4x4 wvp = mul(wv, proj);float4 vPos = mul( float4(vertexPos, 1.0f), wvp);output.pos = vPos;
Is almost certainly the same shader code. The first two lines will be compiled to a preshader which gives you your third line that is actually executed on the GPU which, conveniently, is identical to the original line that you had problems with [smile]

Cheers,
Jack

##### Share on other sites
Quote:
 Any chance of a more detailed analysis? Pictures including any debug output maybe?
Yes, sure.
If I use snippet 1 or 2 I get this result:
http://img186.imageshack.us/my.php?image=skybuggyfl6.png
The grayish color is my backbuffer clearcolor. If I use the code snippet 3 (the one where I multiply the vertex position with the matrices step by step I get a correct sky). If I move the camera then these grayish "holes" flicker and move around.

Quote:
This is my app code where I set the matrices:
D3DXMATRIX world, view, proj;D3DXVECTOR3 eye = cam->eye;D3DXMatrixTranslation(&world, eye.x, -innerRadius, eye.z);cam->getViewMatrix(&view);cam->getProjMatrix(&proj);D3DXMATRIX worldViewProj = world * view * proj;worldViewProjSC->SetMatrix( (float*)&worldViewProj);worldSC->SetMatrix( (float*)&world);viewSC->SetMatrix( (float*)&view);projSC->SetMatrix( (float*)&proj);
As you can see worldViewProj is really just the composite of the other 3 matrices.
One thing maybe I should mention: my projection matrix (which I get with cam->getProjMatrix) uses a huge value for the clip plane: nearplane = 0.2f and farplane = 6000000.0f.

Since it doesnt work if I compose the 3 matrices to one matrix (either in the app code or in the shader) I guess it really has something to do with precision. But could this really lead to such extreme artefacts? If yes: is there any other workaround to fix this, because the shader code is executed very often and its a waste of performance to execute the muls again and again.

##### Share on other sites
hmm, I don't see anything jumping out at me in the code you've posted.

What happens when you render in wireframe - D3DRS_FILLMODE = D3DFILL_WIREFRAME?? Is everything clustered around those small bits of sky, or does it look more like its being clipped?

Quote:
 One thing maybe I should mention: my projection matrix (which I get with cam->getProjMatrix) uses a huge value for the clip plane: nearplane = 0.2f and farplane = 6000000.0f.
This does jump out at me as being a bad idea. You'll be causing yourself plenty of pain with that sort of ratio, and it could well be hurting you here.

Typically floating point precision problems arise from combining very large and very small numbers - they can handle two very large together or two very small together, just not both extremes!

It's a simple change - make it 1.0 and 100.0 and see if your artifacts go away...

hth
Jack

##### Share on other sites
YES ! Exactly, I´m having the same issues. I´ll explain our situation: We have two planes, very close one from each other (0.01 units of distance). We have tried three different situations:

1.- With the following shader code there´s no problem:

Out.Pos = mul(Position, mMatWorldViewProj);

2.- With this other version, no problem too:

float4 pw = mul(Position, mMatWorld);
pw = mul(pw, mMatView);
Out.Pos = mul(pw, mMatProj);

3.- But with this code, ZBuffer artifacts appear, even at close looks:

float4 pw = mul(Position, mMatWorld);
pw = mul(pw, mMatViewProj);

Matrices and everything are built correctly. And I can tell you more, I have debugged the shader with PIX and I´ve seen that in the three cases, the same EXACT float4 result is produced. Then, if the result is the same, why the different behavior? There´s absolutely no other change in code.

I don´t know if I´m missing something too obvious. It seems to be a numerical precission problem, or just that the "mul" method shows different behaviors in different situations.

Someone can explain this?

My specs:
Pentium IV Quad Core. 3 Gb RAM. nvidia GeForce 8800 GT 512Mb. Windows Vista. Managed DirectX 9.0c. Visual Studio 2008.

Thanks,

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

• 26
• 9
• 11
• 9
• 9
• ### Forum Statistics

• Total Topics
633711
• Total Posts
3013488
×