Chapter 5. Built-in Functions
This chapter provides the details of the functions that are defined as part of the OpenGL Shading Language. Feel free to skip ahead to the next chapter if you want to get down to the nitty-gritty of writing your own shaders. This chapter can be useful as a reference after you are well on your way to writing OpenGL shaders for your own application.
The OpenGL Shading Language defines an assortment of built-in convenience functions for scalar and vector operations. The reasons for providing built-in functions for the OpenGL Language include
Making shaders simpler to develop and easier to understand and maintain. Exposing some necessary hardware functionality in a convenient way such as accessing a texture map. The language for these functions cannot be emulated by a shader. Representing a trivial operation (clamp, mix, etc.) that is simple for a user to write but that is common and may have direct hardware support. Providing a built-in function makes it much easier for the compiler to map such expressions to complex hardware instructions. Representing an operation that graphics hardware is likely to accelerate at some point. The trigonometry functions fall into this category.
Many of the functions are similar to the same named ones in common C libraries, but they support vector input as well as the more traditional scalar input. Because the OpenGL Shading Language supports function overloading, the built-in functions usually have several variants, all with the same name. The difference in the functions is in the type of arguments and the type of the value returned. Quite a few of the built-in functions have four variants: one that takes float parameters and returns a float, one that takes vec2 parameters and returns a vec2, one that takes vec3 parameters and returns a vec3, and one that takes vec4 parameters and returns a vec4.
Whenever possible, you should use the built-in functions rather than do the equivalent computations in your own shader code. It is expected that the built-in functions will be implemented in an optimal way, perhaps even supported directly in hardware. Almost all the built-in functions can be used in either a vertex shader or a fragment shader, but a few are available only for a specific type of shader. You can write a shader to replace a built-in function with your own code simply by redeclaring and defining the same function name and argument list.
Graphical representations of some of the functions are shown for clear illustration. The functions are generally simple ones, and most readers would have no trouble constructing such diagrams themselves. But as we see in later chapters, many of the built-in functions can be used in unconventional ways to achieve interesting effects in shaders. When you are developing a shader, it is often helpful to draw a simple function diagram to clearly envision the value of a variable at a particular spot in a shader. By seeing a pictorial representation of some of these functions, you may find it easier to draw such diagrams yourself and to gain some insight about how you might use them in procedural shaders. Some common uses for these functions are pointed out along the way, and some are illustrated by shader examples in the later chapters of this book.
|