简体   繁体   中英

WebGL - render depth to fbo texture does not work

For a post processing shader, I need the color and the depth buffer of my framebuffer. Accessing the colorbuffer works fine but I have problems creating the depthbuffer. I always get an INVALID_ENUM error when trying to use texImage2D for the depth texture:

WebGL error INVALID_ENUM in texImage2D(TEXTURE_2D, 0, DEPTH_COMPONENT16, 1536, 502, 0, DEPTH_COMPONENT, UNSIGNED_BYTE, null)

using a renderbuffer instead of a texture works but I want depth in a texture so I can pass it to a shader.

framebuffer with depth texture code:

Framebuffer.prototype.initBufferStuffTexture = function(width, height){
    if(this.width == width && this.height == height){
        return;
    }

    this.width = width;
    this.height = height;

    // remove existing buffers
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    if(this.texture != null){
        gl.deleteTexture(this.texture.glid);
        this.texture = null;
    }
    if(this.renderbuffer != null){
        gl.deleteRenderbuffer(this.renderbuffer);
        this.renderbuffer = null;
    }
    if(this.framebuffer != null){
        gl.deleteFramebuffer(this.framebuffer);
        this.framebuffer = null;
    }

    // create new buffers
    this.framebuffer = gl.createFramebuffer();
    this.texture = new Texture();
    this.texture.glid = gl.createTexture();
    this.depth = new Texture();
    this.depth.glid = gl.createTexture();

    // framebuffer
    gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
    this.framebuffer.width = width;
    this.framebuffer.height = height;

    // colorbuffer
    gl.bindTexture(gl.TEXTURE_2D, this.texture.glid);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.framebuffer.width, this.framebuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

    // depthbuffer
    gl.bindTexture(gl.TEXTURE_2D, this.depth.glid);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.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.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT16, this.framebuffer.width, this.framebuffer.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_BYTE, null);

    // assemble buffers
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.glid, 0);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this.depth.glid, 0);

    this.checkBuffer();

    gl.bindTexture(gl.TEXTURE_2D, null);
    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}

The OpenGL ES 2.0 specification (against which WebGL was specified) doesn't list GL_DEPTH_COMPONENT (or any of its sized versions) as a valid texture internal format, so it seems not to support depth textures and as the WebGL specification doesn't state anywhere that it behaves differently, it also doesn't support depth textures.

But maybe this link is of help, where depth txtures are emulated in WebGL by packing the depth value into a standard rgba texture.

texImage2D(TEXTURE_2D, 0, DEPTH_COMPONENT16, 1536, 502, 0, DEPTH_COMPONENT, UNSIGNED_BYTE, null)

OpenGL ES has always been more restrictive in its pixel transfer parameters than desktop GL. So you have to make sure that your pixel transfer parameters match your internal format, even if you're not actually uploading any data. So try UNSIGNED_SHORT rather than UNSIGNED_BYTE.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM