21.3. 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.
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.