简体   繁体   English

WebGL - 渲染深度到fbo纹理不起作用

[英]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. 访问colorbuffer工作正常,但我在创建deepbuffer时遇到问题。 I always get an INVALID_ENUM error when trying to use texImage2D for the depth texture: 尝试将texImage2D用于深度纹理时,我总是会收到INVALID_ENUM错误:

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. OpenGL ES 2.0规范(针对其指定了WebGL)未将GL_DEPTH_COMPONENT (或其任何大小的版本)列为有效的纹理内部格式,因此它似乎不支持深度纹理,因为WebGL规范并未在任何地方声明它表现不同,它也不支持深度纹理。

But maybe this link is of help, where depth txtures are emulated in WebGL by packing the depth value into a standard rgba texture. 但也许这个链接有帮助,通过将深度值打包到标准的rgba纹理中,在WebGL中模拟深度txtures。

texImage2D(TEXTURE_2D, 0, DEPTH_COMPONENT16, 1536, 502, 0, DEPTH_COMPONENT, UNSIGNED_BYTE, null) 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. OpenGL ES的像素传输参数一直比桌面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. 所以尝试UNSIGNED_SHORT而不是UNSIGNED_BYTE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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