我正在尝试创建一个 übershader 来表示一些可能包含或不包含某些属性的波前数据,例如:
- 一个或多个对象可能包含
uv
坐标和纹理 - 一个或多个对象可能包含每个顶点的法线映射
- 一种或多种 Material 可能会使用不同的照明类型进行渲染,并包含用于凹凸贴图的纹理
等等。
现在,为此创建一个 übershader 可能是一个好主意,也可能不是一个好主意(我正在试验),但我面临的问题是某些属性已指定,有些则未指定(缺少制服,如纹理采样器未设置的使用打开和关闭采样功能的 bool 统一处理)。
当属性both 未分配(例如,这意味着没有glEnableVertexAttribArray
,但也没有缓冲区绑定(bind)/任何东西)并且没有在 GLSL 程序中用于读取(例如,当缺少 UV 坐标时,我将使用统一的 boolean
来关闭纹理查找,虽然我可能仍会在顶点和片段着色器之间将坐标插入为 in/out,如下所示:
// Vertex shader
in vec3 vn;
out vec3 fvn;
[...]
fvn = vn;
...)?
这是对 glsl 的合法使用,还是会遇到奇怪的兼容性问题(我正在为移动设备开发,正如 OpenGL ES3.0 标签所暗示的那样)?
我正在寻找第一手经验或权威来源,
谢谢!
最佳答案
属性总是被指定的。您可以选择是从数组中获取它们,还是使用当前值。
要使用数组中的数据,请调用:
glEnableVertexAttribArray(loc);
启用属性数组时,会从上次调用 glVertexAttribPointer()
时绑定(bind)为 GL_ARRAY_BUFFER
的缓冲区获取属性。
要使用当前的属性值,你调用:
glDisableVertexAttribArray(loc);
当属性数组被禁用时,用于属性的值由最后一次调用 glVertexAttrib4f()
给出,或者来自同一 glVertexAttrib*() 的另一个函数
family,如果您从不调用任何这些函数,则默认值为 (0.0, 0.0, 0.0, 1.0)。
因此,“未指定”属性不是问题,因为它从未真正未指定。唯一需要注意的是,如果没有使用 glVertexAttribPointer()
指定有效数组,则不能启用属性数组。最安全的方法是为不使用的属性调用 glDisableVertexAttribArray()
。
关于opengl-es - 具有可选属性的 GLSL 着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34578074/