为了进行调试,我想渲染蒙皮网格物体的骨架。但是,在glTF中,它们似乎是以非常抽象的方式定义的。就是说,没有像通过线连接的一组顶点那样的“骨架”。换句话说,这没有明确定义:
c++ - 您可以从gltf文件中获取明确的框架吗?-LMLPHP
相反,“骨骼”实际上是节点的集合,这些节点仅指定将相关顶点的位置转换为关节位置的矩阵。
但是,是否可以提取关节的位置?也许通过反转inverseBindmatrix或类似的东西?
TL; DR我有一个gltf模型,我想像在Blender中那样渲染它的骨架。

最佳答案

我确定您不是在这里寻找“多数”或“kinda-sorta”答案,但确实存在一些复杂因素。
我将从基本策略开始:glTF是最后一英里格式,一种GPU就绪格式,旨在以最小的麻烦将数据泵入渲染API。因此,glTF对最终用户客户毫无意义的“艺术家 Assets 交换”类型功能没有任何同情。在这种情况下,我们对这种哲学感到失望:骨头的长度。
骨骼的起源和方向是众所周知的。它们是glTF场景层次结构中的节点(通常是空的),实际上我们只知道当皮肤和关节列表一起出现时,它们就被视为“骨骼”,这些关节表明哪些节点实际上是骨骼。作为glTF节点意味着骨骼与父节点之间具有已知关系,形式为转换矩阵,或更可能是节点上的平移,旋转和缩放参数形式。这为您提供了骨骼的原点和方向。甚至可以将其设置为动画,就像任何glTF节点都可以应用动画一样(但仅在使用TRS时才适用,而不能与矩阵一起使用)。
但是glTF中不需要骨头的长度。为什么不?因为为了快速渲染模型,所以需要骨骼对周围顶点的影响。这是通过JOINTS_0WEIGHTS_0访问器(顶点属性)完成的,因此每个顶点都知道哪些骨骼可以影响它,以及影响多少。骨骼的“长度”是艺术家的有用的可视化参数,但在顶点着色器中不需要使用它来计算皮肤的最终位置。给定的3D应用程序可以使用骨骼长度来帮助计算或设定顶点关节权重,但是一旦计算出这些权重,就可以对其进行手动调整和更改,并且原始骨骼长度没有意义。
inverseBindMatrix本质上保留绑定(bind)姿势。它是骨骼相对于根(而非父级)的原始静止/绑定(bind)位置的倒数。以那个 ARM 骨骼为例,它具有一些非零的+ X位置。但是,当它以自己的静止姿势坐在那里时,它基本上不会对皮肤产生影响,也不应将皮肤从原来的位置拉近+ X。 ARM 骨骼远离模型原点的事实使其想将其他顶点拉得更远,而inverseBindMatrix可以取消该效果。因此,当骨骼处于静止状态(处于绑定(bind)姿势)时,骨骼及其inverseBindMatrix会彼此完美抵消。随着骨骼开始从该姿势移开,它开始施加影响。
物有所值,Blender glTF导入器有些花哨的恶作剧,可以在导入glTF时尽力猜测骨头的长度。但是它也导入原始顶点权重,因此,骨骼长度仅出于艺术家的视觉利益,对皮肤没有影响。

关于c++ - 您可以从gltf文件中获取明确的框架吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64690136/

10-10 09:44