Подтвердить что ты не робот

WebGL - глубина рендеринга текстуры fbo не работает

Для шейдера пост-обработки мне нужен цвет и буфер глубины моего фреймбуфера. Доступ к colorbuffer отлично работает, но у меня возникают проблемы с созданием буфера глубины. Я всегда получаю ошибку INVALID_ENUM при попытке использовать texImage2D для текстуры глубины:

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

использование renderbuffer вместо текстуры работает, но я хочу глубину в текстуре, чтобы передать ее в шейдер.

фреймбуфер с текстурой глубины:

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);
}
4b9b3361

Ответ 1

Спецификация OpenGL ES 2.0 (в отношении которой была указана WebGL) не отображает GL_DEPTH_COMPONENT (или любую из ее размерных версий) как допустимый внутренний формат текстуры, поэтому, похоже, не поддерживает текстуры глубины и как спецификацию WebGL не указывает нигде, что он ведет себя по-другому, он также не поддерживает текстуры глубины.

Но, возможно, эта ссылка помогает, где глубинные дуги эмулируются в WebGL, упаковывая значение глубины в стандартную текстуру rgba.

Ответ 2

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

OpenGL ES всегда был более ограничительным по своим параметрам передачи пикселей, чем рабочий стол GL. Поэтому вы должны убедиться, что параметры переноса пикселей соответствуют вашему внутреннему формату, даже если вы фактически не загружаете какие-либо данные. Поэтому попробуйте UNSIGNED_SHORT, а не UNSIGNED_BYTE.