Fun with OpenGL and Shaders

April 23, 2010

Last week i was having fun with OpenGL(in fact QGL) and creating some interesting effects with it like edge detection, embossing and sharpening. So i decided to work with GLSL(OpenGL Shading Language) and create the same effects using Fragment Shaders(yeah hardware accelerated effects).

So i used QGLShaderProgam that allows me create Fragment shaders in a Qt Way(tm). Initially i create two filters the first one was sharpening and the second was edge detection. Both work in a same way(with little modifications), applying a matrix convolution in the image.

The matrix convolution used in sharpening is:

0 -1 0

-1 5 -1

0 -1 0

And the matrix convolution used in edge dection is:

-1 -1 -1

-1 8 -1

-1 -1 -1

Below you can see the fragment shader used in sharpening.

uniform sampler2D sampler;

uniform vec2 offset[9];

uniform int kernel[9];

void main()
{
vec4 sum = vec4(0.0);
int i;

for (i = 0; i < 9; i++) {
vec4 color = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
sum += color * kernel[i];
}

gl_FragColor = sum;
}


The shader used in edge is almost the same

uniform sampler2D sampler;

uniform vec2 offset[9];

uniform int kernel[9];

void main()
{
vec4 sum = vec4(0.0);
int i;

for (i = 0; i < 9; i++) {
vec4 color = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
sum += color * kernel[i];
}

sum += 0.51;

gl_FragColor = sum;
}

The original image used in my experiments can be seen below:

The result of sharpening filter is:

Yeah we have a little bit improvement on the image.

And the result of edge filter is:

The embossing filter is a little bit complicated as you can see:


uniform sampler2D sampler;
uniform vec2 offset[9];
uniform int kernel[9];


void main()
{
vec4 sum = vec4(0.0);
int i = 0;
for( i = 0; i < 9; i++) {
vec4 color_tmp = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
float h = (color_tmp.x + color_tmp.y + color_tmp.z + color_tmp.w)/4.0;
if (h > 1)
h = 1.0;

if (h < 0)
h = 0.0;

vec4 color = vec4(h, h, h, h);
sum.x += color.x * kernel[i];
}

sum.x /= 1.0;
sum.x += 0.51;

if (sum.x > 1)
sum.x = 1;
if (sum.x < 0)
sum.x = 0;

gl_FragColor = vec4(sum.x, sum.x, sum.x, 1);
}

And the result is:

Qt already do OpenGL accelerated filters in QGraphicsEffects classes(look in qt_top_dir/src/opengl/qglpixmapfilter*) it is not anything new but it is interesting use it in others KDE application like krita filters :).

About these ads

8 Responses to “Fun with OpenGL and Shaders”

  1. Fri13 Says:

    Could these help make faster effects for Krita, digiKam and all kipi-plugins?

    OpenCL would be very nice as well.

    • Igor Trindade Oliveira Says:

      Yeah These could.
      About OpenCL i personally do know any opensource implementation of it. Right now each video vendor has it own OpenCL implementation and it could be a problem when implementing the OpenCL kernels.

      • slangkamp Says:

        In theory OpenCL code should run on any device that supports it. Even if some code is vendor specific at the beginning it should be easy to change that later.

        We would love to have OpenCL support in Krita.

  2. LukasT Says:

    We had glsl code editor where you could write code like you wrote in the blog post and Krita would run it as filter. But nobody was around to maintain. Maybe you can help us? We are nice to newcomers ;)

  3. Martin Ortiz Says:

    What are the values in
    uniform vec2 offset[9]; ?
    uniform int kernel[9]; ?

    is the matrix convolution the one that goes in kernel matrix?
    if so, what goes in offset matrix?

  4. Igor Trindade Oliveira Says:

    Hi Martin,

    Sharpen has a threshold you can apply the filter again and probably the image will not change.

    Igor


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: