2016-04-01 31 views
0

我的代码有效,但我想知道为什么!在绘制之前绑定纹理(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个绑定, 每一件作品!

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

感谢一些解释

回答

0

它的正常工作,因为在提交代码要发送的采样适当的制服。

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

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

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

可能即使没有取消注释这些行 - 事情应该工作。

+0

好的,但它不工作,如果我做一个:'gl.bindTexture(gl.TEXTURE_2D,null)',那么绑定之前画的立场? –

+0

绑定代表在活动单元中设置纹理。您之前通过调用glActiveTexture(GL_TEXTURE0)激活了单位0; 。正如你所猜测的 - GL_TEXTURE0表示0单位。之后,您通过调用glBindTexture来绑定纹理。如果你用null(或0是明确的)调用glBindTexture,你将从单元中移除纹理。另外请记住,您可以切换活动单位,但通过切换活动单位,您不会丢弃先前活动单位中的更改,因此纹理将停留在那里。 – spectre

+0

Okk ...并且如果在进行绑定之前没有显式活动单元,则默认情况下该绑定处理单元0。 –

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

+0

太好了,我打算用它作为“参考卡”! –