如何访问WebGL上下文之外的深度缓冲区的值?

问题描述 投票:1回答:1

给定一个WebGL场景(从THREE.js创建),如果使用DEPTH_ATTACHMENT将framebuffer绑定到纹理,你将如何从framebufferTexture2D访问浮点值(作为WebGL上下文之外的数据数组)。

到目前为止,我已经收集了一个解决方案,即使用自定义着色器覆盖将场景渲染到纹理目标,该覆盖访问深度纹理信息,然后将其编码为RGB格式。使用的代码与此处的THREE.js示例非常相似:Depth-Texture-Example

#include <packing>

varying vec2 vUv;
uniform sampler2D tDiffuse;
uniform sampler2D tDepth;
uniform float cameraNear;
uniform float cameraFar;

float readDepth (sampler2D depthSampler, vec2 coord) {
    float fragCoordZ = texture2D(depthSampler, coord).x;
    float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
    return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
}

void main() {
    vec3 diffuse = texture2D(tDiffuse, vUv).rgb;
    float depth = readDepth(tDepth, vUv);
    gl_FragColor.rgb = vec3(depth);
    gl_FragColor.a = 1.0;
}

一旦渲染完毕,我就可以使用readPixels将特定像素读入数组。但是,这个选项具有令人难以置信的低精度,仅限于给定vec3(float) = vec3(float, float, float)的256个离散值。有没有办法从这种特定的方法或替代方法中获得更高的精度?

最终我想要的是以高效的方式访问深度缓冲区作为WebGL上下文之外的浮点值数组。我有一个自定义光栅化器,可以创建一个相当好的深度缓冲区,但我不想浪费任何时间重做已经完成的步骤。

javascript webgl depth-buffer webgl2
1个回答
2
投票

一种可能性是将32位IEEE 754浮点值的24个有效位编码为vec3

vec3 PackDepth(float depth)
{
    float depthVal = depth * (256.0*256.0*256.0 - 1.0) / (256.0*256.0*256.0);
    vec4 encode    = fract(depthVal * vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0));
    return encode.xyz - encode.yzw / 256.0 + 1.0/512.0;
}

RGB颜色通道可以解码到范围[0.0,1.0]的深度,如下所示:

depth = (R*256.0*256.0 + G*256.0 + B) / (256.0*256.0*256.0 - 1.0);
© www.soinside.com 2019 - 2024. All rights reserved.