【问题标题】:Reducing duplicate data in vertex buffers减少顶点缓冲区中的重复数据
【发布时间】:2012-11-07 15:43:49
【问题描述】:

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

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

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

有一个 skin 缓冲区,其中包含用于渲染纹理区域的顶点,就好像它位于世界原点 (0,0)

在着色器中,将两个骨骼缓冲区与一个缓动值组合(作为制服传递),然后通过变换皮肤顶点,将部分渲染到正确的位置。

这表现得很好,并且是对我开始的地方的一个很好的改进——我在 GPU 上计算了所有的东西,并且只是传入了 x/y/u/v 坐标,我受到了向 GPU 传输大量数据的限制每一帧。

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

当它与骨骼结合时,每个骨骼顶点被复制 4 次——以匹配皮肤缓冲区。在移动设备上工作,这简直就是一个痛苦,因为我的内存不足,而且有这么多的浪费让我很恼火。

如果只有 1 根骨头,这就是缓冲区的样子。

骨骼缓冲区 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 个属性。

有什么方法可以减少骨骼缓冲区的内存占用吗?我有很多很多帧到一个皮肤缓冲区。

【问题讨论】:

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


    【解决方案1】:

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

    关于你的笔记。要克服 16 个属性的限制,您可以将较小的 vec2 属性组合成 vec4。例如,您可以将bonePosition1bonePosition2 合并为一个vec4

    attribute vec4 bonePosition12;
    

    然后在shader中这样使用:

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

    这可能对性能有一些轻微的影响,但由于此代码在顶点着色器中,与着色器的数学相比,性能下降应该可以忽略不计。我已经使用类似的代码来操纵颜色(在片段着色器中)并且性能还可以。

    【讨论】:

    • 我已经在降低骨骼缓冲区的精度,所以每个顶点实际上只有 12 个字节(xy 为一个整数,缩放为整数,旋转为浮点数)。我不太清楚绑定两个GL_ELEMENT_ARRAY_BUFFERs 是什么意思,我从来没有听说过。这将是两个单独的绘图调用,对吗?或者你是说一个GL_ELEMENT_ARRAY_BUFFER 用于骨骼顶点,一个用于皮肤顶点?那确实可以解决它,但据我所知,这是不可能的。如果是的话,可以给我看看吗?
    • @Sticky 我的意思是 2 GL_ELEMENT_ARRAY_BUFFERs。不幸的是,OpenGL ES 2.0 无法做到这一点。所以我能建议的最好的办法是降低精度,因为我知道结合骨骼和皮肤缓冲区不是一种选择,也不能在你的场景中使用。至少我希望您能解决达到 16 个属性限制的问题。
    • 好的,谢谢你的帮助!我没有提到我在问题中已经完成的精度更改,因为这主要是在寻找一种方法来减少重复的东西的数量。干杯
    猜你喜欢
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多