OpenGL ES 2.0中的几何实例化


12

我打算在OpenGL ES 2.0中进行几何体实例化。基本上,我打算在场景中渲染相同的几何体(一把椅子)大约1000次。

在OpenGL ES 2.0中执行此操作的最佳方法是什么?

我正在考虑将模型视图mat4作为属性传递。由于属性是每个顶点数据,因此我需要传递相同的mat4,因此对于同一三角形的每个顶点都要传递三遍(因为modelview在三角形的各个顶点之间保持不变)。

这将导致发送到GPU的大量额外数据(2个额外的顶点* 16个浮点*(三角形数)数量的额外数据)。

还是应该每个三角形仅发送一次mat4?但是由于属性定义为“每个顶点”数据,使用属性怎么可能呢?

在OpenGL ES 2.0中进行实例化的最佳和有效方法是什么?


3
我真的很想念glVertexAttribDivisor:(
威尔

Answers:


9

ES2既没有glVertexAttribDivisor也没有浮点纹理,因此您的选择非常有限。

如果您还没有的话,绝对可以将椅子模型放入VBO中。从那里开始,您或多或少地受到单个绘图调用的限制(每把椅子一个),因此这是将每把椅子的转换矩阵尽可能高效地传递到GPU的问题。

您可以通过常规的glUniform调用来做到这一点,或者可以在绘制每把椅子之前滥用一些额外的顶点attrib插槽并进行一些glVertexAttrib(注意:不是glVertexAttribPointer)调用,使用4个此类插槽指定矩阵,并且这些值将“粘贴”为椅子上的每个后续顶点。在某些硬件上,这可能是一条足够快的路径,而在另一些硬件上,则要慢一些,因此您必须进行试验。

如果您的椅子不旋转,您可以做的只是将位置发送到着色器,并在那里动态构建一个新的变换矩阵。这听起来很可怕,但实际上是非常快的(仅设置3个浮点数),就可以完成任务。

总体而言,假设您的目标是一个典型的移动平台,那么我认为无论您做什么,抽奖活动都会杀死您。


6

最好的选择是使用类似于外观模型的实例化方法。创建一个VBO,该VBO将保存您的椅子的许多副本,所有副本都是相同的。现在,每个顶点都必须具有字节属性,该属性将保存要应用于该变换矩阵的索引。将矩阵矩阵发送到着色器,并将其用作每个椅子的世界变换。这样,您可以在每个调用中吸引与array参数的最大大小一样多的椅子,而不必重写VBO中的任何数据。


3

Wolfire Games有一篇关于快速对象实例化的优秀博客文章。他们所做的是多次渲染模型,但是将每个对象的不同矩阵发送到统一的插槽。

这是实例化一整堆对象的一种非常有效的方法,因为您只需发送一次数据(渲染一批对象时最大的瓶颈始终是带宽),然后在着色器中转换模型。


+1无论如何,我仍然不确定引用Nvidia文本是否也适用于移动PVR芯片。特别是关于他们提到的驾驶员部分。http.download.nvidia.com/developer/SDK/Individual_Samples/DEMOS/...
Eonil

1

http://www.youtube.com/watch?v=rfQ8rKGTVlg

这是关于WebGL的Google Talk,它是JavaScript的OpenGL ES,这意味着也没有几何实例化。它可能会给您一个想法,尽管很难说,因为我不知道您的瓶颈在GPU还是CPU上。

虽然,您应该了解统一变量,但绝对不需要在属性中发送mat4,椅子的所有顶点都将由同一矩阵变换,您只需要针对每个模型(而不是每个三角形)发送一次。统一变量使您可以执行此操作,它们是可以在着色器程序本身中设置的特殊类型的变量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.