1

我对 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:

...
4

2 回答 2

2

在我的头顶

  1. 做6个fbo。
  2. 确保每个 fbo 都使用纹理附件,而不是渲染缓冲区。
  3. 将 6 个场景渲染到 6 个 fbo
  4. 对于每个纹理调用 gl.generateMipmap(...)
  5. 编写一个着色器,它采用 6 个纹理并使用带有偏差选项的 texture2D 对它们进行平均。将偏差设置为纹理中的级别数。这是告诉 GPU 使用最小级别。
  6. 使用该着色器将单位四边形渲染到 1 像素 fbo(或后缓冲区中的 1 像素)。
  7. 在该 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;
}
于 2012-12-14T07:32:18.237 回答
1

你有两个选择

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