WebGL - 从渲染缓冲区读取像素数据

Posted

技术标签:

【中文标题】WebGL - 从渲染缓冲区读取像素数据【英文标题】:WebGL - reading pixel data from render buffer 【发布时间】:2011-09-04 13:01:01 【问题描述】:

有没有办法从屏幕外的 WebGL 渲染缓冲区或帧缓冲区获取原始像素数据?

我正在使用 WebGL 进行一些图像处理,例如模糊图像,调整颜色等。 我正在使用帧缓冲区以完整图像大小渲染到纹理,然后使用该纹理以较小的大小显示在视口中。我可以获取缓冲区或纹理的像素数据,以便在正常的画布 2d 上下文中使用它吗?还是我坚持将视口更改为完整图像大小并使用 canvas.toDataURL() 抓取数据?

谢谢。

【问题讨论】:

你真的得到答案了吗?您标记的答案看起来并没有真正回答问题。 我想实际答案是否定的,您无法从缓冲区获取像素数据。你必须使用readPixels() 这是我最接近答案的地方,所以我接受了。我应该不接受这个答案吗? 我认为没有必要。除非有人提供更有用的答案,否则brainjam 已经间接回答了您的问题。我只是好奇。 【参考方案1】:

这是一个非常古老的问题,但我最近在 three.js 中寻找过同样的问题。没有直接的方法来渲染到帧缓冲区,但实际上它是通过渲染到纹理(RTT)过程来完成的。我检查了框架源代码并找出以下代码:

renderer.render( rttScene, rttCamera, rttTexture, true );

// ...

var width = rttTexture.width;
var height = rttTexture.height;
var pixels = new Uint8Array(4 * width * height); // be careful - allocate memory only once

// ...

var gl = renderer.context;
var framebuffer = rttTexture.__webglFramebuffer;
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);        
gl.viewport(0, 0, width, height);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

【讨论】:

【参考方案2】:

readPixels() 应该做你想做的事。在http://www.khronos.org/registry/webgl/specs/latest/ 上阅读 WebGL 规范中的更多信息

【讨论】:

谢谢,我会试试的。不幸的是,看起来我仍然需要将画布的大小调整为我想要读取像素的大小。这会在调整大小时导致“闪烁”。也许在屏幕外使用单独的上下文,然后从中读取像素可能会起作用......? 是的,使用单独的屏幕外上下文应该可以工作.. 但我还没有尝试过。此外,您显然可以创建可用于渲染但不显示的辅助帧缓冲区。有关如何创建这样的帧缓冲区并将其内容用作纹理的说明,请参阅learningwebgl.com/blog/?p=1786。希望这会让你继续前进。 我在 webgl 上下文中使用帧缓冲区作为纹理,但是我遇到的问题是从上下文中获取数据以便在我的应用程序的其他地方使用。我已经让单独的屏幕外上下文排序工作了,所以我现在要走这条路。谢谢。【参考方案3】:

是的,您可以读取原始像素数据。在获取 webgl 上下文时将 preserveDrawingBuffer 设置为 true,然后通过 WebGL 使用 readPixels。

var context = canvasElement.getContext("webgl", preserveDrawingBuffer: true
var pixels = new Uint8Array(4 * width * height);
context.readPixels(x, y, width, height, context.RGBA, context.UNSIGNED_BYTE, pixels)

【讨论】:

以上是关于WebGL - 从渲染缓冲区读取像素数据的主要内容,如果未能解决你的问题,请参考以下文章

WebGL - 当我从帧缓冲区读取像素数据时,图标失去透明度

WebGL 帧缓冲区 ClearColor 仅影响 (0,0) 像素

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

readPixels 函数返回未修改的纹理

使用像素缓冲区对象从 gpu 异步读取数据

WebGL中Stencil Buffer的运用以及ThreeJS的实现