what’s the result if render a texture to a 1x1 size framebuffer?
get the average color if set linear? or other result?
Thanks!
Bilinear filtering uses 4 texels. So if you render a textured quad so as to fill a 1×1 framebuffer, you’ll get the average of the 4 centre texels if the texture width and height are both even. If they’re both odd, you’ll get the value of the centre texel. This assumes that the texture doesn’t have mipmaps.
If you want to average the entire texture, you could use glGenerateMipmap then read out the value of the sole texel in the 1×1 level. But it would probably be more efficient to use a compute shader, as glGenerateMipmap has to store all of the intermediate levels.
Thanks! but why only the 4 or 1 texel center is used? if so, when a 512x512 size texture render to 256x256 framebuffer, only the center 256x256 subregion in the texture was used and the result is only show the center part of the texture?i think this is not the fact, right?
i know glGenerateMipmap and compute shader can do this. But is there any other good method to get the 1 average color of a texture, eg. in fragmentshader?
Because that’s how bilinear filtering works. Note that if the texture has mipmaps (and you’re using a minification filter which uses mipmaps), rendering to a 1×1 framebuffer will use the 1×1 mipmap.
No. Each pixel will use a distinct 2×2 texel block.
Thanks! no mipmaps here.
so now consider reduce size of framebuffer to 4x4, 2x2, even 1x1, the content in framebuffer is still the whole texture, right? so when 1x1 the result is similar to bilinear filter the whole texture, right?
Each output pixel will use a 2×2 texel block. That’s how bilinear filtering works. So rendering to a framebuffer with a single pixel will use a single 2×2 texel block. If you’re rendering a quad which covers the entire framebuffer and whose texture coordinates are the corners of the texture, the 2×2 texel block in the centre wil be used (but if one or both of the texture dimensions are odd, one or two texels will have weight 1 and the other texels will have weight 0, so only one or two of the four texels actually affects the result, even if all four are read).
The more pixels in the framebuffer, the more 2×2 texel blocks will be used. If the size of the framebuffer is less than half the size of the texture in each dimension, some texels won’t be used by any output pixel. This is why mipmaps are needed to avoid aliasing. Each texel in a mipmap level is obtained by averaging multiple texels from the original image, so a 2×2 texel block can contain information from many more texels from the original texture.
Thanks a lot!
so if cannot use glGenerateMipmap and computeShader, only use fragmentShader, is there any fast way to get 1 color similar to average color.
A fragment shader can do almost anything a compute shader can do; it just needs to have a framebuffer bound and be invoked via a rendering operation. You don’t need to actually use the framebuffer; you can output the result to a SSBO.
You’ll want to render a primitive which covers multiple pixels to take advantage of the GPU’s parallelism.
thanks, but not quite understand this. here just want to quickly calculate 1 average color of 1 texture using fragmentShader
You could sum by rendering points (one for each texel) with additive alpha blending into a 1x1 floating-point texture. If you normalize the fragment colors by texture size then you will end up with the mean.
There is no “quick” way to do that. You’re talking about thousands of values being involved. That’s not going to be fast, and it’s unlikely that anything you code would be able to beat repeated blitting or glGenerateMipmaps.
what’s this mean? Would you please give an example? Thanks
Thanks! How about just want a result similar to the precise average color
How “similar” do you want it to be? How much error are you willing to tolerate in the result?
This isn’t something you can ask as a hypothetical. You have some needs (graphical fidelity, performance, etc), and we don’t know what they are. There’s no one-size-fits-all solution; you’re going to have to actually make a decision yourself based on what you’re willing to tolerate and what your profiling data says.
Do you know this method
? How to do this additive alpha blending into 1x1 floating point texture?
Moreover, is there anyway to gen Mipmap directly to 1x1?