2

我正在尝试创建一个 übershader 来表示一些可能包含或不包含某些属性的波前数据,例如:

  1. 一个或多个对象可能包含uv坐标和纹理
  2. 一个或多个对象可能包含每个顶点的法线映射
  3. 一种或多种材质可能会使用不同的照明类型进行渲染,并包含用于凹凸贴图的纹理

等等。

现在,为此创建一个 übershader 可能是也可能不是一个好主意(我正在试验),但我面临的问题是某些属性已指定而有些则没有(缺少制服,例如未设置的纹理采样器是使用打开和关闭采样功能的布尔统一处理)。

在 GLSL v 3.00 中,当一个属性 没有被分配(这意味着 no glEnableVertexAttribArray,例如,但也没有缓冲区绑定/任何东西)并且没有在 GLSL 程序中用于读取(例如,我将使用制服boolean转纹理查找关闭,当 UV 坐标丢失时,虽然我可能仍然在顶点和片段着色器之间插入坐标作为输入/输出,如下所示:

// Vertex shader
in vec3 vn;
out vec3 fvn;

[...]

fvn = vn;

...)?

这是对 glsl 的合法使用,还是会遇到奇怪的兼容性问题(我正在为移动设备开发,正如 OpenGL ES3.0 标签所暗示的那样)?

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

谢谢!

4

1 回答 1

8

始终指定属性。您可以选择是从数组中获取它们,还是使用当前值。

要使用数组中的数据,请调用:

glEnableVertexAttribArray(loc);

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

要使用当前属性值,请调用:

glDisableVertexAttribArray(loc);

当属性数组被禁用时,用于属性的值由最后一次调用给出glVertexAttrib4f(),或者来自同glVertexAttrib*()一族的另一个函数,如果你从不调用这些函数中的任何一个,则默认值为 (0.0, 0.0, 0.0, 1.0) .

所以有一个“未指定”的属性不是问题,因为它从来没有真正未指定。唯一需要注意的是,如果没有指定有效数组,则不能启用属性数组glVertexAttribPointer()。最安全的方法是调用glDisableVertexAttribArray()不使用的属性。

于 2016-01-03T18:31:08.373 回答