|
OVERVIEW
The role of a surface shader is to set the apparent color and opacity of the light reflected from a sample (small region) of the surface of an object. In this section you will learn to use some of the built-in functions of the language, in particular, how to
This tutorial presents several simple shaders that can act as starting points for your own explorations. The sample shaders are not intended to be used for production. |
|
A BASIC SHADER
The experiments on surface shading in this section are based the following source code. Apart from using several intermediate variables, such as ambientcolor, diffusecolor etc., this shader is identical to the standard Pixar 'plastic' shader.
In the following examples new or modified code is shown underlined. |
|
ASSIGNING COLORS
Colors may be assigned as a single value or three individual values, color c; /* declare a variable of data type color */ c = 0.8; /* assign one color */ c = color(0.3, 0.1, 0.5); /* assign three colors */ In the first example, 0.8 is assigned to all the components of the color. In the second example, the function color() is used to set individual values for each of the red, green and blue components. The rgb color space is the default for surface shaders. Colors may also be modified by assigning a value to an individual component of a color, color c = color(0.3, 0.1, 0.5); /* declare a color */ setcomp(c, 0, 0.9); /* reset red to 0.9 */
In this example, the function setcomp() has been used to change the red
component from 0.3 to 0.9. The indices 0, 1 and 2 reference the red,
green and blue color components respectively.
color c1 = color(0.3, 0.1, 0.5),
c2 = color(0.6, 0.7, 0.8),
c3 = mix(c1, c2, 0.5);
In this example, the function mixes 50% of colors c1 and c2 to create a new color, c3; |
|
USING TEXTURE COORDINATES TO SET A COLOR
While each point (actually a small region called a sample) on a 3D
object has an x, y and z coordinate, each "point" is also located in a 2D
coordinate system called the 'st' texture space. The 'st' texture coordinates
are similiar to the measurements of latitude and longitude used to fix
a location on the surface of a cartographers map or on our planet.
When a surface shader is used by the renderer, otherwise known as being
called or instanced, the global variables 's' and
't' store the specific texture coordinates of the region being shaded.
By default the values of 's' and 't' are between zero (0.0) and one (1.0).
The specific values of 's' and 't' can be used for any purpose - not just
for texture mapping.
Modify the Surface statement in the tester RIB file, ie.Surface
"bizarre".
![]() Bizarre Shader |
|
USING A TEXTURE MAP TO SET COLOR AND OPACITY
The shading language function texture() is used to read information from a texture file. It can return a color or a single floating point number that represents the average value of the red, green and blue components of the pixel(s) corresponding to the 's' and 't' coordinates of the sample being shaded. In the following example, the texture() function is used to convert our basic shader into a texture mapper.
If you want to apply a texture map as if it were a grayscale image then use this assignment,
if(texname != "")
surfcolor = float texture(texname);
The word float before the texture function ensures
the function will return a single value ie. a floating
point number, that is an average of the red, green and blue
values of the source image.
![]() Texture Mapping In the next example the function texture() derives a single floating point value that is used to modify the opacity of the point being shaded. Again the Surface statement in the test RIB file should be edited ie. Surface "opacitymapper" "traname" ["swazi_princess.tx"]
Notice the texture() function is forced to return a single
floating point value - the average of the red, green and blue components
of the 's', 't' location in the texture file. The gray scale
value sets the apparent opacity of the surface.
![]() Opacity Mapper |
|
USING THE NOISE() FUNCTION
The noise() function is similiar to the rand() function in the 'C' language except that, depending on the data types it has been given, it can return different values of similiarly varying types. For example, noise1D = noise(1.2); /* a single float */ noise2D = noise(1.2, 3.0); /* two floats */ noise3D = noise(P); /* a single "point" */ noise4D = noise(P, 1.3); /* a "point" and a float */
The noise() function can return either a floating point, a point
or a color value. Which ever way the noise function is used, remember
it returns a floating point value for 1D and 2D noise in the
range 0.0 to 1.0, or a point or a color value with components in the
range 0.0 to 1.0. To ensure you get the type of data that you expect
"out" of the noise function it is best to cast its return value. color surfcolor = color noise(P); Similiarly, even though the variable "noise2D" is declared as a float, its best to be explicit and cast the return value as follows, float noise2D = float noise(s, t);
If the casting had been omitted
the shader compiler would have returned the appropriate data type
based on the data type of the variable receiving the value from the
noise function. color noisyColor = color noise(s, t);
So what would this give us? Since the noise function has been given
two floating point numbers (ie. the values of 's' and 't') it will return
a single float that "represents" a 2D noise value. The single value is
assigned to a data type with three components. As a result, the compiler
uses the output value three times to assign the same value to each of
the red, green and blue components. In effect we get a grayscale value
based on the texture coordinate of the sample being shaded.
![]() Noise Shader |
|
TEXTURE COORDINATES AND SPECIAL EFFECTS I
The global variables "s" and "t" store the texture coordinates of the
point on a surface that is being rendered. The first shader shown below,
stripes.sl, illustrates the use of the mod function to setup a
series of repeating transparent stripes. The mod function returns
the fractional part of "s * frequency" divided by 1.0.
![]() Stripes Shader Although the image shown above does not exhibit aliasing, the shader performs very badly at high frequences. For example, in the test RIB file try this value for the frequency parameter, Surface "stripes" "frequency" 50 |
|
TEXTURE COORDINATES AND SPECIAL EFFECTS II
In the next example both "s" and "t" are converted to sub-spaces ie. divided into bands and on the basis of checking their values "Oi" is set to transparent or the true surface opacity (Os). The result is to cut triagular holes in the surface being shaded.
![]() Triangles Shader |
|
TEXTURE COORDINATES AND SPECIAL EFFECTS III
In this example the distance of the point being shaded from center of each sub-space is checked. The result is to cut circular holes in the surface being shaded.
![]() Circles Shader |
© 2002-4 Malcolm Kesson. All rights reserved.