2.2 High-level Shading Languages
2.2.3 OpenGL shading Language
Three years ago, SGI started the definition of the OpenGL Shading Language, which claimed to be a powerful high-level, hardware independent shading language, the OpenGL Shading Language (GLSL). This language enables direct compilation of C-like programs to graphics hardware machine code, creating enormous opportunities for compiler and graphics architectural innovation and bringing real-time realistic rendering a step closer to reality. [OpenGL 2005]
OpenGLSL has been designed to allow application programmers to define processing at those programmable points of the graphics pipeline. Two shaders in the pipeline are vertex shaders and fragment shaders. Both are independently compilable units separated from the main program. Like the Cg shading language, the OpenGL Shading Language is based on ANSI C with extended vector and matrix data types which make it more concise for the typical operations carried out in 3D graphics. Before the OpenGLSL can been supported by the OpenGL standard, it does have to have a set of extensions that are supported by a number of graphics card vendors.
If there is an OpenGL application, we should disable the original rendering fixed pipeline function and add the programmable shader into the rendering pipeline. Built-in access to the existing OpenGL state keeps the API entry points the same as developer are used to. Another benefit from GLSL is that shader compiles during runtime. The major difference GLSL has with other formats of shading languages is that it allows GLSL to
be compiled inside of OpenGL rather than compiled with individual hardware venders. This could bring optimal performance on the graphics hardware. [Rost 2004]
OpenGLSL is getting closer to becoming the cross-platform standard for all shadings languages. The GLSL is included as a subset of the release of OpenGL2.0 on Sep. 9th 2004. This also depend on if GLSL will became so dominant so that every hardware vendor like to develop the back end compiler for it.
Application
GLSL source code
OpenGL Driver
Shader
Object
Program
Object
Shader Source code
OpenGL API
CompilerLinker
Executable code
Graphics Hardware
Provide by developer
Provide by graphics hardware vender
Let’s look at how the GLSL shader is loaded by the main program and executed on the GPU. Figure 2.5 illustrates how the OpenGL shaders are handled in the execution environment of OpenGL. Applications communicate with OpenGL functions by calling functions in the OpenGL API. An OpenGL function “glCreatShaderObjectARB” allows a shader data structure to be created within the OpenGL driver. Then a character string is sent to the OpenGL API to indicate the name of the shader program. 3DLabs released their GLSL front-end compiler. This front-end compiler tokenizes the shader string and produces a binary, high-level representation of the language. The back end of the compiler has to be implemented individually by different hardware vendors. This should be typically packaged inside of the hardware driver. Of course, hardware support for GLSL depends on each of the hardware vendor’s willingness to implement the compiler for GLSL.
Example 2.3 A vertex shader for brick in OpenGL shading language.
// GLSL
const vec3 LightPosition=vec3(0.0, 0.0, 4.0); const float specularContribution = 0.3;
const float diffuseContribution = 0.7;//0.7 = 1.0 - specularContribution varying float LightIntensity;
varying vec2 MCposition; void main(void)
{
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); vec3 lightVec = normalize(LightPosition - vec3 (ecPosition)); vec3 reflectVec = reflect(-lightVec, tnorm);
vec3 viewVec = normalize(vec3 (-ecPosition)); float spec = max(dot(reflectVec, viewVec), 0.0); spec = pow(spec, 16.0);
LightIntensity = diffuseContribution * max(dot(lightVec, tnorm), 0.0) + specularContribution * spec;
MCposition = vec2 (gl_Vertex);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
Next, example 2.3 shows the OpenGLSL shader. One of the differences between Cg and OpenGLSL is that the connector which glues the shader with the underlying graphics APIs. In GLSL, a set of built-in variables does the gluing job. They have prefix of “gl_” for example, “gl_ModelViewMatrix” is a uniform matrix passed in from main program; and “gl_Vertex” is a variable for the position of each vertex. These variables are needed during vertex shader is executed. Compare to Cg shader, In GLSL the matrix variables for transformation were predefined and can be used directly in shader program. On the other hand, Cg shader takes care of the connection by some developer defined variables binding with a set of Semantics, i.e. POSITION, COLOR etc. and the uniform matrixes which passed in from main program.
On the other hand, in Cg, the “gl_” are not predefined.In GLSL, the inputs of the vertex shader are vertex information such as normal, color, texture coordinate and so on. Data flows into vertex shaders via attribute built-in/user-defined variable, uniform built- in/user-defined variable, and built-in/user-defined varying variable, as well as special vertex shader output variables will pass the information to be rasterized and then to the fragment shader on the next step of the rendering pipeline.
More details of the OpenGL Shading Language functionality and data type’s built-in/user defined variable and functions will be discussed in detail in chapter 3.