3 ms·
I think you're referring to bone animation. With bone animation, there are 4 "weights" per vertex. Each weight refers to a specific matrix in a "bone matrix p
by palish 16y ago
I think you're referring to bone animation. With bone animation, there are 4 "weights" per vertex. Each weight refers to a specific matrix in a "bone matrix palette" (array of matrices).
Typically, it's performed as:
// start in local space. Deform by bone matrices.
float3 pos = 0;
for ( int i = 0; i < 4; i++ )
pos += vtx.boneWeight[i] * ( vtx.pos * boneMats[ vtx.boneIdx[i] ] );
// transform from local space to post-projection space.
return modelViewProjMatrix * float4( pos.xyz, 1.0 );
In other words, a model is deformed (animated) first, then transformed into worldspace.
------------------------------------------------------
You may have done this instead:
// transform from local space into world space.
float3 pos = modelMatrix * vtx.pos;
// deform by bone matrices.
for ( int i = 0; i < 4; i++ )
pos += vtx.boneWeight[i] * ( vtx.pos * boneMats[ vtx.boneIdx[i] ] );
// transform from world space into post-projection space.
return viewProjMatrix * float4( pos.xyz, 1.0 );
This will exhibit the quantization errors you mentioned, and is correctable by re-ordering the operations.
- JabavuAdams 15y agoThanks for the detailed answer, but no, it's still a problem. I mentioned animation, but actually it would happen without animation. The problem is subtracting two very large numbers. This happens when you calculate the camera-relative offset of a vert. From the Tom Forsyth article I linked in another reply: > The most obvious place this happens in games is when you're storing world coodinates in standard float32s, and two objects get a decent way from the origin. The first thing you do in rendering is to subtract the camera's position from each object's position, and then send that all the way down the rendering pipeline. The rest all works fine, because everything is relative to the camera, it's that first subtraction that is the problem. For example, getting only six decimal digits of precision, if you're 10km from the origin (London is easily over 20km across), you'll only get about 1cm accuracy. Which doesn't sound that bad in a static screenshot, but as soon as things start moving, you can easily see this horrible jerkiness and quantisation. >By the way, some rendering code doesn't even do that subtraction. Canonically, you bake that subtraction into the offset of your "camera matrix" in your rendering code and let the GPU do it. This is madness - GPUs have even less precision than full IEEE754 floating-point, and you're doing a whole bunch of vector math before you finally do the subtraction. So your precision problems are going to be a lot worse. Best all round if you just subtract camera position from object position on the CPU before it gets anywhere near a GPU.
- palish 15y agoThank you for the equally detailed response. I apologize. Did you fix the problem? I don't know how I'd solve it.
- JabavuAdams 15y agoIn our case, we were doing a port of a PC game to PS2. We were chopping up the PC levels to try and fit them into memory (~16MB). Unfortunately in chopping them up, they were not re-centered. So, even though one of these new smaller levels might not be large, if the whole thing was far from the origin, madness ensued. El-cheapo solution: pre-process the level geometry to centre it again. Not elegant, but expedient.