2

我可能在这一切都错了,但是,嘿。

我正在渲染大量的墙段(为了论证,假设为 200)。每个部分都是一个单位高,均匀且笔直,没有对角线。所有方向的变化都是90度的变化。
我将每个都表示为一个四尖三角形风扇,也就是一个四边形。每个顶点都有一个与之关联的三维纹理坐标,例如 0,0,0,0,1,7 或 10,1,129。

这一切都很好,但我不禁认为它可以更好。例如,每个点至少重复两次(每面墙都是连续的线段,并且有一些三和四路交叉点)并且起始角纹理坐标(0,0,X 和 0,1,X)正在为每个纹理编号为 X 的墙壁复制。这可以通过将 O 坐标移动到第三个属性并分别索引 S 和 T 坐标来进一步压缩。

问题是,我似乎无法弄清楚如何做到这一点。VAOs似乎只允许一个索引,并且作为一个整体,每个位置和纹理坐标形成一个独特的雪花,永不重复。(诚​​然,这在某些角落可能不是真的,但这是一个非常边缘的情况)

我想做的事情是可能的,还是我必须坚持我目前使用的(公认很好)方法?

4

2 回答 2

2

这取决于你想做多少工作。

OpenGL 不直接允许您使用多个索引。但是你可以获得同样的效果。

最直接的方法是使用缓冲区纹理访问索引列表(使用 gl_VertexID),然后您可以使用它访问包含您的位置或纹理坐标的第二个缓冲区纹理。基本上,您将手动执行 OpenGL 自动执行的操作。这自然会在每个顶点上变慢,因为属性被设计为可以快速访问。您还失去了一些压缩功能,因为缓冲区纹理不支持那么多格式。

于 2011-11-21T00:58:09.057 回答
2

每个顶点和纹理坐标形成一个独一无二的雪花,永不重复

顶点不仅仅是位置,而是由位置、纹理坐标和所有其他属性形成的整个向量。就是你所说的“雪花”。

而且只有 200 面墙,我不会担心内存消耗。它归结为缓存效率。GPU 使用顶点——这意味着整个位置和其他属性向量——作为缓存键。任何你想做的“优化”都可能会对性能产生负面影响。

但是,如果它们在原始索引列表中相距不太远,那么拥有一些重复的顶点并不会造成太大的伤害。今天,GPU 可以在其缓存中保存大约 30 到 1000 个顶点(即在转换后,即着色器阶段),这取决于提供的顶点属性的数量以及传递到片段着色器阶段的可变变量的数量。因此,如果一个顶点(输入键)已经被缓存,着色器将不会被执行,而是将缓存的结果直接反馈给片段处理。

因此,您真正应该针对的优化是缓存局部性,即以某种方式批量处理,将共享/复制的顶点快速连续发送到 GPU。

于 2011-11-21T07:35:11.107 回答