【发布时间】:2022-01-02 12:17:56
【问题描述】:
我正在开发一个未来将支持 3D 的 2D 游戏引擎。在当前的开发阶段,我正在开发批处理渲染器。你们中的一些人可能知道,当将图形批处理在一起时,对颜色 (RGBA)、纹理坐标、纹理 ID(纹理索引)和模型变换矩阵的统一支持超出了窗口,而是通过顶点缓冲区传递。现在,我已经实现了将模型的位置、颜色、纹理坐标和纹理 ID 传递到顶点缓冲区。我的顶点缓冲区格式现在看起来像这样:
float* v0 = {x, y, r, g, b, a, u, v, textureID};
float* v1 = {x, y, r, g, b, a, u, v, textureID};
float* v2 = {x, y, r, g, b, a, u, v, textureID};
float* v3 = {x, y, r, g, b, a, u, v, textureID};
我即将使用变换矩阵集成计算对象在世界空间中的位置。这导致我问这个问题:
转换矩阵应该乘以模型顶点在 CPU 或 GPU 上的位置吗?
要记住的是,如果我将它传递给顶点缓冲区,我将不得不为每个顶点上传一次变换矩阵(每个精灵 4 次),这对我来说似乎是浪费内存。另一方面,将模型顶点位置乘以 CPU 上的变换矩阵似乎比 GPU 的并发能力要慢。
如果我在 GPU 上计算变换,这就是我的顶点缓冲区格式的样子:
float* v0 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v1 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v2 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v3 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
这个问题主要是理论上驱动的。因此,我们将不胜感激理论上和技术上的答案。但作为参考,这里是代码。
【问题讨论】:
-
"将图形批处理在一起时,对颜色(RGBA)、纹理坐标、纹理ID(纹理索引)和模型变换矩阵的统一支持出窗"而是取决于你做了多少批处理。这是个人的选择,而不是神圣的法令。
-
“而是通过顶点缓冲区传递”——不。您可以在下面我的回答中拥有制服数组、SSBO 数组,或者通过纹理传递数据。在极端情况下,您可以在 VAO 中完全不使用任何数据进行渲染。
-
在 99% 的情况下,还有一个 4x4 模型视图矩阵是一种过度杀伤力。除了投影矩阵,您通常不需要任何透视变换。因此,您可以使用 3x4 矩阵将浮点数从 16 降低到 12。您可以进一步将自己限制为仅由四元数 + 向量编码的等距,这仅需要 7 个浮点数并涵盖 80% 的情况。
-
我将继续使用 SSBO。感谢您的所有回答。