Some times ago I decided to start again to dive into GLSL after I paused the development of personal computer graphics projects due to lack of time.
This is the first post of a series of tutorials and notes I took while I was studying the language and the shader development.
As a developer, I spend most of the time using an IDE to write the code and particularly to debug it, so the right IDE must be chosen carefully to have the most confortable development environment. Among many tools tried, the one that has, in my opinion, the better mix of functionalities and easy of development is SHADERed (in this tutorials I’m using the version 1.5.6 and above).
For example it can automatically infer, from the name of the uniform or varying glsl variables, the proper type passed from the application to the shader. Just be sure to have ticked the right flags in the options window.

Another nice option is the preconfigured set of variables, for example the ViewProjection and GeomtryTransform matrices

As you can see from the image above, the uTime is automatically inferred as the elapsed time since the program has started, while uTimeFreq is the uniform used to scale the animation (frequency) and doesn’t link to any “system” (that is, given by the application in some predefined way) variables, but it is shown as a “pinned” variable thanks to the options Pin detected uniforms in the options window

This variable can be changed on the fly to slow down or speed up the animation
Other than the above uniform variable, there is an important set of variables that are set by default when a new project is created by clicking on the File -> New -> GLSL menu item : the Input variables . They can be shown by clicking on the Shader pass , in this case Simple and press Input layout .

The default view shows the variables for the vertex position, normal, and texture uv coordinates
Now that the main concepts have been set, let’s start with a new project and the vertex shader.

As you can see the default vertex shader is capable of setting a different color to each face of the box.
In the window with header Simple(VS) we will change only the gl_Position variable and pass the pos variable, but before that, let’s see what they are and how they can be used in the shader.
OpenGL has a default coordinate system with the X going from left to right, Y from bottom to top and positive Z going towards the viewer (right handed coordinates). A good explanation of coordinate systems and the right-handed system is here.
This variable pos contains the a three dimensional vectory (glsl type vec3) object (or local) space position of the single cube vertex passed by the application to the shader.
The shown cube has side length 1, is centered in (0,0,0) and has 8 vertices where each coordinate X,Y,Z ranges from -0.5 to 0.5.

The first line of the shader specify the version of the GLSL language to use, while the other declare the variables (discussed above and set by SHADERed)
In order to set the vertex position, a set of matrix multiplications must be applied to pass from the vertex specified in local space to screen space.
The variables matGeo and matVP and are used to transform, respectively, the local coordinate to world space and then to screen space. To apply the matrix multiplication the vertex must be transformed to homogeneous coordinate with vec4(pos,1)
The position will be later used by the fragment shader, so a out vec3 posObj variable is declared and then set in the main() function.
The full shader is
1#version 330
2
3uniform mat4 matVP;
4uniform mat4 matGeo;
5layout (location = 0) in vec3 pos;
6
7out vec4 color;
8out vec3 posObj;
9
10void main() {
11 gl_Position = matVP * matGeo * vec4(pos, 1);
12 posObj = pos;
13}The followin screenshot shows what you should see in the vertex shader window:

The vertex shader has been responsible to set the final position of the vertex, while the fragment shader sets the final pixel value.
As described above, SHADERed allow to set shader variables defined by the user or passed from a set of predefined value. One of them is the time passed since the application has been started. By setting
the Input Variables option windows should automatically infer the uTime system variable and the user defined uTimeFreq uniform. If not, enter them as shown in the image below

When you entered uTimeFreq press the + button to add it and then the other + button on the right to pin in the “Pinned” tab in the main editor.
The shader uses the time and the sin function to get a smooth value between -1 and 1, then it set the absolute value to get only the positive value.
The final multiplcation posObj * abs(sin(uTime * uTimeFreq)) set the color based on the coordinate of the local space position of the vertex that was set in the vertex shader.
posObj is a vec3 with values in the range [-0.5, 0.5]
1#version 330
2
3out vec4 outColor;
4in vec3 posObj;
5uniform float uTime;
6uniform float uTimeFreq;
7
8void main() {
9 outColor = vec4(posObj * abs(sin(uTime * uTimeFreq)), 1);
10}The final result is an animation of a cube that fades from black to color.
This is a screen shot of the effect

and here a video of the animation
In the next post we’ll se why there is a black spot in two faces of the cube and how to get rid of it.