Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebGL GLSL Shader: accessing texture2D overrides other texture

I have a very disturbing problem with glsl in WebGL.

This shader works as expected:

uniform sampler2D tColor;
uniform sampler2D tNormal;
varying vec2 vUv;

void main() {
    gl_FragColor = texture2D( tColor, vUv );
}

But this one behaves total different:

uniform sampler2D tColor;
uniform sampler2D tNormal;
varying vec2 vUv;

void main() {
    vec4 test = texture2D( tNormal, vUv );
    gl_FragColor = texture2D( tColor, vUv );
}

By accessing the tNormal texture, the tColor texture is overridden. How is this possible?

like image 598
Torsten Avatar asked May 14 '12 20:05

Torsten


1 Answers

I have seen similar behavior in the past, and it's almost always because I'm binding my textures improperly. The most recent incident was caused when I attempted to bind my textures like so:

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
gl.uniform1i(colorUniform, gl.TEXTURE0);

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, normalTexture);
gl.uniform1i(normalUniform, gl.TEXTURE1);

When the correct syntax is actually:

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
gl.uniform1i(colorUniform, 0); // 0 to indicate texture unit 0!

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, normalTexture);
gl.uniform1i(normalUniform, 1); // 1 to indicate texture unit 1!

This is a fairly common mistake, and unfortunately WebGL doesn't actually throw an error on the first code snippet (a subject of recent discussion in the WebGL mailing list) and it can appear to work in limited cases, so it's easy to mistakenly think that it's valid code.

I don't know if this is your specific problem, but it's probably the best advice I can provide without further details.

like image 126
Toji Avatar answered Oct 14 '22 14:10

Toji