减少顶点缓冲区中的重复数据

时间:2012-11-07 15:43:50

标签: opengl-es opengl-es-2.0 vbo

我一次使用3个顶点缓冲区(实际上我有很多,但一次只使用3个)。

它们包含在着色器中混合在一起以生成所需输出的信息 - 2D骨架动画。

有两个骨骼缓冲区,其中包含任何给定帧的骨骼位置/旋转/比例。

有一个皮肤缓冲区,其中包含用于渲染纹理区域的顶点,就像它位于世界原点一样,(0,0)。 / p>

在着色器中,两个骨骼缓冲区与缓动值(作为一个整体传递)合并,然后通过变换外观顶点,将部件渲染到正确的位置。

这表现很好,并且在我开始的地方是一个很好的改进 - 我计算了GPU上的所有内容,并且只是传递了x / y / u / v坐标,我被限制为将大量数据流传输到GPU每一帧。

但是,有很多重复的信息。皮肤缓冲区仅包含它所需的内容,每个皮肤部分有4个顶点,每个顶点都是唯一的。

当它与骨骼结合时,每个骨骼顶点重复4次 - 以匹配皮肤缓冲区。在移动设备上工作,这是一个令人痛苦的事情,因为我的记忆力很低,让我觉得浪费太多了。

如果只有一个骨骼,这就是缓冲区的外观。

骨骼缓冲区1

[x1,y1,rot1] [x1,y1,rot1] [x1,y1,rot1] [x1,y1,rot1]

骨骼缓冲区2

[x2,y2,rot2] [x2,y2,rot2] [x2,y2,rot2] [x2,y2,rot2]

皮肤缓冲区

[xA,yA,uA,vA] [xB,yB,uB,vB] [xC,yC,uC,vC] [xD,yD,uD,vD]

我不会发布完整的着色器,因为那里有太多额外的东西(旋转和缩放工作类似):

attribute vec2 bonePosition1; // x1, y1
attribute vec2 bonePosition2; // x2, y2
attribute vec2 skinPosition; // xA (or xB .. ), yA (or yB .. )
uniform float a; // Some value 0..1 depending on time
...
vec2 bonePosition = mix(bonePosition1, bonePosition2, a);
vec2 combinedPosition = skinPosition * bonePosition;

请注意;因为我主要针对iOS(其他人也是,但它是最严格的),我知道我只限于16个属性。

有没有办法缩小骨骼缓冲区的内存占用量?我有很多很多帧到一个皮肤缓冲区。

1 个答案:

答案 0 :(得分:0)

如我所见,您需要为具有数据(GL_ELEMENT_ARRAY_BUFFER)的缓冲区绑定多个索引缓冲区(GL_ARRAY_BUFFER)。如果您能够绑定2个GL_ARRAY_BUFFER缓冲区,则可以绑定单独的GL_ELEMENT_ARRAY_BUFFER。我不知道这是否可以在OpenGL ES中实现。如果这是不可能的,你可以尝试使用整数而不是浮点数来节省内存,但我相信这不适用于骨骼转换/旋转值。

关于你的说明。要克服16个属性限制,您可以将较小的vec2属性合并到vec4中。例如,您可以将bonePosition1bonePosition2合并为一个vec4

attribute vec4 bonePosition12;

然后在着色器中以这种方式使用它:

vec2 bonePosition1 = vec2(bonePosition12.x,bonePosition12.y);
vec2 bonePosition2 = vec2(bonePosition12.z,bonePosition12.w);

这可能会对性能产生轻微影响,但由于此代码位于顶点着色器中,因此与着色器数学相比,性能下降应该可以忽略不计。我使用类似的代码来操作颜色(在片段着色器中),性能还可以。

相关问题