WebGL 从浮点渲染目标读取像素

2024-01-06

有一些混乱e.g. https://www.khronos.org/webgl/public-mailing-list/archives/1210/msg00090.html就支持水平而言渲染WebGL 中的浮点纹理。 OES_texture_float 扩展似乎并没有强制要求它本身,根据对 FLOAT 纹理作为 FBO 附件的可选支持(已弃用) http://www.khronos.org/registry/webgl/extensions/OES_texture_float/,但看起来有些供应商已经开始实施它。因此,我的基本理解是,渲染到浮点纹理实际上可以在非 ES 桌面环境中工作。我没能read直接从浮点渲染目标。

我的问题是是否有一种方法可以使用 WebGLContext::readPixels() 调用和 Float32Array 目标来读取浮点纹理?提前致谢。

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

<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>

不幸的是,将 RGBA 分量读取为字节似乎仍然是 WebGL 的唯一方法。如果需要将浮点数编码为像素值,可以使用以下命令:

在分形着色器(GLSL/HLSL)中:

float shift_right (float v, float amt) { 
    v = floor(v) + 0.5; 
    return floor(v / exp2(amt)); 
}
float shift_left (float v, float amt) { 
    return floor(v * exp2(amt) + 0.5); 
}
float mask_last (float v, float bits) { 
    return mod(v, shift_left(1.0, bits)); 
}
float extract_bits (float num, float from, float to) { 
    from = floor(from + 0.5); to = floor(to + 0.5); 
    return mask_last(shift_right(num, from), to - from); 
}
vec4 encode_float (float val) { 
    if (val == 0.0) return vec4(0, 0, 0, 0); 
    float sign = val > 0.0 ? 0.0 : 1.0; 
    val = abs(val); 
    float exponent = floor(log2(val)); 
    float biased_exponent = exponent + 127.0; 
    float fraction = ((val / exp2(exponent)) - 1.0) * 8388608.0; 
    float t = biased_exponent / 2.0; 
    float last_bit_of_biased_exponent = fract(t) * 2.0; 
    float remaining_bits_of_biased_exponent = floor(t); 
    float byte4 = extract_bits(fraction, 0.0, 8.0) / 255.0; 
    float byte3 = extract_bits(fraction, 8.0, 16.0) / 255.0; 
    float byte2 = (last_bit_of_biased_exponent * 128.0 + extract_bits(fraction, 16.0, 23.0)) / 255.0; 
    float byte1 = (sign * 128.0 + remaining_bits_of_biased_exponent) / 255.0; 
    return vec4(byte4, byte3, byte2, byte1); 
}

 // (the following inside main(){}) return your float as the fragment color
 float myFloat = 420.420;
 gl_FragColor = encode_float(myFloat);

然后回到 JavaScript 端,在进行绘制调用后,您可以使用以下命令提取每个像素的编码浮点值:

var pixels = new Uint8Array(CANVAS.width * CANVAS.height * 4);
gl.readPixels(0, 0, CANVAS.width, CANVAS.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
pixels = new Float32Array(pixels.buffer);

// pixels now contains an array of floats, 1 float for each pixel
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebGL 从浮点渲染目标读取像素 的相关文章

  • 在Three.JS中通过鼠标点击选择Collada对象

    我需要通过鼠标单击在 Three JS 中选择 Collada 对象 我知道我可以根据对象的 id 选择对象 并且我看到了一些用户可以与几何定义的对象交互的示例 here http mrdoob github com three js ex
  • 在 Chrome 中调试 webgl

    我有一个在 chrome 中运行的 webgl 页面 chrome 时不时会报如下错误 WebGLRenderingContext GL 错误 GL INVALID OPERATION glDrawElements 尝试在没有附加到启用属性
  • 使用画布(三.js)覆盖画布(WebGL)

    我有两块画布 第一个应该是背景 其内容通过原始 WebGL 3D 渲染 第二个画布应该覆盖第一个画布 并且主要是透明的 它的内容通过 Three js 3D 内容 呈现 不幸的是 第二个画布不是绘制在第一个画布的上面 而是绘制在它的旁边 如
  • 是否可以使用 WebGL 运行 #version 120 着色器

    我有许多 GLSL 片段着色器 我几乎可以保证它们符合 version 120它们使用标准的 不符合 ES 的值 并且没有任何 ES 特定的编译指示 我真的很想使用 WebGL 为他们制作一个网页预览器 预览器不会在移动设备上使用 这可行吗
  • 如何快速发现复杂场景中某个点是否被遮挡?

    我有一个复杂的 3D 场景 需要根据 3D 坐标在其上显示 HTML 元素 我只是简单地覆盖了一个div标签放在顶部并使用 CSS 定位 但是 当 3D 坐标被模型遮挡时 或者以另一种方式表述 当它在相机中不可见时 时 我还需要部分隐藏它
  • 如何在 GLSL / WebGL 中将 1 个 32 位整数打包为 4 个 8 位整数?

    我正在寻求并行化一些复杂的数学 而 WebGL 看起来是实现这一目标的完美方法 问题是 您只能从纹理中读取 8 位整数 理想情况下 我希望从纹理中获取 32 位数字 我的想法是使用 4 个颜色通道来获得每像素 32 位 而不是 4 乘以 8
  • 用于渲染视频的 2d 上下文与 WebGL

    我目前正在使用CanvasRenderingContext2D drawImage 将来自 RTC 媒体流的视频绘制到画布上 不幸的是 这会占用大量的 CPU 资源 使用以下方法执行此操作会性能更高吗WebGLRenderingContex
  • 将 webGL html 转换为 SVG

    我正在使用 R 以及 Misc3d 和 rpanel 库 在 webGL 中创建 3D 图像 然后我需要通过 Latex 将图像嵌入到 PDF 中 3D 图像渲染良好并且看起来很棒 但我想我需要将 webGL HTML 文件转换为 SVG
  • int gl_VertexID 导致 Three.js 出错

    我一直在使用内置顶点索引的 gl VertexID 时遇到问题 通过使用in 与 Three js 一起使用 我不知道为什么 因为文档说它适用于所有版本的 OpenGL http www opengl org sdk docs mangls
  • 如何在三个js渲染的Canvas中添加canvas的结束标签?

    三个js总是向页面添加没有结束标签的canvas元素 这背后有什么具体原因吗 我想在此画布元素上添加结束标签 Example page http threejs org examples webgl animation cloth insp
  • 如何编写基于网络的音乐可视化工具?

    我正在尝试找到构建音乐可视化工具以在网络浏览器中运行的最佳方法 Unity 是一个选项 但我需要构建一个自定义音频导入 分析插件来获取最终用户的声音输出 Quartz 可以满足我的需要 但只能在 Mac Safari 上运行 WebGL 似
  • 以到最近边缘的距离为函数的着色矩形会在对角线上产生奇怪的结果

    I m trying to color a rectangle in ShaderToy GLSL in function of each pixel s distance to the nearest rectangle edge How
  • 如何在WebGL中实现类似隧道的动画? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如何在WebGL中实现类似隧道的动画
  • 着色器:如何在不生成几何体的情况下绘制 3D 点顶点?

    我有一个 3D Webgl 场景 我正在使用Reglhttp regl party http regl party 这就是WebGL 所以我本质上是直接写 GLSL 这是一个游戏项目 我有一个 3D 位置数组 x y z 它们是子弹或射弹
  • 为什么我不能使用uniform1f而不是uniform4f来设置vec4制服?

    我通过以下方式逐步学习WebGL这本书 https sites google com site webglbook 我尝试通过使用缓冲区来绘制三个点 gl ARRAY BUFFER 而不是循环 正如我之前在本书的其他示例中所做的那样 var
  • 有多少 WebGL 内存可用?当我用完时会发生什么?

    GPU 内存是有限的 通常比 JS 堆大小等更有限 诸如大量高分辨率图像之类的东西可能会填满内存 而且它是共享资源 因此其他应用程序可能会使用大量内存 在 OpenGL 中 我可以查询可用内存 WebGL 有没有办法做同样的事情 我怎样才能
  • 如何添加标签/标签以显示在多个对象的顶部,以便当用户单击对象时标签始终面向相机?

    本质上 我想说的是 我想创建一个出现在对象顶部 表面上的标签或标签 以便当用户单击对象时 即使对象旋转 标签也始终面向相机 我该如何去做呢 我被告知要使用正交相机 但我不确定如何 和 CSS 作为标签 请参阅上一篇文章 如何使我的文本标签始
  • WebGL:Android 上对 OES_texture_float 的支持下降

    有谁知道减少对 WebGL 扩展的支持是怎么回事OES texture float多年来在Android上 https webglstats com webgl extension OES texture float platforms 0
  • 重复凹凸贴图

    我正在尝试使用 Three js r55 将凹凸贴图应用到平面上 以创建一个模糊的感觉表面 这是我的代码 var mapHeight THREE ImageUtils loadTexture images felt png mapHeigh
  • 使用文件 API 将资源加载到 Three.js 中

    我想创建导入 3D 模型以在浏览器中查看的功能 方法是使用File API http www html5rocks com en tutorials file dndfiles Three js 加载器在我托管的文件上运行良好 我的理解是加

随机推荐

  • 如何为 django-taggit 创建列表和详细视图?

    我有一个相当简单的模型 使用 Django Taggit 进行标记 一切都很好 但现在我想扩展一些功能 但我有点困惑 我想要的是两种观点 显示我在系统中的所有标签的一个 显示我的应用程序中带有特定标签的所有内容的一个 对我来说有意义的是对每
  • 在活动目录中查找计算机

    当我使用 dsa msc 手动搜索计算机并打开其属性时 会出现一个 位置 选项卡 它可能有也可能没有价值 当我尝试使用 Net 的目录服务获取此信息时 我没有看到 位置 属性 我打印了所有可用的属性 但没有看到它 它只是不可用还是我错过了一
  • 带有节点的分类视图

    使用 Drupal 6 我尝试创建一个包含如下视图的页面 分类术语 1 包含该术语的节点的标题和描述 包含该术语的节点的标题和描述 分类学术语 2 包含该术语的节点的标题和描述 包含该术语的节点的标题和描述 分类学术语 3 包含该术语的节点
  • 弱阻力和强阻力有什么区别

    我读过一些关于强抗碰撞性和弱抗碰撞性的文章 但我无法理解其中的区别 我唯一能理解的是 具有弱抗碰撞性的哈希函数发生碰撞的概率较低 而具有强抗碰撞性的哈希函数发生碰撞的概率较高 我无法理解什么是真实的东西 这些参数的意义是什么 谁可以帮我这个
  • 按组选择事件首次发生之前的行

    我有一系列的观察结果 描述了是否以及何时在特定区域发现动物 下面的示例表标识了何时看到某种动物 status 1 或不 status 0 白天 id date status 1 1 2014 06 20 1 2 1 2014 06 21 1
  • CMake路径错误

    我正在尝试为 kinect 演示构建 Visual Studio 项目 rgbddemo http nicolas burrus name index php Research KinectRgbDemoV5 根据页面上的说明 我需要设置
  • 如何获得向量中函数的多个输出?

    假设我有一个函数 其输出是两个实数 a 和 b a b function c 我想获得向量 v 中的所有输出 v function c 没有执行我想要的操作 v 只是 a 当然这里我可以做v a b 但所讨论的函数是 N 维数组的 ind2
  • Ionic 1 推送通知

    有人有 ionic 1 推送通知的经验吗 他们建议的云解决方案有其他替代方案吗 有人可以展示实施示例吗 请记住 我对 ionic 完全陌生 我用这个插件https github com phonegap phonegap plugin pu
  • 如何在 asp.net mvc 3 项目中路由 .aspx 页面?

    我在以下路径中有一个 aspx 页面 Areas Management Views Ticket Report aspx 我想将其路由到浏览器中的以下路径 http localhost Reports Tickets 我怎样才能做到这一点
  • MVC 3 模型验证问题 - 疏忽或有意为之

    我遇到了一个场景 我需要知道当前正在验证哪个属性在一个习惯中ValidationAttribute 我认为这在 MVC 3 中会很容易 因为ValidationContext正在被传递到IsValid http msdn microsoft
  • 时间间隔不均匀的组的滚动总和

    这是我的调整之前发布的问题 https stackoverflow com questions 41693081 r calculate number of distinct categories in the specified time
  • 分析 GIL

    有没有办法分析 Python 进程对 GIL 的使用情况 基本上 我想知道GIL 持有时间的百分比是多少 该进程是单线程的 我的动机是我用 Cython 编写了一些代码 它使用nogil 理想情况下 我想在多线程进程中运行它 但为了知道这是
  • Python 数学模块

    每当我尝试使用 Python 的指数和对数模块的任何内置函数时 都会收到如下错误 NameError name sqrt is not defined 我尝试过使用math sqrt 4 sqrt 4 and sqrt 4 0 但它们都不起
  • opencv各列之和

    在 Matlab 中 如果 A 是矩阵 则 sum A 将 A 的列视为向量 返回每列和的行向量 总和 图像 用OpenCV怎么能做到呢 Using cvReduce对我有用 例如 如果您需要将矩阵的按列总和存储为行矩阵 您可以这样做 Cv
  • 带有阅读更多内容的网页视图

    Is it possible to specify the number of lines displayed by a web view and to disable its scrolling and to have a read mo
  • Laravel - DecryptException:“MAC 无效”

    在 Laravel 中进行注册时 我使用密码加密算法而不是 Laravel 中内置的 bcrypt 函数 因为要获取密码并在忘记密码时将其发送到邮件 但解密它显示错误 例如 DecryptException The MAC is inval
  • 如果 postgres 有依赖对象,如何删除用户

    数据库 idd 所有者是角色idd owner 数据库有 2 个数据模式 public and firma1 用户可能对此数据库和对象拥有直接或间接分配的权限 用户不是任何对象的所有者 它只授予了权利 如何删除这样的用户 I tried r
  • 如何在 Firebase 中执行以下查询? (多个where条件)[重复]

    这个问题在这里已经有答案了 考虑以下 firebase 结构 users 00 03 aa dc 1c 2b firstName Ofek groupName thailand lastName Ron registration type
  • numpy数组除以向量列

    我有一个 3x3 numpy 数组 我想用 3x1 向量划分该数组的每一列 我知道如何将每一行除以向量的元素 但无法找到划分每一列的解决方案 您可以转置数组以在每一列上进行划分 arr 3x3 T arr 3x1 T
  • WebGL 从浮点渲染目标读取像素

    有一些混乱e g https www khronos org webgl public mailing list archives 1210 msg00090 html就支持水平而言渲染WebGL 中的浮点纹理 OES texture fl