opengl - OpenGL 中 Sprite 渲染的架构

标签 opengl 3d sprite

我有很多 Sprite 要渲染,并希望从插入该领域性能的人们那里获得任何反馈。

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

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

我是不是该:

  • 当我更新 Sprite 位置时,计算 CPU 上的顶点位置。使顶点着色器成为一个简单的变换步骤。 (优点是每帧更新数据量明显减少,但CPU必须做很多trig)。
  • 将 POS 数据作为附加数据放入 VBO,为 4 个顶点复制,然后使顶点位置只是简单的偏移量 (-1,-1; -1,1; 1,1; 1,-1) 并执行在着色器中触发(优点是 GPU 进行了更多计算,但每个顶点有 5 个额外的数据字)。
  • 哪个更好并不明显,因此两种方法都需要进行分析以了解会发生什么。

  • 显然我可以做 3,但我认为提出这个问题来看看我是否只是缺乏关于什么应该更快的格式塔会很有用。无论哪种方式,答案都可以在以后帮助其他认真的 Sprite /粒子实现者。

    最佳答案

    所以我做了(3)并进行了分析。而且,正如 kronemi 所说,选项 2 令人信服地获胜。

    表现最好的结构是两个 VBO:

  • vec2 float pos , float orientation , float scale (16 字节/顶点)
  • vec2 float tex , vec4 ubyte color , uint flags (16 字节/顶点)

  • 标志编码 Sprite 的角的地方,所以我们有 0x00000001 代表右边,0x00000002 代表底部。这允许代码更新 Sprite 位置以遍历第一个 VBO 并一次设置四个值,而无需任何触发或其他逻辑。所有的数学运算都发生在顶点着色器中。

    在我的测试中,如果位置更新的数量与纹理/颜色更新的数量没有太大区别,则将两个 VBO 合并为一个效果会更好。我认为这是因为顶点是 32 字节对齐的。但是在我的应用程序中(我假设大多数人的),位置更新了大多数帧,但其他事情从来没有,并且有一个较小的缓冲区来向下推到图形卡似乎获胜。

    关于opengl - OpenGL 中 Sprite 渲染的架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11402348/

    相关文章:

    css sprites - 悬停图像未正确加载

    c - 我怎样才能从矩阵中得到角度

    c++ - 如何将opengl进程绑定(bind)到具体的gpu卡上?

    c# - .NET 3D,从哪里开始?

    java - Android OpenGL ES - 我无法使 gluLookAt/gluPerspective 工作

    css - CSS Sprite 按钮结束在表格内掉落

    java - LIBGDX 不渲染由类创建的 Sprite

    c - openGL glDrawPixels

    c++ - 如何减少图像/纹理中的 "flickering"薄元素?

    opengl:将原点更改为左上角