GLSL : recommendations

From OpenGL.org
Jump to: navigation, search

Here are a few quick recommendations for your GLSL code.

Version Number

No matter what your target GL version is, it is best to put the version number at the top of each shader (vertex shader, geometry shader, fragment shader and any other shader stage). It would look like this

 #version 110

where the above version number means 1.10 in this particular example.

It makes things clearer. People will understand what version of GLSL you are aiming for and so they don't have to guess it by looking at the rest of the code. Also, the driver might be more strict in terms of the syntax if it sees that. Strictness is a good thing because it enforces the GLSL standard and no additional features that the IHV might provide (IHV such as nVidia).

Code Comments

It is nice to put some comments in your code.

This one is obvious : write //VERTEX SHADER at the top of your vertex shader. Write //FRAGMENT SHADER at the top of your fragment shader

No Missing Shader

For GL 2.0 and 2.1, it was possible to just have a vertex shader and no fragment shader. In this case, the fixed pipeline would take care of the fragment processing. You could also have a fragment shader with no vertex shader. It is good practice to get into the habit of thinking of the GPU as a programmable device.

In core contexts of 3.1 or greater, everything is done with shaders.

Built-in Uniforms

For GL 2.0 and 2.1, you could make use of built in uniforms such as gl_ProjectionMatrix and gl_ModelViewProjectionMatrix and many others.

It is strongly recommended that you get rid of these and use your own uniforms.

In core contexts version 3.1 or greater, most of the built-in uniforms were removed.

Vertex or Fragment Stage?

You might be tempted to write some part of your code in the fragment stage. Is it possible to move that piece of code to the vertex stage and send the result to the fragment stage as a varying?

Try to not overburden the fragment processors of your GPU. Consider: you might have on the order of 10,000 vertices in your scene, while your display might easily be showing around 1,000,000 pixels. The vertex shader gets called for every vertex, while the fragment shader gets called for every fragment (i.e. at least once per pixel). That’s around 100 invocations of the fragment shader for every vertex shader invocation.

Optimizations

The All In One Shader

There is a temptation to just have 1 shader that does all : 100 lights and textures and bump mapping that can be turned on and off at the flip of a boolean uniform. Boolean uniforms and for loops all over the place.

Consider writing separate shaders for different cases. Consider writing a tool that auto-generates some of your shaders.