Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL中动态模型的实例绘制_C++_Opengl_Opengl 3 - Fatal编程技术网

C++ OpenGL中动态模型的实例绘制

C++ OpenGL中动态模型的实例绘制,c++,opengl,opengl-3,C++,Opengl,Opengl 3,我目前正在开发一个框架,允许我方便地渲染更多的动画模型 模型被组织为一个简单的骨骼层次,根是躯干/骨盆,通常: 因此,作为伪代码,我目前正在呈现如下模型: RenderBone(Bone b, Mat4x4 currentTransform){ Mat4x4 pos = currentTransform * b.boneTransform; SetUniform("transformation", pos); Draw(bone.mesh); for each

我目前正在开发一个框架,允许我方便地渲染更多的动画模型

模型被组织为一个简单的骨骼层次,根是躯干/骨盆,通常:

因此,作为伪代码,我目前正在呈现如下模型:

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个draw调用

为了减少这种开销,同时使用同一个模型渲染所有参与者,我考虑切换到实例渲染

然而,我能找到的所有信息和教程都是关于绘制立方体、球体或类似的简单对象的。在任何地方,我都看不到关于如何使用实例化图形渲染模型的简单易懂的信息,其中每个部分(骨骼)都需要为着色器提供不同的变换矩阵

因此,问题是: 使用
glvertexattributedivisor
gl\u InstanceID
I只能指定与实例相关的矩阵,而不能指定骨实矩阵。那么我该如何应用我的骨骼转换呢

我能想到的唯一可行的解决方案是,我可以实例化每个骨骼,而不是实例化整个模型。因此,绘制一种骨骼类型的所有实例,然后绘制另一种骨骼类型,以此类推。 但是我仍然需要相对频繁地使用转换矩阵更新缓冲区,这更像是内务管理代码

那么这是最好的选择吗?或者,更一般地说,有没有更好的不太复杂的渲染方法?
或者,实例化渲染只有在与静态几何体一起使用时才会真正发光吗?

当需要绘制同一模型的数千个副本时,可以使用实例化。通常,使用骨骼的网格不是绘制数千个网格所需的类型

实例化是一种优化,而且并不总是有回报。除非您知道自己需要它(通过分析并查看是否达到性能目标),否则您不应该尝试使用它。即使如此,当它是一个实际的性能改进时,它也可能非常敏感

有时候,这根本没用。但这里有一些一般的经验法则:

  • 除非渲染数千个实例,否则实例化是不值得的
  • 实例不应用于顶点过多或过少的网格。100-1000左右
  • 记住,这些是一般规则,而不是绝对法则。它们也依赖于硬件

    因此,问题是:使用glVertexAttributeDivisor或gl_InstanceID,我只能指定一个与实例相关的矩阵,而不能指定一个骨实矩阵。那么我该如何应用我的骨骼转换呢

    对于你所看到的例子或你所看到的其他人所做的事情,你想得太多了。像程序员一样思考

    gl_InstanceID
    不是“实例相关矩阵”;这是一个索引。如何使用该索引完全取决于您。您看到的大多数示例都使用此索引查找矩阵数组,这些矩阵可能存储在或中。此矩阵是用于渲染的变换。每个索引表示单个实例的转换

    每个实例都有多个矩阵、多个变换。但是每个实例都有相同数量的骨骼(否则就不会进行实例渲染)。假设你有5块骨头

    同样,每个索引都是单个实例的转换。您的案例与标准之间的区别在于每个实例需要多少信息。一般情况下需要一个矩阵;你需要五个。但无论哪种方式,想法都是一样的

    如果当前实例需要骨骼索引3,只需使用以下表达式访问矩阵数组:
    (gl_InstanceID*5)+3
    ,其中5是每个实例的骨骼数


    剩下的就是简单地使用逐顶点属性传递用于变换每个顶点的骨骼索引。

    “尝试减少开销”到此为止。你为什么要减少开销?您是否有来自感兴趣的平台的实际分析数据表明这种开销是一个问题?如果没有,那么你就过早地优化了。@Nicolas,我没有。我知道你不能简单地给OGL调用贴上价格标签,但人们似乎同意减少函数调用的数量是个好主意,是吗?目前我不需要优化任何东西,因为我可以用我的棍棒和石头渲染实现达到1000 FPS。但是,如果有一种渲染方法通常表现良好,那么为什么不从一开始就使用它呢?当我的问题集足够复杂,我实际上可以分析它时,我仍然可以看到问题所在,并在需要时更改实现。“但是如果有一种呈现方法通常表现良好,那么为什么不从一开始就使用它呢?”因为它需要更长的时间来实现,最终可能没有任何价值。它使代码更难调试,使开发花费更长的时间,可能没有实际的可测量的收益。优化永远不应该只是因为你能做到而做的事情。哦,不,减少函数调用的数量并不是先验的更快;这是在您获得性能数据之前不进行优化的另一个原因。感谢您写下您的答案,它为我提供了更多信息。我知道我基本上是为了优化而优化。但我并不是在试图建立一个真正有用的高效引擎,而是要有一个游乐场,在那里我可以进行实验和学习,即使它们并不总是最好的想法。我认为这是一种更好的学习OpenGL并获得乐趣的方法,而不是尝试制作一个游戏,在你真正完成它的罕见情况下,它会让你失望,因为它比你刚开始时脑子里的想法糟糕得多:)@Derek该链接的重要部分是“对于一些