Chapter 21. Language Comparison

The OpenGL Shading Language is by no means the first graphics shading language ever defined. Here are a few other notable shading languages and a little about how each one compares to the OpenGL Shading Language. Compare the diagrams in this chapter with the OpenGL Shading Language execution model in Figure 2.4 for a visual summary.

Chronology of Shading Languages

Rob Cook and Ken Perlin are usually credited with being the first to develop languages to describe shading calculations. Both of these efforts targeted offline (noninteractive) rendering systems. Perlin’s work included the definition of the noise function and the introduction of control constructs. Cook’s work on shade trees at Lucasfilm (later Pixar) introduced the classification of shaders as surface shaders, light shaders, atmosphere shaders, and so on, and the ability to describe the operation of each through an expression. This work evolved into the effort to develop a full-featured language for describing shading calculations, which was taken up by Pat Hanrahan and culminated in the 1988 release of the first version of the RenderMan Interface Specification by Pixar. Subsequently, RenderMan became the de facto industry-standard shading language for offline rendering systems for the entertainment industry. It remains in widespread use today.

The first interactive shading language was demonstrated at the University of North Carolina on a massively parallel graphics architecture called PixelFlow that was developed over the decade of the 1990s. The shading language used on PixelFlow could render scenes with procedural shading at 30 frames per second or more. The shading language component of this system was described by Marc Olano in 1998.

After leaving UNC, Olano joined a team at SGI that was defining and implementing an interactive shading language that would run on top of OpenGL and use multipass rendering methods to execute the shaders. This work culminated in the release in 2000 of a product from SGI called OpenGL Shader, the first commercially available real-time, high-level shading language.

In June 1999, the Computer Graphics Laboratory at Stanford embarked on an effort to define a real-time shading language that could be accelerated by existing consumer graphics hardware. This language was called the Stanford Real-Time Shading Language. Results of this system were demonstrated in 2001.

The OpenGL Shading Language, Microsoft’s HLSL, and NVIDIA’s Cg are all efforts to define a commercially viable, real-time, high-level shading language. The white paper that first described the shading language that would become the OpenGL Shading Language was published in October 2001 by Dave Baldwin of 3Dlabs. NVIDIA’s Cg specification was published in June of 2002, and Microsoft’s HLSL specification was published in November 2002, as part of the beta release of the DirectX 9.0 Software Development Kit. Some cross-pollination of ideas occurred among these three efforts because of the interrelationships of the companies involved.

In subsequent sections, we compare the OpenGL Shading Language with other commercially available high-level shading languages.


In 1988, after several years of development, Pixar published the RenderMan Interface Specification. This was an interface intended to define the communications protocol between modeling programs and rendering programs aimed at producing images of photorealistic quality. The original target audience for this interface was animation production, and the interface has proved to be very successful for this market. It has been used as the interface for producing computer graphics special effects for films such as Jurassic Park, Star Wars Episode 1: The Phantom Menace, The Lord of the Rings: The Two Towers, and others. It has also been used for films that have been done entirely with computer graphics such as Finding Nemo, Toy Story, A Bug’s Life, and Monsters, Inc.

One of the main differences between the OpenGL Shading Language and RenderMan is that RenderMan attempts to define the entire interface between modeling programs and rendering programs. It provides an entire graphics processing pipeline of its own that has no relationship to OpenGL. Although a hardware implementation was envisioned at the time RenderMan was first defined, it was primarily designed as a high-quality, realistic rendering interface; therefore, it provides no compromises for interactivity or direct hardware implementation on today’s graphics hardware. RenderMan includes support for describing geometric primitives, hierarchical modeling, stacking geometric transformations, camera attributes, shading attributes, and constructive solid geometry. OpenGL already provides many of these capabilities; therefore, they need not be addressed in the OpenGL Shading Language.

RenderMan execution environment

Figure 21.1. RenderMan execution environment

Of particular interest, however, is the portion of RenderMan called the RenderMan Shading Language. This language completely describes arbitrary shaders that can be passed to a renderer through the RenderMan interface. This language was also based on C, and as such, it bears some resemblance to the OpenGL Shading Language. In a general way, the RenderMan interface is similar to OpenGL, and the RenderMan Shading Language is similar to the OpenGL Shading Language. The RenderMan interface and OpenGL both let you define the characteristics of a scene (viewing parameters, primitives to be rendered, etc.). Both shading languages compute the color, position, opacity, and other characteristics of a point in the scene.

One of the main differences between the OpenGL Shading Language and the RenderMan Shading Language is in the abstraction of the shading problem. The OpenGL Shading Language closely maps onto today’s commercial graphics hardware and has abstracted two types of shaders so far: vertex shaders and fragment shaders. The RenderMan Shading Language has always had uncompromising image quality as its fundamental goal, and it abstracts five shader types: light shaders, displacement shaders, surface shaders, volume shaders, and imager shaders. The RenderMan shader types lend themselves to the implementation of high-quality software rendering implementations, but they do not match up as well with hardware that has been designed to support interactive rendering with OpenGL. As a result, RenderMan implementations have typically been software based, but attempts to accelerate it in hardware have been made (read Interactive Multi-Pass Programmable Shading by Peercy, Olano, Airey, and Ungar, 2000). The OpenGL Shading Language was designed from the beginning for acceleration by commodity graphics hardware.

There are some differences in the data types supported by the two languages. RenderMan supports native types that represent colors, points, and normals, whereas the OpenGL Shading Language includes the more generic vectors of 1, 2, 3, or 4 floating-point values that can support any of those. RenderMan goes a bit further in making the language graphics-specific by including built-in support for coordinate spaces named object, world, camera, NDC, raster, and screen.

RenderMan supports a number of predefined surface shader variables, light source variables, volume shader variables, displacement shader variables, and imager shader variables. The OpenGL Shading Language contains built-in variables that are specific to OpenGL state values, some of which are similar to the RenderMan predefined variables. Because it is aimed at producing animation, RenderMan also has built-in variables to represent time. The OpenGL Shading Language does not, but such values can be passed to shaders through uniform variables to accomplish the same thing.

On the other hand, the two languages have much in common. In a very real sense, the OpenGL Shading Language can be thought of as a descendant of the RenderMan Shading Language. The data type qualifiers uniform and varying were invented in RenderMan and have been carried forward to mean the same things in the OpenGL Shading Language. Expressions and precedence of operators in both languages are very much like C. Keywords such as if, else, while, for, break, and return are the same in both languages. The list of built-in math functions for the OpenGL Shading Language is largely similar to the list of built-in math functions for the RenderMan Shading Language.

OpenGL Shader (ISL)

OpenGL Shader was a software package developed by SGI and released in 2000. It was available as a commercial product for several years, but is no longer available. OpenGL Shader defined both a shading language (Interactive Shading Language, or ISL) and a set of API calls that defined shaders and used them in the rendering process.

The fundamental premise of OpenGL Shader was that the OpenGL API could be used as an assembly language for executing programmable shaders (see Figure 21.2). Hardware with more features (e.g., multitexture and fragment programmability) could be viewed as having a more powerful assembly language. A sequence of statements in an ISL shader could end up being translated into one or more rendering passes. Each pass could be a geometry pass (geometry is drawn to use vertex, rasterization, and fragment operations), a copy pass (a region of the framebuffer is copied back into the same place in the framebuffer to use pixel, rasterization, and fragment operations), or a copy texture pass (a region of the framebuffer is copied to a texture to use pixel operations). Compiler optimization technology determined the type of pass required to execute a sequence of source code instructions and, if possible, to reduce the number of passes needed overall. The final version of OpenGL Shader was optimized for multiple hardware back ends and could exploit the features exposed on a particular platform to reduce the number of passes required.

OpenGL Shader (ISL) execution environment

Figure 21.2. OpenGL Shader (ISL) execution environment

Like every other shading language worth its salt, ISL is based on C. However, because of its fundamental premise, ISL shaders end up looking quite different from OpenGL shaders. Many of the instructions in an ISL shader end up look like directives to perform a rendering pass. For example, consider the following ISL source code:

varying color b;
FB  = diffuse();
FB *= color(.5, .2, 0, 1);
b   = FB;
FB  = specular(30.0);
FB += b;

The identifier FB specifies a result to be stored in the frame buffer. This sequence of operations first calls a subshader that executes a light shader to compute a diffuse color for the geometry being rendered. This value is multiplied by the color value (.5, .2, 0, 1), and the result is then stored in a region of texture memory called b. A specular reflection calculation is performed next, and finally the diffuse component and specular components are added together. Although it has the appearance of requiring multiple passes, this sequence of instructions can actually be executed in a single pass on a number of different graphics accelerators.

ISL supports surface and light shaders, which are merged and compiled. In this regard, it is more similar to the RenderMan way of doing things than it is to the OpenGL distinction of vertex and fragment shaders.

Another difference between the OpenGL Shading Language and ISL is that ISL was designed to provide portability for interactive shading by means of the OpenGL capabilities of both past and current hardware, whereas the OpenGL Shading Language was designed to expose the programmability of current and future hardware. The OpenGL Shading Language is not intended for hardware without a significant degree of programmability, but ISL executes shaders with the identical visual effect on a variety of hardware, including hardware with little or no explicit support for programmability.

Yet another difference between ISL and the OpenGL Shading Language is that ISL was designed with the constraints of using the OpenGL API as an assembly language, without requiring any changes in the underlying hardware. The OpenGL Shading Language was designed to define new capabilities for the underlying hardware, and so it supports a more natural syntax for expressing graphics algorithms. The high-level language defined by the OpenGL Shading Language can be translated into the machine code native to the graphics hardware with an optimizing compiler written by the graphics hardware vendor.


HLSL stands for High-Level Shader Language, and it was defined by Microsoft and introduced with DirectX 9 in 2002. In terms of its syntax and functionality, HLSL is much closer to the OpenGL Shading Language than either RenderMan or ISL. HLSL supports the paradigm of programmability at the vertex level and at the fragment level just as in the OpenGL Shading Language. An HLSL vertex shader corresponds to an OpenGL vertex shader, and an HLSL pixel shader corresponds to an OpenGL fragment shader.

One of the main differences between the OpenGL Shading Language and HLSL is in the execution environment (see Figure 21.3). The HLSL compiler is really a translator that lives outside DirectX in the sense that HLSL programs are never sent directly to the DirectX 9 API for execution. Instead, the HLSL compiler translates HLSL source into assembly-level source or binary programs called vertex shaders and pixel shaders (in Microsoft DirectX parlance). Various levels of functionality have been defined for these assembly level shaders, and they are differentiated by a version number (e.g., Vertex Shader 1.0, 2.0, 3.0; Pixel Shader 1.1, 1.4, 2.0, 3.0).

Execution environment for Microsoft’s HLSL

Figure 21.3. Execution environment for Microsoft’s HLSL

One advantage of this approach is that HLSL programs can be translated offline, or long before the application is actually executed. However, the translation is done to a binary representation of assembly code. This binary representation may still need to be translated to native machine code at execution time. This is in contrast to the OpenGL Shading Language model, in which the compiler is part of the driver, and the graphics hardware vendor writes the compiler. Giving the graphics hardware vendor the responsibility of translating from high-level shading language source to machine code grants these vendors a lot of room for shader optimization and architectural innovation.

HLSL is designed to make it easier for application developers to deal with the various levels of functionality found in these assembly-level shaders. Using HLSL and the support environment that has been built around it, application developers can write shaders in a high-level shading language and be reasonably confident that their shaders will run on hardware with widely varying capabilities.

However, because HLSL is more expressive than the capabilities of graphics hardware that exists today and much more expressive than hardware shipped in the past, HLSL shaders are not guaranteed to run on every platform. Shader writers have two choices: They can write their shader for the lowest common denominator (i.e., hardware with very little programmability), or they can target their shader at a certain class of hardware by using a language feature called profiles. Microsoft provides supporting software called the DirectX Effects Framework to help developers organize and deploy a set of shaders that do the same thing for hardware with differing capabilities.

The fundamental data types in HLSL are the same as those in the OpenGL Shading Language except for slight naming differences. HLSL also supports half- and double-precision floats. Like the OpenGL Shading Language, HLSL accommodates vectors, matrices, structures, and arrays. Expressions in HLSL are as in C/C++. User-defined functions and conditionals are supported in the same manner as in the OpenGL Shading Language. Looping constructs (for, do, and while) are defined in HLSL, but the current documentation states that they are not yet implemented. HLSL has a longer list of built-in functions than does the OpenGL Shading Language, but those that are in both languages are very similar or identical.

One area of difference is the way in which values are passed between vertex shaders and pixel (HLSL) or fragment (OpenGL Shading Language) shaders. HLSL defines both input semantics and output semantics (annotations that identify data usage) for both vertex shaders and pixel shaders. This provides the same functionality as the OpenGL Shading Language varying and built-in variables. You are allowed to pass arbitrary data into and out of vertex and pixel shaders, but you must do so in named locations such as POSITION, COLOR[i], TEXCOORD[i], and so on. This requirement means that you may have to pass your light direction variable lightdir in a semantic slot named TEXCOORD[i], for instance—a curious feature for a high-level language. The OpenGL Shading Language lets you use arbitrary names for passing values between vertex shaders and fragment shaders.

Another obvious difference between HLSL and the OpenGL Shading Language is that HLSL was designed for DirectX, Microsoft’s proprietary graphics API, and the OpenGL Shading Language was designed for OpenGL. Microsoft can add to and change DirectX, whereas OpenGL is an open, cross-platform standard that changes more slowly but retains compatibility with previous versions.


Cg is a high-level shading language that is similar to HLSL. Cg has been defined, implemented, and supported by NVIDIA. Comparing Cg to the OpenGL Shading Language is virtually the same as comparing HLSL to the OpenGL Shading Language. There are a few minor differences between Cg and HLSL (for instance, HLSL has a double data type but Cg does not), but Cg and HLSL were developed by Microsoft and NVIDIA working together, so their resulting products are very similar.

One advantage that Cg has over both HLSL and the OpenGL Shading Language is that the Cg translator can generate either DirectX vertex shader/pixel shader assembly code or OpenGL vertex/fragment program (assembly-level) code. This provides the potential for using Cg shaders in either the DirectX environment or the OpenGL environment (see Figure 21.4). However, it also requires the application to make calls to a library provided by NVIDIA that sits between the application and the underlying graphics API (either OpenGL or DirectX). This library is called the Cg Runtime library. For simple applications, it can be a help in covering up the limitations of the underlying driver (for instance, it can cover up the fact that a DirectX driver supports multiple versions of vertex and pixel shaders and automatically selects the most appropriate version to use). But this intervening layer can also complicate things for more complicated applications because it covers up details of shader management.

The Cg execution environment

Figure 21.4. The Cg execution environment

NVIDIA has its own version of the framework that surrounds the shading language. CgFX is a shader specification and interchange format whose file format is the same as that supported by the .fx Effect format for DirectX 9. The CgFX runtime library, like the Cg runtime library, supports both OpenGL and DirectX, so in this way the Microsoft and NVIDIA products differ.

Because it is so similar to HLSL, the advantages and disadvantages of Cg with respect to the OpenGL Shading Language are also similar: proprietary versus standard (thus earlier to market), support for less capable hardware at the cost of hardware dependencies in shader source code, translation from high-level shading language to “standard” assembly interface offline versus a compiler embedded in the driver, a more complete shader development system but with the requirement of extra runtime libraries, and so on.


Shading languages have been around for some time now. The first shading languages were non-real-time languages aimed at producing photorealistic imagery. Graphics hardware capable of supporting an interactive shading language showed up in research labs in the 1990s, and today, this type of programmable graphics hardware is available at consumer price points. This has led to the development of several commercially available shading languages, notably, ISL, the OpenGL Shading Language, HLSL, and Cg.

In the spectrum of programming languages, the last three are extremely similar. Each was designed to provide functionality available in RenderMan by the use of C/C++ as the basis for the language syntax. The result is that all three languages are similar in terms of syntax and capability. The single biggest technical difference is that HLSL and Cg sit on top of standard interfaces such as DirectX and OpenGL and translate high-level source code to assembly outside those APIs. The OpenGL Shading Language, on the other hand, translates high-level source code to machine code within the OpenGL driver.

As far as nontechnical differences, the HLSL and CG specifications are controlled by Microsoft and NVIDIA, respectively. The OpenGL Shading Language is controlled by the OpenGL ARB, a standards body made up of representatives from a variety of graphics hardware and computer manufacturers. HLSL is designed for use in Microsoft’s DirectX environment, and the OpenGL Shading Language is designed for use with OpenGL in a variety of operating environments. Cg is designed to be used in either DirectX or OpenGL environments.

Further Information

The RenderMan Shading Language is specified in Pixar’s The RenderMan Interface Specification (2000), and its use is described in the books The RenderMan Companion: A Programmer’s Guide to Realistic Computer Graphics (Upstill 1990) and Advanced RenderMan: Creating CGI for Motion Pictures (Apodaca and Gritz 1999).

OpenGL Shader and ISL are described in the SIGGRAPH 2000 paper Interactive Multi-Pass Programmable Shading. The book Real-Time Shading by Olano, Hart, Heidrich, and McCool (2002) contains chapters describing various shading languages, including RenderMan, ISL, and shading languages defined and implemented by researchers at the University of North Carolina, Stanford, and the University of Waterloo.

The Stanford Real-Time Shading Language is described in the SIGGRAPH 2001 paper, A Real-Time Procedural Shading System for Programmable Graphics Hardware, and in the course notes for Real-Time Shading, Course 24, SIGGRAPH 2001.

There are sure to be books out that describe Microsoft’s HLSL, but at the time of this writing, the only documentation I could find is available from Microsoft on the DirectX 9 page of its Web site, directx. A good starting point is Introduction to the DirectX 9 High-Level Shader Language by Craig Peeper and Jason Mitchell. This paper also appears as a chapter in the book ShaderX2: Shader Programming Tips and Tricks with DirectX 9.0 by Wolfgang Engel.

Cg is described in documentation from NVIDIA in the book The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics by Fernando and Kilgard (2003) and in the SIGGRAPH 2003 paper Cg: A System for Programming Graphics Hardware in a C-like Language.

The bibliography at the end of this book contains references to other notable noncommercial shading languages.

  1. Apodaca, Anthony A., and Larry Gritz, Advanced RenderMan: Creating CGI for Motion Pictures, Morgan Kaufmann Publishers, San Francisco, 1999.

  2. Baldwin, Dave, OpenGL 2.0 Shading Language White Paper, Version 1.0, 3Dlabs, October, 2001.

  3. Cook, Robert L., Shade Trees, Computer Graphics (SIGGRAPH ’84 Proceedings), pp. 223–231, July 1984.

  4. Fernando, Randima, and Mark Kilgard, The Cg Tutorial, the Definitive Guide to Programmable Real-Time Graphics, Addison-Wesley, Boston, Massachusetts, 2003.

  5. Kessenich, John, Dave Baldwin, and Randi Rost, The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004.

  6. Mark, William R., Real-Time Shading: Stanford Real-Time Procedural Shading System, SIGGRAPH 2001, Course 24, course notes, 2001.

  7. Mark, William R., R. Steven Glanville, Kurt Akeley, and Mark Kilgard, Cg: A System for Programming Graphics Hardware in a C-like Language, Computer Graphics (SIGGRAPH 2003 Proceedings), pp. 896–907, July 2003.

  8. Microsoft, DirectX 9.0 SDK, 2003.

  9. NVIDIA Corporation, Cg Toolkit, Release 1.4, software and documentation.

  10. Olano, Marc, and Anselmo Lastra, A Shading Language on Graphics Hardware: The PixelFlow Shading System, Computer Graphics (SIGGRAPH ’98 Proceedings), pp. 159–168, July 1998.

  11. Olano, Marc, John Hart, Wolfgang Heidrich, and Michael McCool, Real-Time Shading, AK Peters, Ltd., Natick, Massachusetts, 2002.

  12. Peeper, Craig, and Jason Mitchell, Introduction to the DirectX 9 High-Level Shader Language, in ShaderX2 : Shader Programming Tips and Tricks with DirectX 9.0, Editor: Wolfgang Engel, Wordware Publishing, 2003.

  13. Peercy, Mark S., Marc Olano, John Airey, and P. Jeffrey Ungar, Interactive Multi-Pass Programmable Shading, Computer Graphics (SIGGRAPH 2000 Proceedings), pp. 425–432, July 2000.

  14. Perlin, Ken, An Image Synthesizer, Computer Graphics (SIGGRAPH ’85 Proceedings), pp. 287–296, July 1985.

  15. Pixar, The RenderMan Interface Specification, Version 3.2, Pixar, July 2000.

  16. Proudfoot, Kekoa, William R. Mark, Svetoslav Tzvetkov, and Pat Hanrahan, A Real-Time Procedural Shading System for Programmable Graphics Hardware, Computer Graphics (SIGGRAPH 2001 Proceedings), pp. 159–170, August 2001.

  17. SGI OpenGL Shader Web site. (defunct)

  18. ShaderX2 : Shader Programming Tips and Tricks with DirectX 9.0, Editor: Wolfgang Engel, Wordware Publishing, 2003.

  19. Upstill, Steve, The RenderMan Companion: A Programmer’s Guide to Realistic Computer Graphics, Addison-Wesley, Reading, Massachusetts, 1990.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.