5
votes

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?

1
Shouldn't be possible. Can you put up your client side code (textures, shaders, binding, etc), to make sure there's nothing incorrect going on there?Tim
What platform are you seeing this on? Chrome ANGLE/OpenGL, FF, Win, Mac etc.? And are you sure your color texture isn't bound to a render target?MikaelEmtinger

1 Answers

8
votes

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.