在绘制纹理之前绑定纹理 (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_2D
和 TEXTURE_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.texImage2D
和 gl.texParamteri
像这样查找要使用的纹理
gl.texImage2D = function(bindPoint, .....) {
var texture = gl.textureUnits[gl.activeTextureUnit][bindPoint];
// now do something with texture
换句话说,在WebGL内部有一个全局的纹理单元数组。 gl.activeTexture
和 gl.bindTexture
操作该数组。
gl.texXXX
操纵纹理本身,但它们通过该数组间接引用纹理。
gl.uniform1i(someSamplerLocation, unitNumber)
将着色器的统一设置为查看该纹理单元数组中的特定索引。
我的代码有效,但我想知道为什么!
我有 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_2D
和 TEXTURE_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.texImage2D
和 gl.texParamteri
像这样查找要使用的纹理
gl.texImage2D = function(bindPoint, .....) {
var texture = gl.textureUnits[gl.activeTextureUnit][bindPoint];
// now do something with texture
换句话说,在WebGL内部有一个全局的纹理单元数组。 gl.activeTexture
和 gl.bindTexture
操作该数组。
gl.texXXX
操纵纹理本身,但它们通过该数组间接引用纹理。
gl.uniform1i(someSamplerLocation, unitNumber)
将着色器的统一设置为查看该纹理单元数组中的特定索引。