Selecting a Shading Language
The various extensions and core revisions of the OpenGL API have led to the availability of a number of different potential shading languages that you may use. This page will deal with
While there are other possibilities, these are the three primary competitors in the OpenGL space:
- OpenGL Shading Language (GLSL)
- C for Graphics (Cg)
- ARB assembly: assembly-like languages that are accessed through a set of ARB extensions.
- NVIDIA assembly: NVIDIA-specific extensions to the ARB assembly language.
OpenGL shading language
The OpenGL Shading Language (GLSL) is a "high-level" language. This means high-level compared to assembly, not high-level the way a language like C# is compared to C. GLSL is structurally very similar to C.
This is the current standard, as far as OpenGL is concerned. It is the only shading language that is a part of the OpenGL specification.
Because of this, it is kept up-to-date with current OpenGL features. Each new version of the base standard usually means a new version number of GLSL as well.
The complexity of having a full C-style language in a graphics driver causes quite a few driver bugs to show themselves, particularly in ATI compilers.
NVIDIA's GLSL compiler is really a slight modification of the Cg compiler. Because of that, some of the differences between GLSL and Cg will occasionally show their heads. Cg is more permissive syntactically than GLSL, so a GLSL program that compiles on an NVIDIA driver may not compile on an ATI driver. It can also give unusual error messages, with references to a "profile" (a concept that exists in Cg but not GLSL).
C for graphics
Cg is NVIDIA's shading language. It was originally intended for OpenGL, but the ARB rejected it in favor of GLSL.
The syntax is almost identical to Direct3D's HLSL. As such, Cg shaders can be ported without changes to HLSL, if one is doing cross-API development.
The Cg compiler is a library that is external to the driver. As such, the user can pre-compile shaders into their target form.
The Cg compiler is really a cross-compiler. The source code is compiled into an output based on a profile. To use Cg in OpenGL, your output profile must be something that OpenGL can accept. Therefore, Cg's disadvantages depend entirely on what profile you are using.
The GLSL profile causes the use of Cg to gain the disadvantages of GLSL, but also the advantages of it. The same goes for the ARB assembly and NVIDIA assembly profiles.
Without precompiling, you also gain a increased compile time. First the Cg compiler must generate the output for the profile, then the GLSL or ARB assembly compiler must operate to create the actual shader.
Additionally, you lose some of the flexibility of using GLSL directly. For example, you can use extensions to GLSL, but only if you're using it directly. You can't use extensions through Cg.
Another problem, particularly when using GLSL profiles, is that the code generated may not be the best for all platforms. NVIDIA writes the profiles, after all. As such, they can optimize for things their hardware does well, but would be less optimal for other hardware. What you get out of the GLSL profile is not necessarily what you would have written yourself, though it may be close to it.
The ARB_vertex_program and ARB_fragment_program extensions expose a assembly-like shading language. It is not pure assembly, and implementations of it do not have to resemble the language. But it is something close.
Faster compile times.
Intel supports these.
ARB assembly predates GLSL version 1.0. As such, ARB assembly is very old. It was designed to work with hardware around the time of the Radeon 9xxx and the GeForce FX 5xxx series. This means, in Direct3D terms, that ARB assembly only provides shader model 2.0-level functionality. It has no support for many common features.
As an assembly-like language, it is more difficult to program in the more complex your programs become.
NVIDIA assembly refers to a number of NVIDIA-specific extensions to the ARB assembly language. They make the language congruent with modern GL 3.x features (geometry shaders, etc).
Compilation speed similar to that of ARB assembly.
Intel is the sales leader in dedicated graphics hardware for PCs. This hardware is not standalone graphics boards, but low-end graphics chips integrated in Intel's motherboards.
Put simply, Intel's driver support is terrible (note: this is true for both Direct3D and OpenGL, though GL gets it worse). They refuse to implement GLSL on any of their D3D9 chips. They have implemented GLSL on their D3D10 parts, but even then, they only implement OpenGL version 2.0 (D3D10 is the functional equivalent of version 3.2 of OpenGL).
If you are interested in your shader-based programs working on older Intel hardware, the ARB assembly is your best bet, as Intel's OpenGL drivers do support that.