I'm still having some trouble to get my head around fragment shaders and doing some image processing on textures. The context is a 2D sprite: a simple texture painted on a quad. All done with OpenGL ES 2.0.
My very basic goal is a simple blur filter using a 3x3 Kernel with average weights: every pixel used is weighed 1/9th and summed up.
Besides many ways to improve the performance of the fragment shader(code below) so far I'm still having some difficulties to find the right texture coordinate for the kernel.
My approach so far is to use the actual size of the quad on the screen on which the texture is painted and pass those two values to the shader. This is done outside the shader and passed as a uniform to the shader program.
glUniform2f(_offset, 1 / spriteWidth, 1 / spriteHeight);
This should result in the step in both directions to calculate a texture coordinate in the 0 to 1 space.
The result is kind of looking good. BUT I am still struggling if this is something that could be done within the shader. Is there a way to get the size of the texture within the fragment shader? If we would be only doing this on a bitmap, I'll just go from pixel to pixel and read the color of the surrounding pixels. I am wondering if my understanding of a fragment shader is quite right: It's run per rendered pixel on the screen. I found some examples for the GLSL to do this but I wasn't able to port it to OpenGL ES, so I had to start from scratch.
For the sake of readability I write a bit more code in hope it's easier to understand the fragment shader:
varying vec2 v_texCoord;
uniform vec2 u_offset;
uniform sampler2D u_texture;
const int size = 3;
const int KernelSize = size * size;
void main()
{
int i, j;
vec4 sum = vec4(0.0);
vec4 intensityOfPixel;
vec2 texCoordForKernel;
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
texCoordForKernel = vec2(v_texCoord.x + (float(i) - 1.0) * u_offset.x,
v_texCoord.y + (float(j) - 1.0) * u_offset.y);
intensityOfPixel = texture2D(u_texture, texCoordForKernel);
sum += intensityOfPixel * 1.0 / float(KernelSize);
}
}
gl_FragColor = sum;
}
Thanks alot in advance!