iOS OpenGL ES 2.0 VBO混乱问题

3
我正在尝试在iPhone上渲染大量的纹理四边形。为了提高渲染速度,我创建了一个VBO,在单个绘制调用中渲染我的对象。这似乎很有效,但我对OpenGL还不熟悉,当涉及到为每个四边形提供唯一变换时遇到了问题(最终我希望每个四边形都有自定义比例、位置和旋转)。
经过相当多的谷歌搜索,似乎处理这种情况的标准方法是向顶点着色器传递一个统一的矩阵,并让每个四边形负责渲染自己。但这种方法似乎抵消了VBO的目的,最终需要每个对象进行一次绘制调用。
在我看来,每个对象应该保留自己的模型视图矩阵,使用它来根据需要转换、缩放和旋转对象。但是将单独的矩阵应用于VBO中的对象让我感到困惑。我考虑了两种方法:
  • 将模型视图矩阵作为非统一属性发送到顶点着色器,并在着色器内部应用它。
  • 或在将顶点数据存储在VBO中并发送到GPU之前对其进行转换
但是我发现很难找到有关如何最好处理此问题的信息,这让我相信我正在混淆问题。什么是最好的处理方法?

我认为你没有错过简单的解决方案。你正在考虑的两种方法都是可行的。在你的使用情况下,每个四边形变换有多频繁地改变?你通常会用相同的变换进行多次绘制,只偶尔修改变换吗?还是所有/部分四边形的变换每帧都会改变? - Reto Koradi
变换将会相当频繁地更新。我曾考虑过使用带有静态顶点数据的VBO,并将属性(例如弧度旋转)传递到顶点着色器中 - 在那里我可以生成一个变换矩阵。但我有一种感觉,这可能比在CPU上简单地执行更加昂贵。 - ndg
1
如果你想确保找到最适合你使用情况的最佳解决方案,可能需要尝试几种方法并进行基准测试。根据我们拥有的信息,我认为这并不是一件明确的事情。尽管看起来不太优雅,但在CPU上更新顶点坐标可能比其他方法更好。不幸的是,glMapBufferRange不能在ES 2.0中使用,它可以帮助你避免这种方法中的一个复制。相反,将更多的计算移动到GPU上显然很有吸引力,但你需要找出它是否适用于你的使用情况。 - Reto Koradi
1个回答

1
这是一个“常青”的问题(一个好问题),关于如何优化多个简单几何体的渲染(一个四边形实际上是2个三角形,大多数情况下有6个顶点,除非我们使用条带)。
无论如何,在这种情况下使用VBO与VAO不应该意味着显著的优势,因为要传输到内存缓冲区的数据量相对较小(每个顶点32字节,每个三角形96字节,每个四边形192字节),这对于现今的内存带宽来说不算大的负担(但这取决于你指的是多少个四边形。如果每帧有20,000个四边形,那么这将是一个问题)。
一种可能的方法是通过建立一个新的VAO批处理绘制四边形,并将不同的四边形放置在自己的坐标系中。类似于将四边形的顶点移动到“虚拟”网格原点的正确位置。然后你只需在你的VAO中执行新创建的网格的单次绘制。
这样,你可以在更少的调用中批处理绘制多个对象。
问题在于,如果你的四边形需要“缩放”和“旋转”,而不仅仅是平移,你可以计算CPU实际顶点的位置,但这将在计算能力方面代价太高。
在您传输网格的方式之上,一个简单的建议是使用纹理图集来存储所有四边形的纹理,这样您将需要更少(甚至不需要)的纹理绑定操作,这可能会在渲染操作中产生高昂的成本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接