Blank texture in webGL

2019-06-14 15:15发布

I have simple quad, and very simple shader (see below). I load image needed for texture, process it, get uniform place in shader program, and send it, the way that has been explained in "learning webgl" examples. I tested everything and used webGL inspector to see the textures I've been using and the problem is that quad is whole black. In fragment shader, the line:

gl_FragColor = texture2D( uSampler, vUV);

actually always sets the fragment color to (0,0,0,1). So it's like "blank" texture, or all-black with alpha equals to 1 texture, which is not the same as image I'm trying to attach.

If anyone encountered similar problem and knows how to fix it, please tell me. It's done in Chrome, with --allow-file-access-from-files flag, html page, js/webgl code and image are local, I even tested it on my server, with no results.

Vertex:

attribute vec3 aVertexPosition;
attribute vec2 aUV;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
varying vec2 vUV;
void main() {
vUV = aUV;
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}

Fragment:

uniform sampler2D uSampler;
varying vec2 vUV;
void main() {
gl_FragColor = texture2D( uSampler, vUV)
}

Texture loading and attaching:

var tex = new CHAOS.Texture().load2D("ch.jpg");
var mat = new CHAOS.Material().fromScript("v1", "f1");
mat.addTexture("uSampler", tex);

loading function:

load2D: function(url) {
    function handleTextureLoaded(image, texture, gl) {
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.generateMipmap(gl.TEXTURE_2D);
        gl.bindTexture(gl.TEXTURE_2D, null);
    }

    var tex, im, gl = CHAOS.__R.context;

    tex = gl.createTexture();
    im = new Image();
    im.src = url;
    im.onload = function() { handleTextureLoaded(im, tex, gl); }


    return tex;
},

and addTexture:

addTexture: function(name, texture) {
    this.maps[name] = texture;
    this.locUnif(name);
}

in render function there's part:

for(var key in mate.maps) {
  gl.activeTexture(gl.TEXTURE0 + tex_count); // some problem with int+string, don't look at it
  gl.bindTexture(gl.TEXTURE_2D, mate.maps[key]);
  gl.uniform1i(shaderProgram.unif[key], tex_count);     
  tex_count++;
}

1条回答
何必那么认真
2楼-- · 2019-06-14 15:32

I declared property .isReady on texture, and put on 'true' in the end of the image's onload callback function. Then in render function I just check if it .isReady and send it to gpu. If animation is running, it will probably be visible in the second or third frame, depending on image size and the time it takes to be loaded. The problem was that I used local variable for buffered arrays, so they would be discarded after first frame was rendered (because I buffer data only once). All fine now.

      •  

If someone encounteres similar problem with blank texture, check if the right values are being sent with gl.uniform1i, check that the binded texture is actual webGL texture object and check how your attributes are going.

查看更多
登录 后发表回答