桌面GLSL是否有可能将固定大小的浮点数组作为属性传递给顶点着色器?如果是,怎么样?
我想为角色动画设置每个顶点权重,所以我想在顶点着色器中使用以下内容:
attribute float weights[25];
我如何从我的C ++&中填充属性数组? OpenGL程序?我在另一个question中看到我可以获取数组属性的属性位置,然后只需将索引添加到该位置。有人可以为我的大型数组提供一个例子吗?
感谢。
答案 0 :(得分:16)
让我们从你要求的开始。
几乎没有当前存在的硬件将attribute float weights[25];
编译。着色器可以具有属性数组,而每个数组索引代表 new 属性索引。在目前存在的所有硬件上,属性索引的最大数量是...... 16.你需要25,而只是的权重。
现在,您可以通过记住可以使用vec4
属性来轻松地缓解此问题。因此,您将每四个数组元素存储在一个属性中。你的数组将是attribute vec4 weights[7];
,这是可行的。你的举重逻辑当然必须改变。
即便如此,您似乎也没有考虑到顶点数据实际上意味着什么的后果。每个属性代表顶点数据的一个组成部分。渲染调用的每个顶点将具有相同数量的数据;该数据的内容会有所不同,但不会有多少数据。
为了完成您的建议,网格中的每个顶点都需要25个浮点来描述权重。即使将其存储为规范化的无符号字节,这仍然是至少25个额外字节的数据。好多啊。特别是考虑到浩大大多数顶点,大多数这些值都是0.即使在最坏的情况下,你也可能会看到影响单个顶点的6-7个骨骼。
通常在顶点着色器中完成蒙皮的方法是将影响单个顶点的骨骼数限制为 4 。这样,您就不会使用属性数组;您只需使用vec4
属性作为权重。当然,您现在还需要说明哪个骨骼与哪个骨骼相关联。因此,您有第二个vec4
属性,用于指定该权重的骨骼索引。
这取得了良好的平衡。您只需要占用2个额外属性(就大小而言可以是无符号字节)。对于绝大多数顶点,您甚至都不会注意到,因为大多数顶点仅受1-3个骨骼的影响。少数使用4,少数使用5+。在这些情况下,您只需按比例切断最低权重并重新计算其他权重。
答案 1 :(得分:11)
Nicol Bolas已经给你一个如何重组你的任务的答案。你应该这样做,因为为一个顶点处理25个浮点数,可能通过一些四元数乘法会浪费很多好的GPU处理能力;无论如何,顶点的大部分属性都将转换为接近身份转换。
但是出于学术原因,我将告诉你,如何在每个顶点传递25个浮点数。关键是不使用属性,而是从某个缓冲区(纹理)中获取数据。 GLSL顶点着色器阶段具有内置变量gl_VertexID
,它传递当前处理的顶点的索引。使用最近的OpenGL,您也可以从顶点着色器访问纹理。所以你有一个大小为vertex_count × 25
的纹理来保存这些值。在您的顶点着色器中,您可以使用texelFetch
函数访问它们,即texelFetch(param_buffer, vec2(gl_VertexID, 3));
如果在骨架动画中使用,此系统通常称为纹理蒙皮。然而,它应该谨慎使用,因为它是一个真正的性能猪。但有时你无法避免它,例如在实施面部动画系统时,如果你想准确地模拟人脸,你必须将所有顶点加权到26个肌肉。