I'm looking for a shader CG or HLSL, that can count number of red pixels or any other colors that I want.
Asked
Active
Viewed 3,106 times
3
-
Downvoters, please explain your hate. @ragia, this might help http://stackoverflow.com/questions/23091370/count-pixels-by-color-in-webgl-fragment-shader – yoyo Mar 31 '15 at 04:55
-
I wish I know why they downvote ! – ragia Mar 31 '15 at 13:59
-
Downvotes are part of StackOverflow, but downvoters are meant to indicate in a comment why they are downvoting. /shrug/ – yoyo Mar 31 '15 at 16:00
-
What do you meen by pixels? Pixels of the used texture? Pixels the shader renders onto the screen? What is your problem which makes you think you want to count red pixels with a shader? – aggsol Apr 01 '15 at 11:27
-
I want to make a historygram. I need to count the pixels of the the render to texture (render target image) – ragia Apr 02 '15 at 12:50
1 Answers
2
You could do this with atomic counters in a fragment shader. Just test the output color to see if it's within a certain tolerance of red, and if so, increment the counter. After the draw call you should be able to read the counter's value on the CPU and do whatever you like with it.
edit: added a very simple example fragment shader:
// Atomic counters require 4.2 or higher according to
// https://www.opengl.org/wiki/Atomic_Counter
#version 440
#extension GL_EXT_gpu_shader4 : enable
// Since this is a full-screen quad rendering,
// the only input we care about is texture coordinate.
in vec2 texCoord;
// Screen resolution
uniform vec2 screenRes;
// Texture info in case we use it for some reason
uniform sampler2D tex;
// Atomic counters! INCREDIBLE POWER
layout(binding = 0, offset = 0) uniform atomic_uint ac1;
// Output variable!
out vec4 colorOut;
bool isRed(vec4 c)
{
return c.r > c.g && c.r > c.b;
}
void main()
{
vec4 result = texture2D(tex, texCoord);
if (isRed(result))
{
uint cval = atomicCounterIncrement(ac1);
}
colorOut = result;
}
You would also need to set up the atomic counter in your code:
GLuint acBuffer = 0;
glGenBuffers(1, &acBuffer);
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, acBuffer);
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);

Nick Toothman
- 36
- 3