uniform1i 切换到错误的纹理单元

uniform1i switches to wrong texture unit

我正在尝试将旧的 OpenGL 屏幕保护程序转换为 WebGL。它应该渲染一个莫比乌斯带,上面写着从“00”到“23”的数字,就像模拟钟面上的数字一样。这是原来的样子:

由于我现在不完全记得的原因,条带的纹理分为 4 个单独的文件,名为 hours?.bmp,其中 ? 代表 0..3。因此,我尝试将每个文件加载到不同的纹理单元中,如下所示

    for (const which of [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2, gl.TEXTURE3]) {
      const texture = loadTexture(gl, `${process.env.PUBLIC_URL}/texture/hours${which - gl.TEXTURE0}.bmp`);
      gl.activeTexture(which);
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
    }

并将整个环渲染为 4 个三角形条带(每个三角形条带跨越 180°),在渲染每个部分之前更改采样器:

for (let i = 0; i < 4; i++) {
    gl.uniform1i(uniforms.sampler, i);
    // Render the ith piece.
    // ...
}

然而,出于某种原因,程序没有按预期顺序(0、1、2、3)使用四个纹理,而是使用 TEXTURE1TEXTURE2TEXTURE3 然后再次 TEXTURE3。也许这只是我的一些愚蠢的编码错误,但我已经连续两天盯着代码看,但无法弄清楚。

代码在GitHub and you can see a live version on GitHub Pages

gl.bindTexture 将纹理绑定到活动纹理单元。活动纹理单元是全局状态,可以使用 gl.activeTexture 进行更改。每次调用 gl.activeTexture 时,活动纹理单元都会更改。这会影响对 gl.bindTexture.
的所有后续调用 loadTexture 中的第 2 行是 gl.bindTexture(gl.TEXTURE_2D, texture) 并将纹理绑定到随机设置的纹理单元。
使用loadTexture中的纹理单元0(gl.TEXTURE0)加载纹理。加载纹理后,将它们绑定到特定的纹理单元。或者,您可以将特定的纹理单元传递给 loadTexture 并在加载纹理时使用它。