3

我需要将帧缓冲区的像素读取为浮点值。我的目标是在 CPU 和 GPU 之间快速传输大量粒子并实时处理它们。为此,我将粒子属性存储在浮点纹理中。

每当添加新粒子时,我想从纹理中取回当前粒子数组,添加新粒子属性,然后将其重新放入纹理中(这是我能想到的动态添加粒子并处理它们的唯一方法GPU 方面)。

我正在使用 WebGL 2,因为它支持将像素读回PIXEL_PACK_BUFFER目标。我在 Firefox Nightly 中测试我的代码。有问题的代码如下所示:

// Initialize the WebGLBuffer
this.m_particlePosBuffer = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.m_particlePosBuffer);
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
...
// In the renderloop, bind the buffer and read back the pixels
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.m_particlePosBuffer);
gl.readBuffer(gl.COLOR_ATTACHMENT0); // Framebuffer texture is bound to this attachment
gl.readPixels(0, 0, _texSize, _texSize, gl.RGBA, gl.FLOAT, 0);

我在控制台中收到此错误:

TypeError: Argument 7 of WebGLRenderingContext.readPixels could not be converted to any of: ArrayBufferView, SharedArrayBufferView.

但是查看当前的 WebGL 2 规范,这个函数调用应该是可能的。使用该类型gl.UNSIGNED_BYTE也会返回此错误。当我尝试读取 ArrayBufferView 中的像素时(我想避免这种情况,因为它似乎要慢得多),它适用于 and 的格式/类型组合,gl.RGBAgl.UNSIGNED_BYTE不适Uint8Array()用于and gl.RGBA——这是预期的,因为它已记录在案在 WebGL 规范中。gl.FLOATFloat32Array()

我很感谢有关如何从我的帧缓冲区中获取我的浮点像素值或如何让这个粒子管道运行的任何建议。

4

3 回答 3

0

您拥有的 gl 是 webgl1,而不是 webgl2。尝试:

var gl = document.getElementById("canvas").getContext('webgl2');
于 2021-06-16T09:39:08.173 回答
0

您是否尝试使用此扩展程序?

var ext = gl.getExtension('EXT_color_buffer_float');
于 2017-03-21T12:35:11.413 回答
-1

在 WebGL2 中 glReadPixel 的语法是

void gl.readPixels(x, y, width, height, format, type, ArrayBufferView pixels, GLuint dstOffset);

所以

let data = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels, 0);

https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels

于 2017-08-04T22:08:13.457 回答