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).
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 instancea 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.