5.7 Kernels
The Sh library includes implementations of some standard program kernels.
These are functions to generate parameterized shader objects. Kernel
programs are designed to be used immediately, specialized, or combined
with other kernels to build useful custom shaders using shader algebra
operations.
Several design decisions were made in an attempt to keep the kernel library
easy to use:
- Commonly curried inputs are placed at the beginning of the input list
to reduce the need for the shExtract manipulator.
- All inputs and outputs are named (have name metadata attached)
which allows manipulation and selection by name.
- Names for inputs and outputs that should be joined together on
connection have the same name and type and are usually in the same
order. This allows these kernels to be connected by position or by name
without complex manipulator expressions.
In the following subsections, we will describe the available kernel generators.
For each, we will give a list of input and output attributes each with their string
names and positional ordering. Negative positions denote position from the end
(-1 means last attribute, -2 means second last, etc.). Note that negative positions
are accepted by manipulators.
Please note that some of the more complicated kernels described here may
not be set in stone at this point in time, and may change in the future. Since
the Shader Algebra is a fairly new addition to Sh, these kernels are still being
developed and may not yet have the ideal interface for what they do.
5.7.1 Universal Vertex Shader Kernel
The shVsh kernel function is a generalized vertex program generator. It creates a
“universal” vertex shader that can generates many common attributes required
by fragment shaders. There are some construction parameters, but you can also
just generate a shader with this function and then specialize it, for instance to
discard the half vector or tangents if you don’t need them. Its definition is given
as follows:
template<ShBindingType B, typename T>
ShProgram shVsh (
const ShMatrix<4, 4, B, T> &MV, // MCS to VCS transformation
const ShMatrix<4, 4, B, T> &VM, // VCS to MCS transformation
const ShMatrix<4, 4, B, T> &MD, // MCS to DCS transformation
const ShMatrix<3, 3, B, T> &T, // texture transformation
int num_tangents = 0,
int num_lights = 1,
int use_scs = 0,
int provide_scs_frame = 0,
);
This function generates a program with the following inputs and outputs,
which are given these precise names:
Inputs: | 0: | ShTexCoord2f u; surface texture coordinate.
|
| 1: | ShNormal3f nm; normal vector (MCS). |
| 2: | ShVector3f tm; primary tangent (MCS); |
| | | only included if num_tangents > 0. |
| *: | ShVector3f sm; secondary tangent (MCS); |
| | | only included if num_tangents > 1. |
| *: | ShPoint3f lpvi; light position (VCS); |
| | | for i = 0...num_lights- 1. |
| -1: | ShPosition4f pm; vertex position (MCS). |
Outputs: | 0: | ShTexCoord2f u; transformed surface texture coordinate. |
| 1: | ShPoint3f pv; vertex position (VCS). |
| 2: | ShPoint4f pm; vertex position (MCS). |
| 3: | ShNormal3f nv; normal vector (VCS). |
| 4: | ShVector3f tv; primary tangent (VCS); |
| | | only included if num_tangents > 0. |
| *: | ShVector3f sv; secondary tangent (VCS); |
| | | only included if num_tangents > 0. |
| *: | ShVector3f vv; view vector (VCS). |
| *: | ShVector3f hv; half Vector (VCS); |
| *: | ShVector3f hvi; half Vector (VCS), |
| | | for i = 0...num_lights- 1. |
| *: | ShVector3f lwv; light Vector (VCS); |
| *: | ShVector3f lwvi; light Vector (VCS), |
| | | for i = 0...num_lights- 1. |
| *: | ShVector3f lpv; light position (VCS); |
| *: | ShPoint3f lpvi; light position (VCS), |
| | | for i = 0...num_lights- 1. |
| *: | ShNormal3f ns; normal vector (SCS). |
| *: | ShVector3f vs; view vector (SCS). |
| *: | ShVector3f hs; half Vector (SCS); |
| *: | ShVector3f hsi; half Vector (SCS), |
| | | for i = 0...num_lights- 1. |
| *: | ShVector3f lws; light Vector (SCS); |
| *: | ShVector3f lwsi; light Vector (SCS), |
| | for i = 0...num_lights- 1. |
| -1: | ShPosition4f pd; position (HDCS). |
If num_tangents is 0, then tv and sv are not included in the inputs. In this case,
no surface coordinate frame outputs will be included either. If num_tangents is
1, then only one tangent is given an input. In this case, sv is computed from the
normal nv and the single tv. All surface coordinate outputs are valid. If
num_tangent is greater than or equal to 2, then the first two tangents on the
input are taken to define a surface coordinate frame, the rest are just
transformed.
All other kernels in this section generate fragment shaders designed, generally,
to interact with this particular vertex shader.
5.7.2 Surface Shader Kernels
These kernels implement various basic lighting models at the fragment level.
These lighting models are actually defined in a coordinate-free manner and so.
as long as all vectors are consistent, vectors in the VCS, MCS, or SCS
can be used. To make it easier to plug shaders together, we drop the
coordinate system suffix from names when the coordinate system does not
matter.
Diffuse
The shDiffuse kernel function generates a fragment program for diffuse lighting.
This does not do much, it just passes through the interpolated diffuse color given
it on its input, after multiplying it by the irradiance color from the light source.
template<typename T>
ShProgram shDiffuse();
It creates an ShProgram with the following interface:
Inputs: | 0: | T kd; diffuse coefficient.
|
| 1: | T irrad; irradiance from the light source. |
| 3: | ShVector3f lw; light direction vector. |
| 4: | ShPosition4f pd; position (HDCS). |
Outputs: | 0: | T c; result color. |
The specular kernel is coordinate system independent, so n, h, and lw can be in
any space (as long as it is the same space for all three vectors).
Specular
The shBlinnPhongSpecular kernel function generates a fragment program that
computes a Blinn-Phong highlight.
template<typename T>
ShProgram specular();
It creates an ShProgram with the following interface:
Inputs: | 0: | T ks; specular coefficient.
|
| 1: | ShAttrib1f spec_exp; specular exponent. |
| 2: | T irrad; irradiance from the light source. |
| 4: | ShVector3f h; half vector. |
| 5: | ShVector3f lw; light vector. |
| 6: | ShPosition4f pd; position (HDCS). |
Outputs: | 0: | T c; result color. |
The specular kernel is coordinate system independent, so n, h, and lw can be in
any space (as long as it is the same space for all three vectors).
Blinn-Phong
The shBlinnPhong kernel function generates a fragment program that combines
the effects of the shDiffuse and shBlinnPhong kernels.
template<typename T>
ShProgram shBlinnPhong();
It creates an ShProgram with the following interface:
Inputs: | 0: | T kd; diffuse coefficient.
|
| 1: | T ks; specular coefficient. |
| 2: | ShAttrib1f spec_exp; specular exponent. |
| 3: | T irrad; irradiance from the light source. |
| 5: | ShVector3f h; half vector. |
| 6: | ShVector3f lw; light vector. |
| 7: | ShPosition4f pd; position (HDCS). |
Outputs: | 0: | T c; result color. |
The phong kernel is coordinate system independent, so n, h, and lw can be in any
space (as long as it is the same space for all three vectors).
Gooch
The shGooch kernel function generate a fragment program that computes Gooch
illustrative shading [?].
template<typename T>
ShProgram shGooch();
It creates an ShProgram with the following interface:
Inputs: | 0: | T kd; diffuse coefficient.
|
| 1: | T cool; cool multiplier, |
| 2: | T warm; warm multiplier, |
| 3: | T irrad; irradiance from the light source. |
| 5: | ShVector3f lw; light vector. |
| 6: | ShPosition4f pd; position (HDCS). |
Outputs: | 0: | T c; result color. |
The shGooch kernel is coordinate system independent, so n and lw can be in any
space (as long as it is the same space for both).
Identity
The shIdentity kernel generates a surface shader that does nothing, just copies
its irradiance to its output.
template<typename T>
ShProgram shIdentity();
It creates an ShProgram with the following interface:
Inputs: | 0: | T irrad; irradiance from the light source.
|
| 1: | ShPosition4f pd; position (HDCS). |
Outputs: | 0: | T c; result (copy of irrad). |
5.7.3 Light Shader Kernels
Light kernels are designed to be connected to the vertex shader outputs from a
universal vertex shader. Each outputs one irrad output representing the
irradiance at a surface of type T (usually ShColor3f).
Point Light Kernel
The shPointLight kernel builds a shader represents a point source.
template<typename T>
ShProgram shPointLight();
It generates an ShProgram with the following interface:
Inputs: | 0: | T lc; color and power of source.
|
Inputs: | 0: | T lp; position of source. |
Outputs: | 0: | T irrad; irradiance. |
Spot Light Kernel
The shSpotLight kernel builds a shader that has a linear falloff from the light
vector in the same direction as the given direction vector to zero at the falloff
angle.
template<typename T>
ShProgram shSpotLight();
It generates an ShProgram with the following interface:
Inputs: | 0: | T lc; color and power of source.
|
| 1: | ShAttrib1f falloff; angle in radians |
| | | where spotlight intensity begins to decrease. |
| 2: | ShAttrib1f angle; angle in radians |
| | | where spotlight intensity equals 0. |
| 3: | ShVector3f direction; direction light faces. |
| 4: | ShPoint3f lp; light position. |
| 5: | ShPoint3f p; surface point position. |
Outputs: | 0: | T irrad; irradiance. |
Projector Light Kernel
This light source projects a texture onto a surface like a slide projector (except it
does not itself handle shadows). This kernel is really a spotlight with a texture
instead of a fixed falloff function.
template<typename T>
ShProgram shProjectorLight(const ShBaseTexture2D<T> &tex);
It generates an ShProgram with the following interface:
Inputs: | 0: | ShAttrib1f scale; scaling on the texture (tiles).
|
| 1: | ShAttrib1f angle; angle in radians |
| | | for field of view of light. |
| 2: | ShVector3f direction; direction light faces. |
| 3: | ShVector3f up; up direction of light, |
| | | must be orthogonal to direction. |
| 4: | ShPoint3f lp; light position. |
| 5: | ShPoint3f p; surface point position. |
Outputs: | 0: | T irrad; irradiance. |
5.7.4 Surface Map Kernels
These kernels modify some surface property.
SCS Bump Map Kernel
This takes a 2D gradient vector (usually acquired from a texture lookup, where
the texture value in turn was obtained by differencing values in a height field)
and the base normal represented relative to the surface coordinate space. It
computes a perturbed normal represented relative to the surface coordinate
space. Note that we do not use the space suffix to make it easier to hook this up
to other shaders, but that it will only work with normals expressed relative to the
SCS.
ShProgram shBumpMapSCS();
It generates an ShProgram with the following interface:
Input: | 0: | ShAttrib2f gradient; gradient
|
| 1: | ShNormal3f n; normalized normal vector (SCS). |
Output: | 0: | ShNormal3f n; perturbed normal (SCS). |
Bump Map Kernel
This does the same thing as SCS bump mapping, but in an arbitrary space (such
as view space). It needs an explicit surface frame, because what it really has to
do is transform the perturbed normal from the surface coordinate frame back out
to the given coordinate frame. It computes the perturbed normal in the SCS then
uses those coordinates to create a linear combination of the vectors in the given
surface frame.
It generates an ShProgram with the following interface:
Input: | 0: | ShVector2f gradient; gradient vector
|
| 1: | ShVector3f t; normalized tangent vector. |
| 2: | ShVector3f s; normalized secondary tangent. |
| 3: | ShNormal3f n; normalized normal vector. |
Output: | 0: | ShNormal3f n; perturbed normal. |
All vectors should be in the same space.
5.7.5 Postprocessing Kernels
These are postprocessing kernels, which modify the output color in some way,
creating a new output color. Several postprocessing kernels can be connected
together to create a more complicated postprocessing kernel.
Simple postprocessing kernels take an input of type T and return one output
of type T named result. More complex postprocessing kernels might require
extra information, such as the texture coordinates of each surface point, or the
position.
Halftoning Kernel
The halftone function generates a kernel that performs halftoning/hatching
independently in each color channel. A texture provided as an argument is tiled
and used as a threshold image, / indexed by texture coordinates passed as
inputs. A value of 1 is output if the input is larger than the corresponding
component in the texture; otherwise, 0 is output. Intermediate values will
also be output for halftoning (the threshold is actually a smooth step).
template<typename T>
ShProgram shHalftone(const ShBaseTexture2D<T> &tex);
It generates an ShProgram with the following interface:
Inputs: | 0: | T c; output from previous set of shaders.
|
| 1: | ShTexCoord2f tc; texture coordinate for lookup. |
Noise-adding Kernel
The / shNoisify kernel function generates a shader that adds noise to some
attribute, such as a rendered image.
template<typename T, int N>
ShProgram shNoisify();
It generates an ShProgram with the following interface:
Inputs: | 0: | ShAttrib1f noise_scale; scaling on cellnoise.
|
| 1: | T c; value to be perturbed. |
| 2: | ShAttrib<N> tc; coordinate used for noise. |
Note: This manual is available as a bound book from AK Peters, including better formatting, in-depth examples, and about 200 pages not available on-line.