I have 2d texture S and want to return 3d texture H, such that pixel H[r,g,b] is equal to number of pixels of color rgb in texture S. Basically histogram of colors in textur
how to count the pixels in fragment shader?
In one pass, possibly - you risk hitting either a GPU timeout exception or a too many commands exception. I recently ran some profiles to see the limit in WebGL: Can one fragment access all texture pixel values in WebGL GLSL? (Not just it's own TexCoord)
Basically you want to use a for loop (or two for loops for x/y) to iterate through each pixel on the texture, this example adds all the color value into one pixel:
void main() {
vec4 color_register = 0.0;
for (float x = 0.0; x < PIXELS_WIDE; x++)
for (float y = 0.0; y < PIXELS_TALL; y++)
color_register += texture2D(tex0, vec2(x / PIXELS_WIDE, y / PIXELS_TALL));
gl_FragColor = color_register;
}
Then if you wanted each pixel to represent the total occurrences of a different color, you would need to render to a surface with C
pixels, where C
is the number of unique colors you want a histogram of. This requires each pixel to be aware of it's color value, which is most simply done by having a texture containing all colors once, sampling from that with the UV (texture coordinate), then iterating all pixels in the actual scene to be histogramed and tallying that color:
void main() {
vec4 this_pixels_unique_color = texture2D(tex_unique_colors, tex_coord);
int occurrences_of_this_unique_color = 0;
for (float x = 0.0; x < SCENE_PIXELS_WIDE; x++)
for (float y = 0.0; y < SCENE_PIXELS_TALL; y++)
color_register += texture2D(tex_scene_to_histogram, vec2(x / SCENE_PIXELS_WIDE, y / SCENE_PIXELS_TALL));
gl_FragColor = vec4(occurrences_of_this_unique_color, occurrences_of_this_unique_color, occurrences_of_this_unique_color, 1);
}
Leaving you with a rendered surface with one pixel for each unique color, where the darkness of each pixel represents the amount of that color in the scene histogramed.