我为我们的小型游戏引擎编写了fbx转换器。我坚持使用动画渲染模型。每个时间戳记的矩阵看起来都很好,当我仅渲染骨骼时,它也看起来像原始的动画。我做了一些快照来显示我的问题。我只是不知道怎么了。也许有人可以给我一个提示:)
我用于测试的文件是FBX-SDK中的humanoid.fbx。
着色器应该没问题:
VS_OUT output = (VS_OUT)0;
float4x4 skinTransform = 0;
skinTransform += MatrixPallette[input.BoneIndices.x] * input.Weights.x;
skinTransform += MatrixPallette[input.BoneIndices.y] * input.Weights.y;
skinTransform += MatrixPallette[input.BoneIndices.z] * input.Weights.z;
skinTransform += MatrixPallette[input.BoneIndices.w] * input.Weights.w;
//skinTransform = mul(BindShape, skinTransform);
//Transform Position
float4 worldPosition = mul(input.Position, skinTransform);
float4 viewPosition = mul(worldPosition, matView);
output.Position = mul(viewPosition, matProj);
这是图片。 (右->原始)
http://www.pic-upload.de/view-13949399/Unbenannt.png.html
最佳答案
建议不要使用提供的变换来计算变换后的顶点,然后再使用权重获得组合位置,而不是计算顶点的“蒙皮变换”。插值两个矩阵确实不是一个好主意。
float4 worldPosition = 0;
worldPosition += mul(input.Position, MatrixPallette[input.boneIndicies.x]) * input.Weights.x;
worldPosition += mul(input.Position, MatrixPallette[input.boneIndicies.y]) * input.Weights.y;
worldPosition += mul(input.Position, MatrixPallette[input.boneIndicies.z]) * input.Weights.z;
worldPosition += mul(input.Position, MatrixPallette[input.boneIndicies.w]) * input.Weights.w;
但是,当您看到这种变形的对象时,通常意味着您忘记将矩阵调色板乘以“逆骨变换”。逆骨骼变换是骨骼具有“皮肤游行”姿势(即已绑定(bind)对象的原始姿势)的变换矩阵。要计算蒙皮对象的正确位置,应在矩阵调色板中存储组合的transform =
inverse(skinParadeTransform)*currentTransform
。当前变换是骨骼在当前动画层次结构中具有的变换,而skinParadeTransform是“皮肤游行”模式下的原始骨骼变形。 inverse
是矩阵求逆(是的,您必须这样做)。关于c++ - FBX的骨骼动画,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10353110/