# How to get the texture coordinate of a neighbouring pixel for a blur shader?

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!

• Isn't that ddx and ddy are used for (might be wrong here)? Otherwise do the 1.0/texturesize in the (c++/ ...) code and set a global uniform shader variable to it. – Valmond Mar 9 '12 at 12:57
• @Valmond I don't know what ddx and ddy are but maybe you can give me a hint where to search for those terms related to glsl? Yes that's what I tried to explain how I am doing it right now: The single line of code. I'll clarify that. – Nick Weaver Mar 9 '12 at 13:03
• For little optimization: You don't have to use for (i = 0; ...) and then float(i) - 1, but you can use: for (i = -1; ...) – zacharmarz Mar 9 '12 at 13:28
• And if I should comment question: You are doing it right. You have to pass 1/textureWidth and 1/textureHeight. – zacharmarz Mar 9 '12 at 13:30
• @zacharmarz Yes there is alot you can refactor and make this more efficient, even go as far as using two different shaders for one axis only. This was just to show my general approach. Thanks for your comment. – Nick Weaver Mar 9 '12 at 13:42

• Thanks for your answer. I thought I am already passing the divided values already: glUniform2f(_offset, 1 / spriteWidth, 1 / spriteHeight); or are you refering to something else? – Nick Weaver Mar 9 '12 at 13:40