【问题标题】:Texture units for preparing textures用于准备纹理的纹理单元
【发布时间】:2018-03-11 23:34:41
【问题描述】:

在 WebGL(我相信 OpenGL)中使用纹理的简单过程中,执行以下操作是有意义的:

  1. 使用gl.activeTexture()激活纹理单元
  2. gl.bindTexture()绑定纹理
  3. gl.texParameteri() 和朋友一起设置参数
  4. 使用gl.texImage2D()上传数据
  5. 使用gl.uniform1i()将正确的单位分配给采样器

这也是各种书籍和教程学习该技术所采用的方法。

但是,在更高级的用法中,纹理可能会被重新用于不同的着色器,或者希望在加载和渲染之间进行拆分,在渲染时间之前,步骤 1(分配纹理单元)似乎是不必要的。

纹理单元真的会影响纹理本身的设置吗?

换句话说 - 以下方法可以吗?

PREP(对于每个纹理,在任何渲染调用之前)

  1. 不要激活纹理单元(这里总是默认为 0)
  2. gl.bindTexture()绑定纹理
  3. gl.texParameteri() 和朋友一起设置参数
  4. 使用gl.texImage2D()上传数据

渲染(在每个刻度上)

  1. 使用gl.activeTexture()激活所需的纹理单元
  2. gl.bindTexture()绑定纹理
  3. 使用gl.uniform1i()将正确的单位分配给采样器

【问题讨论】:

标签: webgl


【解决方案1】:

活动纹理单元通常不会对纹理准备过程产生任何影响。您只需要确保在整个过程中设置相同的纹理单元即可。

OpenGL 4.5 Direct State Access API 也可以看到这一点,您根本不需要绑定纹理进行准备。

请注意,您也可以避免在每一帧中设置采样器统一 (gl.uniform1i),除非您使用具有不同纹理单元的相同着色器。在今天的 OpenGL 中,我还建议在着色器中使用 layout (binding = x),而不是从应用程序代码中设置采样器统一。

编辑:解释“确保在整个过程中设置相同的纹理单元”的含义:

选择的纹理单元没有直接影响。但是像texParameteritexImage2D 这样的所有命令都在当前纹理单元上运行。你不应该做的是这样的事情:

gl.activeTexture(X)
gl.bindTexture(T1);
gl.texParameteri(...)

gl.activeTexture(Y);
gl.texImage2D(...);

因为 gl.texImage2D 不再对 T1 纹理进行操作,因为 T1 只绑定到纹理单元 X,而不绑定到纹理单元 Y。基本上,您可以为设置过程选择所需的任何纹理单元 X,但是您不应在两者之间更改纹理单元(无需重新绑定纹理)。

【讨论】:

  • 很好奇为什么这被否决 - 似乎是一个明智的答案?您能否详细说明“在整个过程中设置相同的纹理单元”?例如。如果它没有影响,那么改变它会如何破坏?
  • 这个答案和 WebGL 有什么关系?
  • @gman:在 webgl 中的行为完全相同。 (DSA 段落除外)。代码的区别是 gl.Active... 而不是 glActive... 等等。另请注意,在编写答案时,该问题被标记为 webgl 和 opengl。
  • 除非它不是。这只是令人困惑,因为提出这个问题的人不了解 DSA 或 OpenGL。 WebGL 在着色器中没有layout 设置(WebGL2 有,但支持仍然很低)。此外,这里还有一条非常常见的非正式规则,即这个问题不会同时被 WebGL 和 OpenGL 标记,因为它只会导致混淆,而且它们都是用不同的语言编程的。您会注意到 Nicol 删除了他在几乎每个双重标记问题上的标记
  • @gman:我将代码示例更新为 webgl,如果您认为它使答案更容易理解,我可以删除第二和第三段(如前所述,已添加因为当我回答时,这个问题被标记为 opengl 和 webgl)。我不确定在这种情况下删除标签(不是我或操作员完成的)是否是一件好事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多