用于准备纹理的纹理单元

Texture units for preparing textures

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

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

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

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

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

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

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

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

RENDER(在每个刻度上)

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

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

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

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

编辑:解释"make sure that the same texture unit is set during the whole process"的含义:

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

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

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

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