如何在 webgl2 中使用深度纹理

Posted

技术标签:

【中文标题】如何在 webgl2 中使用深度纹理【英文标题】:How to use a depth texture in webgl2 【发布时间】:2020-03-15 21:51:50 【问题描述】:

当您只需要帧的颜色部分时,您可以将depth存储在渲染缓冲区中。 这对我来说在 webgl1webgl2 上都很好用。

当你还需要使用 depth 部分你不能使用 render buffer 时,你需要将它存储在 texture . 在 webgl1 中,您需要获得一个扩展来支持它。 这在 webgl1 中也适用于我。

    const gl = canvas.getContext('webgl');
    const depthTextureExtension = gl.getExtension('WEBGL_depth_texture');
    if (!depthTextureExtension) 
        alert('Depth textures not supported');
    

webgl2 中应该默认提供此功能。 然而,当我用这个替换上面的代码时:

    const gl = canvas.getContext('webgl2');

我的代码无法呈现,我找不到任何解释原因。

    this.texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);


    this.depth = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, this.depth);
    checkGLErrors(gl); // OK
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
    checkGLErrors(gl); // for webgl2: 1281 INVALID_VALUE
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);


    this.framebuffer = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this.depth, 0);

【问题讨论】:

您可能会发现this article 很有帮助 【参考方案1】:

在 WebGL2 中,DEPTH_COMPONENT 不是有效的内部格式。使用DEPTH_COMPONENT16DEPTH_COMPONENT24DEPTH_COMPONENT32F

例如from here

  const level = 0;
  const internalFormat = gl.DEPTH_COMPONENT24;
  const border = 0;
  const format = gl.DEPTH_COMPONENT;
  const type = gl.UNSIGNED_INT;
  const data = null;
  gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
                targetTextureWidth, targetTextureHeight, border,
                format, type, data);

【讨论】:

我很惊讶看到这一点,因为到目前为止我看到的所有文档都没有提到 webgl2 不支持与 webgl1 相同的所有选项 顺便说一句,我实际上关注了你的很多工作,但我一定跳过了你的一些 webgl2 帖子,所以我花时间浏览了它

以上是关于如何在 webgl2 中使用深度纹理的主要内容,如果未能解决你的问题,请参考以下文章

glDrawElements:绘制的源纹理和目标纹理相同

如何使用OpenGL着色器在平面上绘制没有透视的纹理?

如何提高自定义 OpenGL ES 2.0 深度纹理生成的性能?

THREE.js - 大型int作为Uniform

将 WebGL 2 中的像素读取为浮点值

WebGL2:不完整的帧缓冲区