Beginners guide to GLSL (openGL shaders)
Posted on May 4th, 2012 by emil – Be the first to commentLivecoder so you can follow along: glsl.heroku.com
GLSL is based on the syntax of C, and those of you that have written shaders in PixelBender will recognize the syntax.
There are two types of shaders that are commonly used, Vertex shaders and Fragment shaders.
Vertex shaders handle geometry, like positioning and rotating a 3d model. Usually with a 4×4 matrix in 3d, and 3×3 matrix in 2d.
Fragment shaders handle the output color. All examples here will handle fragment shaders.
The shader code is uploaded to the GPU, which will be able to render it blazingly fast.
The code we write in a fragment shader will be executed once per pixel. So a canvas of 1000×1000 pixels will execute the code 1 million times. Since the scope you have is only one pixel, it requires us to think a bit differently.
On glsl.heroku.com, you get 3 things you can play around with.
Time, mouse and resolution.
Time is a float that increases in value from the second you load the shader.
Mouse is a vec2 that keeps track of our current mouse position.
Vec2 is a data type that stores two floats. You can access the first value with .x, and the second with .y.
Resolution is another vec2 that stores the current resolution in pixels of the canvas.
So resolution.x would give us the width, and resolution.y the height.
void main( void){ }
This is our main function that will be run per pixel. We can create additional functions but everything originates from here.
gl_FragCoord (Fragment Coordinate) is the current pixel being rendered. Let us store this in a variable with a shorter name, for faster typing.
void main( void){ vec2 pos = gl_FragCoord.xy; }
This could also be written:
void main( void){ vec2 pos = vec2( gl_FragCoord.x, gl_FragCoord.y); }
gl_FragColor is the output color of the pixel that will be rendered to the screen. It’s a vec4, meaning it stores 4 floats.
it can be used like this:
gl_FragColor = vec4(red, green, blue, alpha);
The color and alpha values range from 0.0 - 1.0.
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);//this will output black gl_FragColor = vec4(1.0,1.0, 1.0, 1.0);//this will output white
We can stores these values in variables for easier manipulation.
vec2 pos = gl_FragCoord.xy;</p> float red = 1.0; float green = 1.0; float blue = 1.0; float alpha = 1.0; gl_FragColor = vec4(red, green, blue, alpha);
Paste this in to the main function and the background should turn white.
Now let’s create the UV. The UV is basically just a value that ranges from 0.0-1.0, keeping track of the current pixels position in percent.
So if the resolution is 1000 pixels in width and the current current pixel is at pixel 500, the uv.x would be 0.5;
UV is handy to work with since colors values range from 0.0 - 1.0.
vec2 uv = pos.xy/resolution.xy;
So if we type uv.x, we get the current pixels position on the screen in percent. This is handy since the color values are in percent as well.
float red = uv.x;
The shader should update and now the background is a gradient.
By adding the values of the mouse to the mix, we can create some interactivity. The mouse variable is already in percent, so it’s easy to add.
float green = mouse.x;
Moving the mouse should now change and the green output color, and therefore the gradient.
In order to to animate something we need to use the time variable.
An easy way to get a value between 0.0 - 1.0 is to use sin();
sin() will output a value between -1.0 - 1.0 no matter what value you put in. So it’s perfect for our colors.
float blue = sin( time );
But we do not want to get -1.0.
float blue = (sin( time ) + 1.0) / 2.0;
To change the speed of the animation we simply multiply time.
float blue = (sin( time * 10.0 ) + 1.0) / 2.0;
Ok, too epileptic. Lets change to 2. And create a variable for speed.
float speed = 2.0; float blue = (sin( time * speed ) + 1.0) / 2.0;
That’s it for the basics.



On