【问题标题】:GLSL shader with optional attributes具有可选属性的 GLSL 着色器
【发布时间】:2016-01-04 03:50:40
【问题描述】:

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

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

等等。

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

当一个属性both 未分配(例如,这意味着没有glEnableVertexAttribArray,但也没有缓冲区绑定/任何东西)时,GLSL v 3.00 中会发生什么) 并且 没有在 GLSL 程序中用于读取(例如,当 UV 坐标丢失时,我将使用统一的 boolean 来关闭纹理查找,尽管我可能仍会将坐标插值为 in/out 在顶点和片段着色器之间,像这样:

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

[...]

fvn = vn;

...)?

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

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

谢谢!

【问题讨论】:

  • “既未指定又未使用”是什么意思?具体由“未指定”?
  • @NicolBolas 谢谢你的评论(我的解释不清楚)!我会立即更正这个问题,即使我认为 Reto 的回答解决了我的问题。

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


【解决方案1】:

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

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

glEnableVertexAttribArray(loc);

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

要使用当前的属性值,你调用:

glDisableVertexAttribArray(loc);

当属性数组被禁用时,用于属性的值由上次调用 glVertexAttrib4f() 或来自同一 glVertexAttrib*() 系列的另一个函数给出,默认值为 (0.0, 0.0, 0.0, 1.0 ) 如果您从不调用任何这些函数。

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

【讨论】:

  • 非常感谢您提供非常清晰和详尽的解释:这正是我想要的! glVertexAttrib* 上的“后备”特别是我一直在寻找的东西,很高兴知道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
相关资源
最近更新 更多