如何将顶点与顶点着色器外的模型矩阵相乘

Posted

技术标签:

【中文标题】如何将顶点与顶点着色器外的模型矩阵相乘【英文标题】:How to multiply vertices with model matrix outside the vertex shader 【发布时间】:2015-10-15 13:41:56 【问题描述】:

我正在使用 OpenGL ES2 来渲染相当多的大部分 2d 项目,到目前为止,我已经通过将预乘模型/视图/投影矩阵作为统一发送到顶点着色器然后将我的顶点与结果相乘来摆脱困境MVP 在那里。

所有项目都使用纹理图集进行批处理,我每批使用一个 MVP。所以我所有的顶点都与那个 MVP 的平移有关。

现在我想对每个单独的项目进行旋转和缩放,这意味着我需要为每个项目使用不同的模型。所以我修改了我的顶点以包含模型(16 个浮点数!)并在我的着色器中添加了一个 mat4 属性,这一切都很好。但我对这个解决方案有点失望,因为它显着增加了顶点大小。

所以当我盯着屏幕试图想出一个不同的解决方案时,我考虑在将顶点发送到着色器之前将它们转换为世界空间。如果可能的话,甚至可以屏蔽空间。我使用的顶点是以像素为单位的非标准化坐标。

所以问题是,这样的事情可能吗?如果是的话,你怎么做?我想不出为什么它不应该是因为它只是数学但是在谷歌上搜索了相当长的时间之后,看起来很多人实际上并没有这样做......

奇怪的原因,如果确实有可能,在这种情况下,这将是一个相当大的优化。

【问题讨论】:

【参考方案1】:

如果每批次的矩阵数量有限,那么您可以将所有这些矩阵作为统一(最好在 UBO 中)传递,并使用指定您需要使用哪个矩阵的索引来扩展顶点数据。

这类似于用于skeletal animation 的 GPU 蒙皮。

【讨论】:

您仍然可以在常规制服中传递多个矩阵。您将被限制在您可以通过的数量上。 非常感谢 rachet。我见过人们这样做的代码,但我真的想知道哪种解决方案实际上更有效。将矩阵作为属性或统一数组传递?还是其他我没找到的??我尝试了属性解决方案,看起来还不错。我只是担心顶点大小,因为我可能也必须添加照明。明天我会试试你的建议,看看效果如何。您会建议使用 glDrawElementsInstanced 还是以其他方式传递索引?顺便说一句,目标板是nvidia k1。 哦,批量大小介于 50-5000 个顶点之间。虽然通常它实际上大约有 500-1000 个顶点。甚至更少。

以上是关于如何将顶点与顶点着色器外的模型矩阵相乘的主要内容,如果未能解决你的问题,请参考以下文章

如何在 OpenGL ES 2.0 中将视图/模型/投影矩阵传递给我的顶点着色器?

OpenGL 3.0 窗口碰撞检测

如何将模型矩阵包含到 VBO?

为啥 GPU 外的顶点变换与 GPU 内的顶点变换不同?

GLSL索引绘图并设置纹理案例

OPENGL矩阵顺序与调用顺序相反