GLSL着色器与可选属性

4
我正在试图创建一个übershader来表示一些波前数据,可能包含有/没有某些属性,例如:
1. 一个或多个对象可能包含`uv`坐标和纹理 2. 一个或多个对象可能包含每个顶点的法线映射 3. 一个或多个材质可能以不同的照明类型呈现,并包含用于凹凸映射的纹理
等等。
现在,为此创建übershader可能是个好主意也可能不是(我正在进行实验),但我面临的问题是,有些属性已经被指定了,有些则没有(缺少uniforms,如未设置的纹理采样器会使用布尔uniforms来打开和关闭采样特性)。
当GLSL v3.00中的属性既未分配(这意味着没有glEnableVertexAttribArray,例如,但也没有绑定缓冲区/任何内容),又没有在GLSL程序中用于读取时会发生什么(例如,当UV坐标丢失时,我将使用一个uniform布尔量来关闭纹理查找,尽管我仍然可能像这样在顶点和片段着色器之间插值坐标:)。
// Vertex shader
in vec3 vn;
out vec3 fvn;

[...]

fvn = vn;

这是否是GLSL的合法使用,还是会遇到奇怪的兼容性问题(因为OpenGL ES3.0标签意味着我正在开发移动应用)?

我正在寻找第一手经验或权威来源,

谢谢!


1
“both not specified and not used”是什么意思?特别是“not specified”是指什么? - Nicol Bolas
@NicolBolas 感谢你的评论(我的解释不够清楚)!我会立即纠正问题,尽管我认为 Reto 给出的答案已经解决了我的问题。 - Rick77
1个回答

10

属性总是被指定的。您可以选择从数组中获取它们,或使用当前值。

要使用数组中的数据,您需要调用:

glEnableVertexAttribArray(loc);

当启用属性数组时,属性将从最后一次调用glVertexAttribPointer()时绑定为GL_ARRAY_BUFFER的缓冲区中获取。

要使用当前属性值,您可以调用:

glDisableVertexAttribArray(loc);

当属性数组被禁用时,属性的值由最后一次调用glVertexAttrib4f()或同一glVertexAttrib*()系列函数中的另一个函数给出,如果您从未调用这些函数,则默认值为(0.0, 0.0, 0.0, 1.0)。

因此,“未指定”属性并不是一个问题,因为它从来没有真正未指定。唯一需要注意的是,在没有使用glVertexAttribPointer()指定有效数组的情况下,不要启用属性数组。最安全的方法是对您未使用的属性调用glDisableVertexAttribArray()


非常感谢您清晰而详尽的解释:那正是我在寻找的!特别是glVertexAttrib*上的“fallback”,这正是我正在寻找的,这是一个很好的东西。 - Rick77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接