OpenGL实例化绘图如何处理顶点输入限制

Posted

技术标签:

【中文标题】OpenGL实例化绘图如何处理顶点输入限制【英文标题】:OpenGL instanced drawing how to deal with vertex input limitation 【发布时间】:2014-09-06 22:33:44 【问题描述】:

我想为我的 opengl 引擎实现实例化渲染,但我刚刚了解到,对于我的 GPU,顶点着色器支持的最大输入数仅为 16。

这些是我需要移动到输入的以下矩阵:

uniform mat4 MVP;
uniform mat4 modelMatrix;
uniform mat3 normalMatrix;
uniform mat4 DepthBiasMVP;

如果我理解正确,每个矩阵的每一列都需要一个属性,所以我需要 4+4+3+4 = 15 个属性空间。 19 和我已经使用的属性(pos、color、texCoord、normal),如果我添加切线和其他东西,它会增长到 20+。

有没有办法解决这个问题,还是我必须忘记实例化的绘图?假设我设法摆脱了其中一个矩阵(modelMatrix)并且我有大约 15-16 个属性,它可以在不同的 GPU 上工作吗? 16个限制是所有GPU的最小值吧?

【问题讨论】:

【参考方案1】:

请注意,16 是您的实现实际拥有的最小数量的顶点属性;大多数情况下,您可以通过以下方式查询更多信息:

glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &n).

现在,当您尝试将所有数据存储在实例化数组中时,您应该尝试组织您希望每个实例不同的实际数据。您是否有很多仅位置和/或方向不同的实例化对象?那么您可能需要将您的uniform modelMatrix 设置为实例数组(这需要4 个顶点属性,一个可接受的值)。您真的需要为每个实例使用不同的视图和投影矩阵吗?可能不是。 DepthBiasMVP 也是如此。

如果您执行非均匀缩放,则需要normalMatrix,并且如果您计划为每个实例执行此操作,您还需要为每个实例设置一个normalMatrix。您可以事先在 CPU 上计算它们并将它们作为顶点属性发送,这会花费您另外 4 个顶点属性。另一种选择是在顶点着色器中计算normalMatrix,但这可能会稍微减慢您的顶点着色器(也许是可以接受的权衡?)。

这些应该会将每个实例所需的信息减少到仅modelMatrixnormalMatrix,已经减少了一半。也许每个实例您只有不同的位置?在这种情况下,即使是简单的vec4 也可以。

基本上,试着想想您实际上需要为每个实例更新哪些数据,您很可能会对每个实例实际需要多少数据感到惊讶。

【讨论】:

【参考方案2】:

可以将每个实例的数据存储在统一数组uniform buffer objects 或texture buffer objects 中,并使用GLSL 中的gl_InstanceID 变量来访问缓冲区对象中的数据。统一数组可能看起来最简单,但大小最有限,因此仅适用于少量实例。 UBO 可以更大一些,但也非常有限。另一方面,TBO 将允许您存储数兆字节的数据,但您必须在此处适当地打包数据。在您的情况下,您似乎只需要浮点类型,因此具有 32 位浮点的基本格式就足够了。

【讨论】:

以上是关于OpenGL实例化绘图如何处理顶点输入限制的主要内容,如果未能解决你的问题,请参考以下文章

使用带有移动对象的 OpenGL 实例化绘图

OpenGL实例化数组奇怪的顶点位置

Java 内部是如何处理判断一个对象是不是被实例化的?

如何在 Qt 5 中使用带有实例化的 VAO

如何处理参数化查询中的空用户输入?

使用 OpenGL 3.3 进行实例化似乎很慢