【发布时间】:2012-08-15 16:03:40
【问题描述】:
我目前正在开发一个框架,可以方便地渲染大量动画模型。
一个模型被组织成一个简单的骨骼层次结构,根是躯干/骨盆,通常:
所以,作为伪代码,我目前正在渲染这样的模型:
RenderBone(Bone b, Mat4x4 currentTransform){
Mat4x4 pos = currentTransform * b.boneTransform;
SetUniform("transformation", pos);
Draw(bone.mesh);
for each Bone bc in b.children do{
RenderBone(bc, pos);
}
}
因此,对于使用具有 n 个骨骼的模型的单个演员,我需要 n 个 SetUniform(不包括设置纹理之类的东西)和 n 个绘制调用。
为了减少开销,并一次使用相同的模型渲染所有演员,我考虑切换到实例渲染。
但是,我能找到的所有信息和教程都是关于绘制立方体、球体或类似的简单对象的。我无法在任何地方看到一些关于如何使用实例绘图来渲染模型的简单易懂的信息,其中每个部分(骨骼)都需要为着色器提供不同的转换矩阵。
所以,问题:
使用glVertexAttribDivisor 或gl_InstanceID 我只能指定实例相关矩阵,而不是骨骼相关矩阵。那我该如何应用我的骨骼变换呢?
我能想到的唯一可行的解决方案是 - 我可以实例化每个骨骼,而不是实例化整个模型。从而绘制一种骨骼类型的所有实例,然后绘制另一种,等等。 但是我仍然需要相对频繁地使用转换矩阵更新缓冲区,而且它是更多的家务代码。
那么这是最好的选择吗?或者,更一般地说,是否有更好的不太复杂的渲染方式? 还是实例化渲染只有在与静态几何体一起使用时才真正发挥作用?
【问题讨论】:
-
"试图减少开销" 停在那里。你为什么要减少开销?您是否有来自感兴趣平台的实际分析数据表明这种开销特别是是一个问题?如果不是,那么您过早地进行了优化。
-
@NicolBolas 我没有。我知道你不能简单地在 OGL 调用上贴上价格标签,但人们似乎同意减少函数调用的数量是个好主意,是吗?目前我不需要优化任何东西,因为我可以通过我的棒和石头渲染实现达到 1000 FPS。但是,如果有一种渲染方式通常表现良好,那么为什么不从一开始就使用它呢?当我的问题集足够复杂以至于我实际上可以对其进行分析时,我仍然可以看到问题所在并在需要时更改实现。
-
"但是,如果有一种渲染方式通常表现良好,那么为什么不从它开始呢?" 因为它需要更长的时间来实现,而且可能不会最终的任何价值。它使代码更难调试并使开发时间更长,可能没有实际可衡量的收益。优化永远不应该仅仅因为你可以就去做。哦,不,减少函数调用的数量并不是先验更快;这是在获得性能数据之前不进行优化的另一个原因。
-
感谢您写下您的答案,它为我提供了更多启示。我知道我基本上是为了优化而优化。但我并不是要构建一个高效的引擎以供实际使用,而是要有一个游乐场,让我可以在其中进行实验和学习,即使它们并不总是最好的想法。我认为这是学习 OpenGL 并从中获得乐趣的更好方法,而不是尝试制作一个游戏——在极少数情况下你真正完成它——让你失望,因为它比你在你的刚开始时的头:)
-
@Derek 该链接的重要部分是“对于某些 OpenGL 实现”,这意味着某些(也许是大多数)实现不会等待屏幕刷新率。这意味着您可以在每个显示的帧中多次交换。