具有可选属性的GLSL着色器

时间:2016-01-03 15:17:21

标签: opengl-es glsl opengl-es-3.0

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

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

    现在,为此创建一个übershader可能会或者可能不是一个好主意(我正在尝试),但是我面临的问题是指定了一些属性而一些属性没有(缺少制服,如纹理采样器)未设置是通过打开和关闭采样功能的布尔制服处理的。)

    当一个属性 未分配时,GLSL v 3.00会发生什么情况(例如,这意味着没有glEnableVertexAttribArray,但也没有缓冲区绑定/任何事情)和没有在GLSL程序中用于阅读(例如,我将使用统一boolean来关闭纹理查找,当UV坐标丢失时,尽管我仍然可以插入在顶点和片段着色器之间坐标为 in / out ,如下所示:

    // Vertex shader
    in vec3 vn;
    out vec3 fvn;
    
    [...]
    
    fvn = vn;
    

    ...)?

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

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

    谢谢!

1 个答案:

答案 0 :(得分:5)

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

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

glEnableVertexAttribArray(loc);

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

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

glDisableVertexAttribArray(loc);

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

因此有一个属性"未指定"不是一个问题,因为它从来没有真正指出过。您唯一需要注意的是,如果没有使用glVertexAttribPointer()指定有效数组,则不启用属性数组。最安全的方法是,您拨打glDisableVertexAttribArray()了解您未使用的属性。