You might be interested in my OpenGL notes.

What is GLSL?

The newer versions of OpenGL (later than 2.0) support (and may even insist upon) using a shading language. This is a completely separate and specialized programming language used to create "shaders". These shaders are sent to the rendering engine (usually the hardware managed by the GPU) where they are compiled and used to modify how the rendering process is accomplished. I think of these so called shaders as simply the programs that run on that other computer you’re hopefully using, the GPU. While somewhat flexible, GLSL is a language that is very focused on the tasks needed to be done by a GPU. It is to the GPU hardware what JavaScript is to a web browser.

There are a few kinds of shaders:

Helpful Tips

Here’s a way to get Vim to highlight GLSL.

Here is an astonishingly good resource that allows composing different shader experiments in a web sandbox with the ability to output the code to Cpp.

Different Shaders

The following are the valid types of shaders as implied by the enum parameter to the glCreateShader() function.

GL_VERTEX_SHADER

This seems to be applied to the geometry of the objects being rendered. I’m not sure really what exactly it does except to ostensibly "shade" vertices.

GL_GEOMETRY_SHADER

This is a less used kind of shader (it’s optional) that is often not even listed in pipeline diagrams. It’s only officially been in OpenGL since version 3.2. Maybe it is used to get effects like hair or fur or plant parts, things which move around the basic points of an object but which are mostly visual. Or maybe it’s designed to distort the view port as in the Oculus Rift’s required barrel distortion. I don’t know yet. New information: It has access to all the vertices in a primitive. The outputs of the vertex shader would be the inputs for the geometry shader and the outputs of the geometry shader can be the inputs for the fragment shader. One application would be to plot the surface normals of a bunch of triangles.

GL_FRAGMENT_SHADER

This seems to be applied to regions of pixels as opposed to geometric coordinates. This seems to happen once the geometry is established and entire regions (which I think are what fragments are) are rendered to screen pixels. Need to make the entire scene sunny or gloomy? Then this is the shader to concentrate on.

GL_COMPUTE_SHADER

No idea.

GL_TESS_CONTROL_SHADER

No idea. Presumably "tess" is for tessellation.

GL_TESS_EVALUATION_SHADER

No idea.

See glCreateShader() for the official details.

Functions For Shader Setup

General Syntax

GLSL is pretty similar to C stylistically. Commenting is the same. The statements end in a semi-colon. Types are strictly declared.

Variable Types

Since the GLSL is a full working programming language, it has a selection of usable data types.

bool

Can be true or false. Specify with: bool ok= false

int

Signed integer. Specify with: int temp= 68

uint

Unsigned integer. Specify with: uint speed= 70u

float

Floating point. Specify with: float ratio= 3.5f

bvec2,bvec3,bvec4

Vector of booleans. bvec2=(true,false)

ivec2,ivec3,ivec4

Vector of integers.

uvec2,uvec3,uvec4

Vector of unsigned integers.

vec2,vec3,vec4

Vector of floats.

Storage Qualifiers

The variables can be declared with storage qualifiers. The main one is uniform for values passed in from the client which will not change in the shader. There are in and out which governs variables that are coming from another or going to another processing stage, i.e. another shader. You can also specify variables with const if they’re specific to the shader program and are not going to change during the its operation. There are also in centroid, out centroid, and inout but these seem exotic. I’ve also seen varying in programs used as a storage qualifier.

With vector types, you can do something called "swizzling" which looks like:

avectype.x= 1.0f;
avectype.yz= (2.0f,3.0f);
doubled= avectype * 2.0f;

The vector type subcomponents are xyzw or rgba or stpq for working on geometry, colors, or textures respectively. BTW, nobody seems to know what the letters stpq stand for.

GLSL Built-In Functions

Can one define GLSL functions? I don’t know that yet. There are quite a few handy functions available to use right away in GLSL. In some ways it’s kind of convenient to be able to count on your graphics hardware to know how to do the normal graphics things without calling special libraries in your program. Here are some available functions:

  • radians(), degrees()

  • sin(), asin(), sinh(), asinh()

  • cos(), acos(), cosh(), acosh()

  • tan(), atan(), tanh(), atanh()

  • pow(), exp(), exp2()

  • log(), log2()

  • sqrt(), inversesqrt()

  • length(vec), distance(v1,v2), normalize(vec)

  • dot(v1,v2), cross(v1,v2), faceforward()

  • reflect() refract()

  • matrixCompMult(), outerProduct()

  • transpose(), determinant(), inverse()

  • lessThan(vec), greaterThan(vec)

  • lessThanEqual(), greaterThanEqual()

  • equal(), notEqual()

  • any(vec) [or], all(vec) [and], not(vec)

  • abs(), sign(), floor(), trunc(), round(), ceil(), fract()

  • mod(), modf()

  • min(), max(), clamp()

  • mix(), step(), smoothstep()

  • isnan(), isinf()

  • floatBitsToInt(), floatBitsToUint(), intBitsToFloat(), uintBitsToFloat()

User Defined Functions and Control Structures

It looks like you can program your own functions in GLSL. The syntax is very much like C.

GLSL seems to support if, else if, and else constructions and they look exactly like C’s.

Although less common, I’ve seen for loops working fine too. They too are exactly like C.

There is also a preprocessor which can do some of the things the C preprocessor its syntax is based on can do.

Here is an example that shows a function definition, local variables, a for loop, and if syntax:

// Comments look like this.

#ifdef GL_ES
precision mediump float;
#endif
#define CUTOFF 0.001

float shadow(vec3 x1, vec3 x2){
    float s= 0.0;
    float p= 0.0;
    for(int i= 0; i < 25; i++) {
        p= myHelper(x1 + x2 * s);
        if (p < CUTOFF){
            return 0.5;
        }
        s += p;
    }
    return 1.0;
}