OpenGL ES顶点着色器中的动态大小阵列;用于混合形状/变形目标

Dynamically sized arrays in OpenGL ES vertex shader; used for blend shapes/morph targets

本文关键字:混合 用于 阵列 目标 变形 顶点 ES 动态 OpenGL      更新时间:2023-10-16

我即将对混合形状/变形目标进行Opengl ES实现,但我不太确定实现这一点的最佳方法。我面临的问题是,我希望在GPU上进行顶点数据的插值,但我也希望混合形状的数量是任意的。

为了澄清,我不希望我的顶点着色器看起来像这样:OpenGL(C++)中的闪光面部变形目标动画。此实现的问题在于,要在其间混合的网格数在着色器中是静态的。我将处理多个网格,这些网格具有不同数量的混合形状,如果可能的话,我不想为每个网格创建单独的着色器。为大约有20个混合形状的网格创建硬编码着色器也会看起来很难看。

所以我想用某种动态数组来保存所有的数据。但是,我不确定是否可以在顶点着色器中分配动态大小的数组?在具有阵列输入的"顶点"着色器中,op的大小设置为常量。我唯一能考虑创建数组的方法是使用一个统一的变量来保持大小,但我猜这不会编译,因为数组不能分配未知变量。

因此,我试图找到一种很好的方法来存储我的数据(混合形状、权重、顶点、法线的数量),并在运行时在顶点着色器中访问它们,这样我就可以在GPU上有效地进行插值。

关于如何做到这一点,有什么想法吗?

编辑忘记提及它的OpenGL ES

您正在寻找的是Shader Storage Buffer Objects(SSBO),它们基本上可以让您准确地执行您想要执行的操作。

不过,需要注意的是:它们只在GL4.x级硬件上可用,特别是4.3+。这一问题每年都越来越小,但如果计算机的GPU使用年限超过5年,它可能就无法工作

如果您使用OpenGL ES,您仍然(可能)拥有只需要OpenGL 3.x硬件的统一缓冲区对象。它们比SSBO要有限得多(规格只能保证65kb的数据,即使是现代硬件通常也不会提供超过65kb的空间),但它更有可能与您的硬件兼容。

在绝对最坏的情况下,还可以使用纹理作为缓冲区,将任意数据写入其中,然后在着色器上重新解释数据。它非常黑客,但它将绕过UBO的空间限制,并且可能在几乎任何级别都与您的硬件兼容。