顶点蒙皮

介绍

Qt Quick 3D 支持顶点蒙皮,用于网格几何体的骨骼动画。

有关骨骼动画的实际演示,请参阅 "简单蒙皮示例"。

在大多数情况下,应用程序开发人员不会手动使用蒙皮 API。正常的工作流程是使用外部内容创建工具定义骨骼和皮肤(有时也称为装配),然后使用Balsam 资产导入工具将资产转换为Qt Quick 3D 的本地格式。

定义骨骼

骨骼动画的基础是Skeleton 。这是模型移动方式的抽象表示,灵感来自脊椎动物的物理骨骼。骨架的 "骨骼 "由Joint 节点的层次结构表示。当然,这些节点并不一定要代表实际的骨骼。

Skeleton {
    id: qmlskeleton
    Joint {
        id: joint0
        index: 0
        skeletonRoot: qmlskeleton
        Joint {
            id: joint1
            index: 1
            skeletonRoot: qmlskeleton
        }
        Joint {
            id: joint2
            index: 2
            skeletonRoot: qmlskeleton
        }

    }
}

将骨骼连接到模型

要将骨架应用到模型,请设置模型的skeleton 属性:

Model {
    skeleton: qmlskeleton
    ...

为了让骨骼产生效果,模型的geometry 需要包含皮肤信息。具体做法是在顶点缓冲区中包含vertex attributes 以及JointSemanticWeightSemantic

JointSemantic 属性决定了骨骼中哪些关节可以影响给定顶点。它使用Joint.index 指定的索引值。由于该属性包含 4 个索引,因此最多有 4 个关节可以影响一个顶点。

WeightSemantic 属性描述了这些关节的影响强度。它包含四个浮点数值,每个数值都决定了赋予JointSemantic 属性中相应位置索引的关节的权重。

例如,在上述骨架中,如果一个顶点具有以下属性

JointSemantic 属性WeightSemantic 属性
QVector4D(2, 0, 0, 0)QVector4D(1.0, 0.0, 0.0, 0.0)

该顶点将 100%受到关节 2 的影响,其移动幅度与该关节相同。JointSemantic 属性中的后三个索引将被忽略,因为相应的权重是0.0

再举一个例子,属性如下

JointSemantic 属性WeightSemantic 属性
QVector4D(1, 2, 0, 0)QVector4D(0.5, 0.25, 0.0, 0.0)

顶点的移动量将是关节 1 移动量的 50%,再加上关节 2 移动量的 25%。

此外,由于骨架是一种抽象表示,因此模型需要指定关节的几何信息。出于性能考虑,不能直接指定这些信息。相反,Model.inverseBindPoses 包含将每个关节移动到初始位置所需的变换矩阵的矩阵。

骨骼动画

骨骼中一个关节的变换将移动与该关节相连的所有顶点。由于 "关节 "继承自Node ,因此只需使用标准的QML animations 就能对骨架进行动画处理。

NumberAnimation {
    target: joint1
    property: "eulerRotation.z"
    duration: 5000
    from: -90
    to: 90
    running: true
}

虽然可以通过嵌套SequentialAnimationParallelAnimationNumberAnimation 来创建复杂的动画,但通常使用时间轴动画来制作带皮肤模型的动画更为方便。

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.