WebGL 从浮点渲染目标读取像素 [英] WebGL Read pixels from floating point render target

查看:31
本文介绍了WebGL 从浮点渲染目标读取像素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些混乱eg 就在 WebGL 中渲染到浮点纹理的支持级别而言.根据 可选支持 FLOAT 纹理作为 FBO 附件(已弃用),但看起来有些供应商继续实施它.因此我的基本理解是,渲染到浮点纹理实际上适用于非 ES 桌面环境.不过,我无法直接从浮点渲染目标中读取.

There is some confusion e.g. in terms of support levels for rendering to floating point textures in WebGL. The OES_texture_float extension does not seem to mandate it per se, as per Optional support for FLOAT textures as FBO attachments (deprecated), but it looks like some vendors went ahead and implement it. Therefore my basic understanding is that rendering to floating point textures actually works in non-ES desktop environments. I have not been able to read from the floating point render target directly though.

我的问题是是否有办法使用 WebGLContext::readPixels() 调用和 Float32Array 目标读取浮点纹理?提前致谢.

My question is whether there is a way to read from a floating point texture using a WebGLContext::readPixels() call and a Float32Array destination? Thanks in advance.

附加的是一个成功读取字节纹理的脚本,但读取浮点纹理失败:

Attached is a script that succeeds reading from a byte texture, but fails for a float texture:

<html>
<head>
<script>
function run_test(use_float) {
    // Create canvas and context
    var canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    var gl = canvas.getContext("experimental-webgl");

    // Decide on types to user for texture
    var texType, bufferFmt;
    if (use_float) {
        texType = gl.FLOAT;
        bufferFmt = Float32Array;
    } else {
        texType = gl.UNSIGNED_BYTE;
        bufferFmt = Uint8Array;
    }

    // Query extension
    var OES_texture_float = gl.getExtension('OES_texture_float');
    if (!OES_texture_float) {
        throw new Error("No support for OES_texture_float");
    }

    // Clear
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(1.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Create texture
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_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, 512, 512, 0, gl.RGBA, texType, null);

    // Create and attach frame buffer
    var fbo = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
    gl.bindTexture(gl.TEXTURE_2D, null);
    if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
        throw new Error("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
    }

    // Clear
    gl.viewport(0, 0, 512, 512);
    gl.clear(gl.COLOR_BUFFER_BIT);
    var pixels = new bufferFmt(4 * 512 * 512);
    gl.readPixels(0, 0, 512, 512, gl.RGBA, texType, pixels);

    if (pixels[0] !== (use_float ? 1.0 : 255)) {
        throw new Error("pixels[0] === " + pixels[0].toString());
    }
}

function main() {
    run_test(false);
    console.log('Test passed using GL_UNSIGNED_BYTE');
    run_test(true);
    console.log('Test passed using GL_FLOAT');
}
</script>
</head>
<body onload='main()'>
</body>
</html>

推荐答案

readPixels 仅限于 RGBA 格式和 UNSIGNED_BYTE 类型 (WebGL 规范).但是,有一些方法可以将浮点数打包"到此处描述的 RGBA/UNSIGNED_BYTE 中:

The readPixels is limited to the RGBA format and the UNSIGNED_BYTE type (WebGL specification). However there are some methods for "packing" floats into RGBA/UNSIGNED_BYTE described here:

http://concord-consortium.github.io/lab/experiments/webgl-gpgpu/webgl.html

这篇关于WebGL 从浮点渲染目标读取像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆