TNM084-2019 lab 3: GLSL

Lab assignment

As with lab 1, you are given quite a bit of freedom concerning exactly what to do: you are supposed to create your own code for at least one vertex shader and at least one fragment shader, together creating an effect that is at least partly planned, well considered and reasonably well executed. The most important thing is not what you do exactly, but that you understand the code you are writing. Making an animated display is not mandatory, but please consider using the supplied uniform variable time to make something move. Not only does it get more interesting, it also makes it more apparent that the rendering is indeed performed in real time.

For the exercise, I have prepared a small OpenGL program called "GLSLPrimer".

The demo will draw a sphere with a fairly small amount of polygons, and rotate the object in response to mouse drags. The vertex and fragment shaders are read from external files. Unless you want to change the tessellation of the sphere to use more triangles, or use a different object for your geometry, you only need to edit the shader files, "vertexshader.glsl" and "fragmentshader.glsl". While the demo is running, you can ask for the shaders to be re-read from the files and recompiled by pressing the space bar. You can perform the task set for you in this lab exercise without touching the C code and without recompiling the executable file, but if you want to edit the C code, there is a Dev-C++ project in the archive above, similarly to lab 1.

A simpler example in WebGL is also available, if you want to try that. Only a plane is rendered, and only the fragment shader is changed:

The built-in GLSL function noise() in all its variants still return zero on all platforms. If you want to try Perlin noise and its relatives in GLSL (yes, you want to do that), I have written implementations of "Simplex noise" as well as classic Perlin noise in GLSL for 2D, 3D and 4D. I also supply some "voronoi" functions capable of creating patterns similar to Worley noise.

Note that GLSL for WebGL is still stuck in a syntax that most closely matches GLSL version 1.20, originally relased with OpenGL 2.1 in 2006. Instead of in and out qualifiers for variables sent from the vertex shader, through interpolation, and on to the fragment shader, the qualifier varying is used for both the vertex shader output and the fragment shader input. The notion of "varying" variables was carried over from RenderMan SL, but it changed in more recent versions of GLSL, for good reasons.

Furthermore, in WebGL, the output from the fragment shader must be written to the predeclared variable vec4 gl_FragColor. More recent versions of GLSL allow considerable flexibility both in terms of the type, the name and the number of outputs from a fragment shader, but we won't go into details on that. In GLSL 3.30, the use of the pre-declared output variable vec4 gl_FragColor is deprecated, and output variables should be declared explicitly. If only one out variable is declared, OpenGL automatically assigns that for writing to the output frame buffer when linking the shader. If several output variables are declared, output variables need to be explicitly assigned to the available frame buffers. Fragment shader outputs may be either floating point or integer types, and either scalar or vector types. The invariably most common case is a single vec4 which is implicitly clamped to the range [0.0, 1.0] and interpreted as an RGBA color pixel value.

Stefan Gustavson 2019-11-20