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:

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);
equals hv0.
*: ShVector3f hvi; half Vector (VCS),
for i = 0...num_lights- 1.
*: ShVector3f lwv; light Vector (VCS);
equals lwv0.
*: ShVector3f lwvi; light Vector (VCS),
for i = 0...num_lights- 1.
*: ShVector3f lpv; light position (VCS);
equals lpv0.
*: 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);
equals hs0.
*: ShVector3f hsi; half Vector (SCS),
for i = 0...num_lights- 1.
*: ShVector3f lws; light Vector (SCS);
equals lws0.
*: 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.
2: ShNormal3f n; normal.
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.
3: ShNormal3f n; normal.
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.
4: ShNormal3f n; normal.
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,
when l|n = -1.
2: T warm; warm multiplier,
when l|n = 1.
3: T irrad; irradiance from the light source.
4: ShNormal3f n; normal.
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.


ShProgram shBumpMap();
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, / E  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.
Outputs: 0: T c; result

Noise-adding Kernel

The / E  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.
Outputs: 0: T c; result


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.