渲染在 OpenGL 中使用 Assimp 加载的动画模型时折叠的网格
Posted
技术标签:
【中文标题】渲染在 OpenGL 中使用 Assimp 加载的动画模型时折叠的网格【英文标题】:Collapsed mesh when rendering animated model loaded with Assimp in OpenGL 【发布时间】:2018-09-12 12:25:41 【问题描述】:所以我正在加载和渲染一个动画模型,我可以毫无问题地在其静态位置渲染网格,以及使用调试线绘制动画骨骼。
Here is a short video illustrating the issue.
正如您在视频中看到的那样,我已经正确显示了动画“简笔画”。然而,顶部的网格似乎只是部分正确显示。
如标题所述,我使用的是 Assimp 和 OpenGL。
在我在场景中加载的东西的模型加载端,遍历保持父子旋转的节点,识别是骨骼的节点并将骨骼信息添加到节点。
└───Scene
├───Camera
├───Armature
│ └───Torso : [ ROOT_BONE ]
│ ├───Chest : [ BONE ]
│ │ ├───Neck : [ BONE ]
│ │ │ └───Head : [ BONE ]
│ │ ├───Upper_Arm_L : [ BONE ]
│ │ │ └───Lower_Arm_L : [ BONE ]
│ │ │ └───Hand_L : [ BONE ]
│ │ └───Upper_Arm_R : [ BONE ]
│ │ └───Lower_Arm_R : [ BONE ]
│ │ └───Hand_R : [ BONE ]
│ ├───Upper_Leg_L : [ BONE ]
│ │ └───Lower_Leg_L : [ BONE ]
│ │ └───Foot_L : [ BONE ]
│ └───Upper_Leg_R : [ BONE ]
│ └───Lower_Leg_R : [ BONE ]
│ └───Foot_R : [ BONE ]
└───Character: [ 1 MESH(ES) ]
这是我当前模型节点结构的示意图。 每个节点都有一个变换矩阵,旁边有[ROOT_BONE]/[BONE]的还有一个偏移矩阵。
为了渲染动画骨骼,我读入动画关键帧,根据插值的位置旋转和缩放值为每个“通道”(骨骼)构造矩阵。当我将动画矩阵相乘(基于父层次结构)时,我得到了世界空间中的骨骼/连接位置。(我似乎不需要知道任何节点变换矩阵或骨骼偏移矩阵来得到这个正确渲染。(只需将动画矩阵与其父动画矩阵相乘)
为了渲染网格,我尝试了一些方法,仅使用动画中的矩阵得到的结果与上面显示的视频相似,但是躯干躺在地上调试骨架,手臂/腿仍然显示与视频相同。视频中看到的结果是通过将动画矩阵乘以相应的骨骼来实现的,然后将结果传递给顶点着色器。
uniform mat4 uModelViewProjection;
uniform mat4 uBones[100];
in vec4 aPosition;
in vec4 aWeights;
in ivec4 aBoneIds;
void main(void)
mat4 skinMat =
uBones[aBoneIds[0]] * aWeights[0] +
uBones[aBoneIds[1]] * aWeights[1] +
uBones[aBoneIds[2]] * aWeights[2] +
uBones[aBoneIds[3]] * aWeights[3];
gl_Position = uModelViewProjection * skinMat * aPosition;
这里是顶点着色器的相关代码。我在这里也尝试了几种不同的方法,结果相同(或者在某些情况下更糟)。
我看到奇怪的“折叠”顶点后立即想到的一些事情可能是骨骼矩阵没有正确传递,我确实记录了它们以验证它们确实被发送了,我还检查了着色器统一位置句柄以确保正确找到它们。
我假设我在某处遗漏了一步,或者可能只是以错误的顺序处理某事。我一直在为这个主题编写充满不同“教程”的手,但它们都很难理解。 (代码到处都是,没有最好的文档,我无法运行其中的任何一个,因为所有示例都需要不同的语言/预先存在的框架,或者它只是被破坏了。)
附加信息:
我当前尝试加载的模型是 Collada (.dae) 文件。 我正在为 Assimp 和 OpenGL 使用 LWJGL 绑定。【问题讨论】:
【参考方案1】:我终于找到了问题所在。在 OpenGL 着色器中使用ivec4
(或任何其他以i
为前缀的数据类型)作为属性时,您必须使用glVertexAttribIPointer
而不是glVertexAttribPointer
(注意I
)。如果不指定,缓冲区数据将作为浮点数发送到 GPU。
【讨论】:
啊,谢谢你的提示。我阅读了您的帖子并遇到了一些问题来重现该问题!以上是关于渲染在 OpenGL 中使用 Assimp 加载的动画模型时折叠的网格的主要内容,如果未能解决你的问题,请参考以下文章
使用 ASSIMP 和 OpenGL 加载 3D 模型时纹理不正确
我的OpenGL学习进阶之旅Assimp库支持哪些3D模型格式?