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

时间:2016-04-01 07:03:07

标签: 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个绑定, 每个人都有效!

所以,我不明白真正的管道基础。

感谢您的一些解释

2 个答案:

答案 0 :(得分:1)

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

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

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

最后,这些单位作为采样器的制服传递 - 这是如何指示采样器中应该采用哪种纹理:在这种情况下,将对应于GL_TEXTURE0单位的0传递给第一制服并将第二制服的类似物传递给第二制服。

甚至可能没有取消注释这些内容 - 事情应该有效。

答案 1 :(得分:1)

此行无效

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)设置着色器的制服以查看该纹理单元数组中的特定索引。