Surface Shaders
Light Sources
Volume Shader
Displacement and Transformation Shaders
Imager Shaders
Surface shaders inherit the surface variables of the surfaces to which
they are attached. A surface shader should always set the output color Ci
and optionally the output opacity Oi
that is emitted in the
direction -I
. I
is the direction of the ray incident
to the surface. The length of this vector is equal to the distance between the
origin of the ray and the point on the surface. Thus the actual origin of the
ray is available as P-I
.
The following surface shader implements a simple turbulence
procedural texture. The shader computes the texture by adding various octaves of
noise, weighting each octave by 1/f
, where f
is the cutoff frequency of that octave. This texture is then used to modulate
the opacity of the surface. The texture is generated in the named coordinate
system "marble
", which must have been established with
by the use of an RiCoordinateSystem("marble
")
call before the instantiation of the turbulence shader. Notice that after the
opacity has been computed, it is multiplied into the color, so that the colors
and opacities output by the shader are premultiplied for use by pixel
compositors.
surface turbulence (float Kd=.8, Ka=.2) { float a, scale, sum ; float IdotN; point M;
/* convert to texture coordinate system */ M = transform("marble", P);
scale = 1; sum = 0; a = sqrt(area(M)); while (a < scale) { sum += scale * float noise(M/scale); scale *= 0.5; } Oi = sum; Ci = Cs * Oi * (Ka + Kd * I.N * I.N / (I.I * N.N)); }
The following is a procedure to implement a Turner Whitted-style ray tracer.
surface whitted( float Ka =.8; /* ambient coefficient */ float Kd =.8; /* diffuse coefficient */ float Ks =.2; /* specular coefficient */ float Kss = 2; /* specular exponent */ float Kr =.8; /* reflective coefficient */ float Kt =.2;) /* transmissive coefficient */ { vector Nn, H, T; float eta, eta2; /* Retrieve the relative index of refraction */ if (incident("eta", eta) && opposite("eta", eta2)) eta /= eta2; else eta = 1.0; Nn = faceforward(normalize(N), I); /* ambient term */ Ci = Ka * ambient(); /* diffuse and specular terms */ illuminance(P, Nn, PI/2) { /* diffuse */ Ci += Kd * Cl * L.Nn; /* specular */ H = normalize(normalize(L)+I); Ci += Ks * Cl * pow(max(0,0, Nn.H), Kss); } /* reflection */ Ci += Kr * trace(P, reflect(I, Nn)); /* transmittance */ T = refract(I, Nn, eta); if (length(T) != 0.0) Ci += Kt * trace(P, T); }
There are several types of light source shaders, distinguished by their directional properties. The directional properties of light sources depend on whether the sources execute a solar or an illuminate statement. Light source shaders without explicit illuminate or solar statements are assumed to be non-directional, or ambient. The total amount of ambient light incident on a surface is normally returned to a surface shader through ambient. A solar statement indicates that the light source is a directional light source, while an illuminate statement indicates that the light source is a local light source. Local light sources have a position. The position can be a property of the shader or can be inherited from a surface. If the light source is attached to a geometric primitive the light source is an area light source.
Light sources set Cl inside a solar or illuminate
block unless they are defining an ambient light. Inside these blocks the
direction L
points towards the surface. This variable is available
so that light source output intensities can be directional. If the light source
has a position, the length of L is the distance from the light source to the
surface being shaded.
For example, consider the following light source:
light phong( float intensity = 1.0; color color = 1; float size = 2.0; point from = point "shader" (0,0,0); point to = point "shader" (0,0,1);) { uniform point R = normalize(to-from); solar(R, PI/2) Cl = intensity * color * pow(R.L/length(L), size); }
The Phong shading model can be interpreted to be a procedural directional light source. The light source has a direction R and a size parameter that controls its fall-off. The solar statement specifies that the light source casts light in the forward facing hemisphere.
An environment background light source would be specified as follows:
light reflection(string texturename = ""; float intensity = 1.0) { solar() Cl = intensity * color environment(texturename, -L); }
The solar statement implies the light is cast from infinity in all directions. The color of the light is given by the environment map.
Volume shaders change Ci
and Oi
due to
volumetric scattering, self-luminosity, and attenuation. A volume shader is
called once per ray so it should explicitly integrate along the path of the ray.
The input Ci
and Oi
are the colors and
opacities at the point P
. The volume shader should set the color
and opacity that result at the point P-I
.
Displacement shaders move the position P
of a surface. After
a point of the surface is moved, the normals should be recalculated with
calculatenormal unless the new normals can be computed as part
of the displacement.
Transformation shaders specify a nonlinear transformation of all points in
space to new points. Since transformation shaders are not bound to surfaces,
they do not have access to the standard surface shader variables such as u
and Cs
.
The following shader places a sinusoidal bump on a surface.
displacement ripple(float amplitude = 1.0, wavelength = 0.25) { P += N * amplitude * sin(2*PI*(s / wavelength)); N = calculatenormal(P); }
Imager shaders change the value of Ci
and Oi
.
The exposure and quantization process specified in the section on
Displays in Part I could be specified as
the following imager:
imager exposure(float gain=1.0, gamma=1.0, one = 255, min = 0, max = 255) { Ci = pow(gain * Ci, 1/gamma); Ci = clamp(round(one * Ci), min, max); Oi = clamp(round(one * Oi), min, max); }
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of Pixar. The information in this publication is furnished for informational use only, is subject to change without notice and should not be construed as a commitment by Pixar. Pixar assumes no responsibility or liability for any errors or inaccuracies that may appear in this publication.
Pixar Animation Studios
|