Is there a fast way to the average colors from several framebuffers in WebGL / Javascript?

独自空忆成欢 提交于 2019-12-08 18:17:29

You have two options

  1. Write a fragment shader that runs once per row (per texture) by rendering a quad (1 x textureheight) and runs through all pixels in the row and averages them. Repeat this process on the averaged rows and you will have the average of the entire image. This is called stream reduction
  2. Call glGenerateMipMap on your FBOs and then access the highest level mipmap (get the params of this mipmap by glGetTexLevelParameter). Now you can use either the ReadPixels method on the much-reduced and averaged mip-image or use GLSL and this ought to be much faster.

Off the top of my head

  1. Make 6 fbos.
  2. Make sure each fbo is made with a texture attachment, not a renderbuffer.
  3. Render the 6 scenes to the 6 fbos
  4. For each texture call gl.generateMipmap(...)
  5. Write a shader that takes 6 textures and averages them using texture2D with the bias option. Set the bias to the number of levels in your textures. This is to tell the GPU to use the smallest level.
  6. Render a unit quad with that shader to a 1 pixel fbo (or 1 pixel in your backbuffer).
  7. Call gl.readpixels on that 1 pixel.

I think the shader would look something like this

--fragment shader--

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!