overview | images | implementation | downloads
Brown Texel
A single texel used to model uniformly thick body fur. The fur shader produces self-shadowing, as shown on the right side of the texel. Self-shadowing plays a key role in the appearance of furry surfaces. |
|
Multi Texel
A single texel rendered using multiple shaders. The first shader consists of short, dense, dark blue fur. The second shader represents long, sparse, light blue fur. This multiple-fur-coat approach is useful in creating a slightly noisier texel and also helps to avoid a brushlike appearance when replicating a single texel across a surface. |
|
Light Texel
A single texel rendered using very low optical density. The optical density is a coefficient that relates local volume density to attenuation. The lower the optical density, the more transparent the texel becomes. Height noise was also liberally applied, resulting in hairs of noticeably different lengths. |
|
Carpet Patch
A patch of brown carpet viewed closely under an intense light. The surface was created by replicating the brown texel (above). |
|
Red Carpet (1)
A piece of red carpet illuminated using two point light sources placed overhead. The vertex normals are perturbed so that the carpet hair appears to lean away from the eye. Click here for a high-res image. |
|
Red Carpet (2)
The same as above, except that the carpet hair now leans toward the eye. Due to the location of the light sources, the surface of the carpet is shadowed a bit more in this image. Click here for a high-res image. |
|
Blue Furball
A simple furry ball rendered using the Multi Texel, above. The normals are biased to make the short hairs point downwards. Although the hairs are intended to be distributed uniformly over the surface, noise is added to both the height and orientation of the texels to avoid a porcupine-like appearance. |
|
Furry Donut
A furry donut (dorm food, anyone?). The fur was rendered with two shaders: one using the Brown Texel (above), and the other using a brighter, longer, and more transparent variant of the Brown Texel. Click here for a high-res image. |
Implementation
My work consists of two programs: makefur, used
to generate texel shaders, and a modified lrt, used to
render furry surfaces. I will describe makefur first.
makefur
makefur reads an ASCII texel description file
and generates a binary shader file. Here is a sample description
file brown.desc:
40 40 40 | // dimensions (x y z) | |
1.0 0.5 0.0 | // color (base_r base_g base_b) | |
0.0 0.0 0.0 | // color noise (noise_r, noise_g, noise_b) | |
0.6 | // hair density (hd) | |
0.8 0.2 | // height (base_h noise_h) | |
0.3 0.3 | // thickness (base_t noise_t) | |
0.0 0.0 | // currently unused | |
50 | // optical density (od) |
The above description file was used to generate the brown texel shader (the first image above). The output file was generated by running the program as follows:
makefur brown.desc brown.tex
In general, makefur will generate a single shader with the following properties:
I was hoping to implement the Poisson distribution as suggested
in the Kajiya paper (instead of using simple dart throwing),
but unfortunately did not have time. Another unimplemented idea involved
some sort of fur curling by tracing a particle upwards through the
volume from the base, guided by a perturbed tangent vector.
lrt
My additions to lrt include code to ray trace arbitrary
triangular texel volumes and integrate the light scattered towards
the eye along this ray. The primary features are:
* |
Triangular texels. lrt casts rays to intersect texels with triangular bases
(as opposed to the rectangular volume described in Kajiya's paper).
This is shown in the diagram below.
This means that lrt can now apply fur to any triangle mesh. I experimented by modeling various blobby NURBS surfaces such as the ones below, then converting them to triangle meshes before rendering them in lrt.
|
|||||||||||||||||||||||||||||||
* |
Multiple shaders per texel.
lrt can apply an arbitrary number of custom-defined
texel shaders to each texel on a given surface. This is useful
for simulating two coats of fur, as described in Kajiya's paper.
The furry donut and furball, above, were each rendered using
two shaders.
|
|||||||||||||||||||||||||||||||
* |
Simplicity and flexibility.
Adding fur to a surface is pretty easy. To use the fur
integrator, add the following line at the top of the RIB file:
Option "render" "integrator" "fur_renderer" For each surface that you want to apply fur to, add the line before the primitive: Surface "fur" "texel_shader" shaders where shaders is a string containing a space-delimited list of shader files generated by makefur. For example, specifying "brown.tex" will apply the brown texel shader to every texel for this surface. Specifying "brown.tex lightsparse.tex" will apply both the brown and lightsparse texel shaders to every texel for this surface. The user can customize how the fur is applied to the skin. Parameters in the RIB file allow the user to specify, per surface, the height of fur texels, sampling density, and normal biasing (useful for achieving combed or smoothed fur effects). The available parameters are listed here:
For example, the line Surface "fur" "texel_shader" "brown.tex" "fur_sample" 0.01 "fur_height 0.4" "fur_normal_bias" [0.0 -0.2 0.0] says to apply the texel shader "brown.tex" with sampling spacing 0.01 (high quality), a uniform fur height of 0.4 units, with fur biased downwards (negative y-valued normal noise). |
FurIntegrator |
Performs a mix of conventional Whitted ray tracing
and texel rendering.
|
||
FurSurface |
Applies user-provided texel shaders to a surface.
The rendering algorithm described in Kajiya's paper
is implemented here.
|
||
FurryMesh |
Given a standard triangle mesh, computes averaged
vertex normals and builds
texel volumes according to various user-specified
parameters, such as height, normal bias, and noise.
|
||
FurryTriangle | Represents a single 3D volume to which texel shaders are applied at render time. Given a ray O + tD, computes the values of t at which the ray enters and leaves the volume. Also maps points (x, y, z) inside the volume to coordinates (u, v, s) in texel space. |
project | Source code for makefur and modified lrt. Includes sample RIB files and texel shader (.tex) files used to generate the images above. |