GLTF - 关节应该如何在动画期间变换

GLTF - how are joints supposed to be transformed during an animation

我正在尝试使用 gltf 2.0 资产实现骨骼动画。

我目前能够转换骨架并正确渲染模型。当编辑关节的变换(例如旋转)时,模型按预期移动。

问题是,一旦我尝试使用动画采样器输出的变换,骨架就完全错误了。我的测试表明,动画第一个关键帧的变换矩阵与初始姿势中关节的变换相匹配,但实际上它们完全不同!我不太清楚这些变换应该在渲染算法中的什么位置。

我的渲染算法大致是这样的:

render_scene() {
    render_node(root_node, transform::IDENTIY)
}

render_node(node, outer_transform) {
    next_transform = outer_transform * node.transform
        
    if (node.has_skin) {
        update_joint_matrices(next_transform, node.joints)
    }
        
    if (node.has_mesh) {
        // draw calls
    }
        
    for child in node.children {
        render_node(child, next_transform)
    }
}

update_joint_matrices(outer_transform, joints) {
    world_transforms = []
    
    // Parent nodes are always processed before child nodes
    for joint in joints {
        if joint.is_root {
            world_transforms[joint] = outer_transform * joint.transform
        } else {
            world_transforms[joint] = world_transforms[joint.parent] * joint.transform
        }
    }
    
    joint_matrices = []
    
    for joint in 0..world_transforms.len() {
        joint_matrices[joint] = world_transforms[joint] * inverse_bind_matrices[joint]
    }
    
    // send joint matrices to the GPU
}

顶点着色器的相关部分如下所示:

void main() {
    mat4 modelTransform;

    modelTransform =
        (inWeights.x * jointMatrices[int(inJoints.x)]) +
        (inWeights.y * jointMatrices[int(inJoints.y)]) +
        (inWeights.z * jointMatrices[int(inJoints.z)]) +
        (inWeights.w * jointMatrices[int(inJoints.w)]);
    }

    gl_Position = projection * view * modelTransform * vec4(inPos, 1.0);
}

另外,还有一个note in the spec不太明白:

Only the joint transforms are applied to the skinned mesh; the transform of the skinned mesh node MUST be ignored.

好的,我解决了问题。 问题是我没有正确加载四元数。 四元数应解释为原始 XYZW 值。