在绘制纹理之前绑定纹理 (webgl)

bind a texture before draw it (webgl)

我的代码有效,但我想知道为什么!

我有 2 个纹理 :

    uniform sampler2D uSampler0;
    uniform sampler2D uSampler1;


    void main() {
        vec4 color0 = texture2D(uSampler0, vTexCoord);
        vec4 color1 = texture2D(uSampler1, vTexCoord);
        gl_FragColor = color0 * color1;
    }

和我的js代码

    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D,my_texture_ZERO); 
    gl.uniform1i(program.uSampler0,0); 

    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D,my_texture_ONE); 
    gl.uniform1i(program.uSampler1); 

    // uncomment one of the 3, it works.
    // gl.bindTexture(gl.TEXTURE_2D, my_texture_ZERO);
    // gl.bindTexture(gl.TEXTURE_2D, my_texture_ONE);
    // gl.bindTexture(gl.TEXTURE_2D, texture_FOR_PURPOSE_ONLY);

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

在gl.draw之前,我测试了3个绑定, 每一个都有效!

所以,我不了解底层的真实管道。

感谢您的一些解释

它工作正常,因为在提供的代码中,您正在为采样器发送适当的制服。

第一个纹理通过调用 glActiveTexture(GL_TEXTURE0) 设置为单元 0,然后绑定。然后切换到unit1.

那时每个单元中有两个单独的绑定纹理。

最后,这些单元作为采样器的制服传递——这就是如何指示采样器中应该使用哪个纹理:在这种情况下,将对应于 GL_TEXTURE0 单元的 0 传递给第一个制服,并且第二件制服的类比。

可能即使不取消对这些行的注释 - 应该也能正常工作。

此行无效

gl.uniform1i(program.uSampler1); 

您没有将值传递给采样器

WebGL 纹理单元的工作方式是它们在 WebGL 中是全局状态

gl.activeTexture 设置纹理单元所有其他纹理命令的效果。对于每个纹理单元,有 2 个绑定点,TEXTURE_2DTEXTURE_CUBE_MAP.

你可以这样想

gl = {
  activeTextureUnit: 0,
  textureUnits: [
     { TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
     { TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
     { TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
     ...
  ],
};

gl.activeTexture 就是这样做的

gl.activeTexture = function(unit) {
 gl.activeTextureUnit = unit - gl.TEXTURE0;
};

gl.bindTexture 这样做

gl.bindTexture = function(bindPoint, texture) {
  gl.textureUnits[gl.activeTextureUnit][bindPoint] = texture;
};

gl.texImage2Dgl.texParamteri 像这样查找要使用的纹理

gl.texImage2D = function(bindPoint, .....) {
  var texture = gl.textureUnits[gl.activeTextureUnit][bindPoint];
  // now do something with texture

换句话说,在WebGL内部有一个全局的纹理单元数组。 gl.activeTexturegl.bindTexture 操作该数组。

gl.texXXX 操纵纹理本身,但它们通过该数组间接引用纹理。

gl.uniform1i(someSamplerLocation, unitNumber) 将着色器的统一设置为查看该纹理单元数组中的特定索引。