OpenGL中Sprite渲染的体系结构

时间:2012-07-09 20:11:21

标签: opengl 3d sprite

我有很多精灵要渲染,并希望得到那些推动这方面表现的人的反馈。

所以我按着色器和纹理排序。并且在VBO中具有相同渲染设置的批量精灵以发送到着色器进行渲染。所有正常的东西。我的精灵都是方形的并且都具有相同的基本数据:中心位置(P),方向(O),比例(S),rgb颜色(Col)和全局不透明度(Alpha)。我必须更新CPU代码中的位置和方向,(虽然大约50%的精灵不会在任何给定的帧对之间发生变化)并且缩放,颜色和不透明度几乎从不改变精灵,但实际上从来没有变化。

我不能假设几何着色器(我会支持它们,但在这种情况下问题没有实际意义)。

我应该:

  1. 当我更新精灵位置时,计算CPU上的顶点位置。使顶点着色器成为一个简单的变换步骤。 (更新每帧的数据量明显减少的优点,但CPU必须做很多触发)。

  2. 将POS数据作为附加数据放入VBO中,复制4个顶点,然后将vert位置设置为简单的偏移量(-1,-1; -1,1; 1,1; 1, -1)并在着色器中执行trig(有利于GPU进行更多计算,但每个顶点有5个额外的数据字)。

  3. 哪个更好是不明显的,所以这两种方法都需要进行分析才能看到会发生什么。

  4. 显然我可以做3,但我认为问这个问题是否有用,看看我是否只是缺乏关于应该更快的格式。无论哪种方式,答案都可以帮助其他严重的精灵/粒子实施者。

3 个答案:

答案 0 :(得分:3)

所以我做了(3)和描述。并且,正如克朗米所说,选项2令人信服地获胜。

表现最佳的结构是两个维也纳国际中心:

  1. vec2 float posfloat orientationfloat scale(16字节/顶点)
  2. vec2 float texvec4 ubyte coloruint flags(16字节/顶点)
  3. 当标志编码精灵的角落时,我们右边有0x00000001,底部有0x00000002。这允许代码更新精灵位置以遍历第一个VBO并一次设置四个值,而不需要任何触发或其他逻辑。所有数学都在顶点着色器中进行。

    在我的测试中,如果位置更新的数量与纹理/颜色更新的数量差别不大,则将两个VBO合并为一个会更好。我假设这是因为那时顶点是32字节对齐的。但是在我的应用程序中(我假设大多数人都是这样),位置会更新大多数帧,但其他的东西永远不会,并且有一个较小的缓冲区来推送到显卡似乎获胜。

答案 1 :(得分:2)

根据我对大量粒子的经验,我会使用选项(2.)。也许你可以将偏移量/方向的索引打包到你的数据中(例如,如果到目前为止你没有使用它,你的位置向量的w分量)? 0 =( - 1,-1); 1 =( - 1,1); 2 =(1,1); 3 =(1,-1)。

(正如Ian所建议的那样,我只是将我的评论复制到答案中!)

@Ian:如果我理解你,你说你有一个全局不透明度/ alpha,所以你应该可以使用uniform并使用{{1}的w分量} vec4 color。但是,我怀疑这会有什么不同......

顺便说一下,你提到的几何着色器解决方案不仅要更优雅,而且要快一点。

答案 2 :(得分:1)

我发现带宽改善很少。我假设每个精灵都有4个顶点(6个索引),那么你可以简单地使用gl_VertexID % 4而不是flags

每个顶点属性:

  • vec2 float positionfloat orientationfloat scale - 精灵几何数据(16B)
  • uint flags - 特殊精灵的可选标志(4B)
  • float param - 用于平滑精灵变换的可选参数(4B)

<强>制服:

  • vec2 vertexPosition[4] - 每个角落的相对位置 - 您可以使用它来指定中心
  • vec2 textureCoord[4] - 每个角落的纹理坐标,您还可以使用4*n texcoords作为n精灵状态,可通过标志定义

对于简单的精灵,此设置每个顶点仅使用16B。