有没有一种快速的方法可以从 WebGL / Javascript 中的几个帧缓冲区中获取平均颜色?

Posted

技术标签:

【中文标题】有没有一种快速的方法可以从 WebGL / Javascript 中的几个帧缓冲区中获取平均颜色?【英文标题】:Is there a fast way to the average colors from several framebuffers in WebGL / Javascript? 【发布时间】:2012-12-13 18:51:03 【问题描述】:

我对 WebGL 主题非常陌生。 我想要做的是计算 6 个不同帧缓冲区的平均颜色,如下图所示。现在我想知道最好的方法是什么? 我试着做

gl.readPixels(0, 0, 256, 256, gl.RGBA, gl.UNSIGNED_BYTE, pixelValues);

但这似乎很慢...... 有没有办法在显卡上发生这种情况?

this is how the FBO is set up - I have this from a tutorial:

...

【问题讨论】:

【参考方案1】:

想不通

    制作 6 个 fbo。 确保每个 fbo 都使用纹理附件,而不是渲染缓冲区。 将 6 个场景渲染到 6 个 fbos 对于每个纹理调用 gl.generateMipmap(...) 编写一个着色器,它采用 6 个纹理并使用带有偏差选项的 texture2D 对它们进行平均。将偏差设置为纹理中的级别数。这是告诉 GPU 使用最小级别。 使用该着色器将单位四边形渲染到 1 像素 fbo(或后缓冲区中的 1 像素)。 对该 1 个像素调用 gl.readpixels。

我认为着色器看起来像这样

--片段着色器--

precision mediump float;

uniform sampler2D u_textures[6];
uniform float u_bias;

void main() 
   // since we know we are rendering only with the last mip
   // then there is only 1 texel.
   vec2 center = vec2(0.5, 0.5);
   vec4 sum = 
     texture2D(u_textures[0], center, u_bias) +
     texture2D(u_textures[1], center, u_bias) +
     texture2D(u_textures[2], center, u_bias) +
     texture2D(u_textures[3], center, u_bias) +
     texture2D(u_textures[4], center, u_bias) +
     texture2D(u_textures[5], center, u_bias);
   gl_FragColor = sum / 6.0;

【讨论】:

您可以做的一个更改是不使用 6 个 FBO - 您可以在不同的纹理单元上设置 6 个纹理并首先将它们平均每个像素,然后对 FBO 进行 1x1 像素四边形渲染。这样,您只需要两个 FBO。【参考方案2】:

你有两个选择

    编写一个片段着色器,通过渲染一个四边形(1 x 纹理高度),每行(每个纹理)运行一次,并遍历行中的所有像素并对它们进行平均。在平均行上重复此过程,您将获得整个图像的平均值。这称为stream reduction 在您的 FBO 上调用 glGenerateMipMap,然后访问***别的 mipmap(通过 glGetTexLevelParameter 获取此 mipmap 的参数)。现在,您可以在大大减少和平均的 mip 图像上使用 ReadPixels 方法,也可以使用 GLSL,这应该会快得多。

【讨论】:

太好了 - 非常感谢。我会调查的。 你能举个例子如何从FBO获取最小的mipmap吗? 你可以简单地调用 glGetTexImage(GL_TEXTURE_2D, , , , pixelValues) (opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml) 这个问题是关于 WebGL 的。 WebGL中没有glGetTexImage和glGetTexLevelParameter。 啊,我的错 - 我想的是 OpenGL 而不是构建 WebGL 的 OpenGL ES。

以上是关于有没有一种快速的方法可以从 WebGL / Javascript 中的几个帧缓冲区中获取平均颜色?的主要内容,如果未能解决你的问题,请参考以下文章

WebGL:有没有一种有效的方法可以只上传图像/画布的一部分作为纹理?

WebGL 中有没有办法快速反转模板缓冲区?

Blender转换成WebGL的4个必要步骤

WebGL浅入浅出,不深入了解一下吗?

《WebGL编程指南》基础篇

WebGL热潮推动BIM快速进入移动互联时代!