2012-01-28 83 views
9

桌面GLSL是否有可能将固定大小的浮点数组作为属性传递给顶点着色器?如果是,如何?GLSL每顶点固定大小的阵列

我想每个顶点的权重人物动画有,所以我想有这样的事情在我的顶点着色器中的以下内容:

attribute float weights[25]; 

我将如何填补属性阵列从我的C++ &的OpenGL程序?我在另一个question中看到,我可以获取数组属性的属性位置,然后将该索引添加到该位置。有人可以举一个例子来说明我的漂亮阵列吗?

谢谢。

回答

16

让我们先从您的要求开始。

几乎没有硬件,目前存在将attribute float weights[25];编译。虽然着色器可以具有属性数组,但每个数组索引都表示一个新的属性索引。并且在当前存在的所有硬件上,属性索引的最大数量是... 16.您需要25,而这是只是的权重。

现在,您可以通过记住您可以使用vec4属性轻松地减轻这一点。因此,您将每四个数组元素存储在一个属性中。你的阵列将是attribute vec4 weights[7];这是可行的。当然,你的体重获取逻辑将不得不改变。

即便如此,你似乎没有考虑到这对于你的顶点数据实际上的意思是的影响。每个属性表示顶点数据的一个组件。渲染调用的每个顶点将具有相同数量的数据;该数据的内容将有所不同,但不是多少数据。

为了做到你所建议,每个顶点在你的网将需要25辆彩车描述的重量。即使这是作为标准化的无符号字节存储的,那么至少仍有25个额外字节的数据值。好多啊。特别是考虑到大多数顶点的巨大的,这些值中的大部分将是0.即使在最坏的情况下,你也会看到可能影响单个顶点的6-7个骨骼。

剥皮在顶点着色器通常做的方式是限制影响单个顶点骨骼数量。这样,你不使用一组属性;您只需使用vec4属性作为权重。当然,你现在也需要说哪个骨骼与哪个重量相关联。因此,您有第二个vec4属性指定该重量的骨骼索引。

这很好的平衡。您只需占用2个额外的属性(可以是大小无符号的字节)。对绝大多数顶点而言,你永远都不会注意到,因为大多数顶点只受1-3个骨骼的影响。少数使用4,少数仍使用5+。在这些情况下,您只需切断最低权重并按比例重新计算其他权重。

+2

非常感谢。你回答了我所有的问题,甚至更多!我希望这会大大提高性能!再次感谢。 – Nicholas 2012-01-28 10:08:15

11

尼科尔布拉斯已经给了你一个答案如何重组你的任务。你应该这样做,因为处理25个浮点的顶点,可能通过一些四元数乘法会浪费很多GPU的处理能力;无论如何,顶点的大部分属性都将转化为身份转换。

然而,由于学术的原因,我要告诉你,如何通过每个顶点25浮点数。关键不在于使用属性,而是从某个缓冲区(纹理)中获取数据。 GLSL顶点着色器阶段具有内建变量gl_VertexID,其传递当前处理的顶点的索引。使用最近的OpenGL,您也可以从顶点着色器访问纹理。所以你有一个尺寸为vertex_count × 25的纹理。在你的顶点着色器,你可以访问它们使用texelFetch功能,即texelFetch(param_buffer, vec2(gl_VertexID, 3));

如果在骨骼动画中使用该系统通常被称为质感蒙皮。但它应该谨慎使用,因为它是一个真正的表演猪。但有时你无法避免它,例如在实现面部动画系统时,如果要准确地模拟人脸,必须将所有顶点的重量减轻到26块肌肉。

+0

非常有趣!我将在未来的工作中牢记这一点。 – Nicholas 2012-01-28 10:06:18