2

简而言之

我想从 JavaScript 中的 WebGL 2 深度纹理中读取单个像素值。这是可能吗?

情景

我在 WebGL 2 中渲染一个场景。渲染器被赋予了一个深度纹理,它将深度缓冲区写入其中。这个深度纹理用于后期处理着色器等,所以我们可以使用它。

但是,我需要在 JavaScript 中读取我的单个像素值,而不是从着色器中读取。如果这是一个正常的 RGB 纹理,我会做

function readPixel(x, y, texture, outputBuffer) {
    const frameBuffer = gl.createFramebuffer();
    gl.bindFramebuffer( gl.FRAMEBUFFER, frameBuffer );
    gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0 );
    gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, outputBuffer);
}

这会将像素x, y写入outputBuffer.

但是,是否有可能对深度纹理做同样的事情?如果我只是将深度纹理传递给上面的函数,则输出缓冲区只有零,并且我会收到 WebGL 警告GL_INVALID_FRAMEBUFFER_OPERATION: Framebuffer is incomplete.。检查帧缓冲区状态显示FRAMEBUFFER_INCOMPLETE_ATTACHMENT

自然,深度纹理不是RGBA纹理,但是我们可以给它一些其他的值来得到我们的深度值,还是不可能?

动机

我知道这个问题已经在 StackOverflow 和其他地方以另一种形式被问过很多次,但总是有一些变化让我很困惑,无法直接回答中的问题是或否表格我在这里问。此外,许多问题和资料来源都非常古老,仅适用于 WebGL 1,还提到了一些关于有所作为webgl_depth_texture等的内容。

如果答案是否定的,我欢迎任何有关如何轻松获得此深度像素的建议。由于并非对每一帧都进行此操作,因此我重视简单性而不是性能。用例是采摘,经典的射线相交是不可行的。(我也知道我可以将标量深度值编码进和出 RGB 像素,但我首先需要能够从 js 代码中访问像素。)

我欢迎任何见解。

4

1 回答 1

1

WebGL 2.0不可能基于OpenGL ES 3.0
OpenGL ES 3.2 Specification - 4.3.2 Reading Pixels中明确规定:

[...] 第二种是从表 3.2 中定义的格式中选择的一种格式,不包括格式 DEPTH_COMPONENT 和 DEPTH_STENCIL [...]

于 2021-05-26T17:50:03.377 回答