Archived

This topic is now archived and is closed to further replies.

punkfloyd

Precision Loss in DirectX

Recommended Posts

Here''s a little tidbit about DirectX programming which might save you some stress if your game runs in DirectX and your game universe is big. Well, as you probably know DirectX has several transformation matrices that are used on different stages of the rendering pipeline. First your 3d data gets transformed from the model space into the world space using the World Transform (set with D3DTRANSFORMSTATE_WORLD) Then the data get trsnformed into the camera space using the View Transform (D3DTRANSFORMSTATE_VIEW) And finally the data gets projected/clipped with the help of Projection Transform (D3DTRANSFORMSTATE_PROJECTION) It turns out that Microsoft has cut some corners (surpise!) and there is a significant loss of precision somewhere between the first and the second stages that results in a very annoying "jiggling" of the objects if they are small enough and are far enough from the world origin. In our project the objects can be as far as 100000 units away from the world origin and there the "jiggling" is as big as 0.1-0.5 units, very irritating since the size of the objects is typically just a few units. Fortunately if you do the multiplication of the matrices manually then you can bring the jiggling down to only a 0.001 units or so - barely noticeable at all. All we do is instead of g_d3ddevice->SetTransform(D3DTRANSFORMSTATE_WORLD,&worldMat); g_d3ddevice->SetTransform(D3DTRANSFORMSTATE_VIEW,&cameraMat); we basically write D3DMATRIX totalMat; totalMat = MatrixMultiply(worldMat,cameraMat); g_d3ddevice->SetTransform(D3DTRANSFORMSTATE_WORLD,&identityMat); g_d3ddevice->SetTransform(D3DTRANSFORMSTATE_VIEW,&totalMat); Bingo! All the jiggling is magically gone. Nice. Now I just wish I didn''t waste 3 days tracking this one down..=) OD

Share this post


Link to post
Share on other sites
I realy like it when people bash microsoft with out doing a little thinking first.

Pardon me as I quote from a book:

" In Theory we have infinate precision for scalar values. The decimal value of 1/3 has a string of 3s that never end. When we multiply two scalar values togeather the value we get is exactly the correct one. When we compare two values we know (with infinate percision) whether or not the numbers are equil......

In reality, floating point numbers do NOT have infinate precision. Floats (32bit) and doubles(64bit) can only encode so much percision (around 5 and 15 base 10 places respectivly). They do not multiply nicely. If we multiply an extremly large number by an extremly small number the solution we get is not the solution we expect due to the lack of percision." - Advanced 3d Game Programming With Direct X 7 by Adrian Perez.


So basicly your percision error isn''t due to "microsoft cutting corners" it''s due to the size of the world. There are other solutions to your dilema but I''d suggest buying Cubans book as it can go into more depth than I can here.

Share this post


Link to post
Share on other sites
Is that a direct quote from Adrian Perez? If it is, he either goofed or doesn''t know what he is talking about. In floating point math, multiplication is fine, addition isn''t. Take his statement and replace the word multiply with the word add and his statement would be correct.

For example:

1^200 * 1 = 1^200. Just fine
1^200 + 1 = 1^200. ACK, bad

And, as anyone will tell you, matrix multiplication has a LOT of additions in it.

Tim


Share this post


Link to post
Share on other sites