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

12

在WebGL中,是否有一种方法可以从离屏的渲染缓冲区或帧缓冲区中获取原始像素数据?

我正在使用WebGL进行一些图像处理,例如模糊图像、调整颜色等。我正在使用帧缓冲区以全尺寸渲染到纹理,然后使用该纹理在视口中显示为较小尺寸。我能否获取缓冲区或纹理的像素数据,以便在普通的2D画布上下文中进行操作?或者我只能更改视口至全尺寸,并使用canvas.toDataURL()来获取数据吗?

谢谢。


你实际上得到了这个问题的答案吗?你标记的答案似乎并没有真正回答这个问题。 - Samuel Harmer
我想实际的答案是否定的,你不能从缓冲区获取像素数据。你必须使用readPixels()。那是我得到的最接近的答案,所以我接受了它。我应该取消接受那个答案吗? - Sean Kent
我认为这并不必要。除非有人提供更有用的答案,brainjam已经间接回答了你的问题。我只是好奇。 - Samuel Harmer
3个回答

11

这是一个非常古老的问题,但我最近在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);

5

谢谢,我会尝试的。不过很遗憾,看起来我仍然需要调整画布大小以便读取像素。这会导致画面闪烁。也许可以使用一个单独的离屏上下文,然后从那里读取像素...? - Sean Kent
2
是的,使用单独的离屏上下文应该可以解决问题..但我还没有尝试过。此外,显然您可以创建辅助帧缓冲区以供渲染,但不会显示。请参见http://learningwebgl.com/blog/?p=1786,了解如何创建这样的帧缓冲区,并使用其内容作为纹理。希望这可以帮助您解决问题。 - brainjam
我在WebGL上下文中使用framebuffer作为纹理,但是我遇到的问题是将该数据从上下文中取出以便在我的应用程序中其他地方使用。我已经让单独的离屏上下文有点工作了,所以现在我会继续追求这条路线。谢谢。 - Sean Kent

1

是的,您可以读取原始像素数据。在获取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)

为什么将preserveDrawingBuffer设置为true? - Yeets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接