Our goal was to realistically render sashimi. Right now, using pbrt, we can't render the subsurface scattering of light that occurs in raw fish. Also, we can't get the veins of the fish to look correct unless we were to use image texture maps, which are inflexible and hard to generate.
To implement Jensen et al's algorithm for subsurface light transport, we started off by defining a BSSRDF class that inherited from BSDF and encapsulated the extra parameters required to describe a translucent material. Finally, to this BSSRDF we added a FresnelBlend BRDF to give us the ability to render the glossy, oily surface of fish.
To make use of this BSSRDF class, we defined a new integrator that was responsible for subsurface light calculations. The new BSSRDFIntegrator basically used direct lighting calculations for all materials that weren't translucent. Translucent materials were also lit using direct lighting, but we added the single & multiple scattering terms from the Jensen paper. So, for each lit point, we calculate both scattering terms (using the analytic solution for single scattering and the dipole approximation for multiple scattering) and then add the glossy term from the BRDF on top of that. These terms are weighted equally in determining the lighting at the intersect point.
Calculating the scattering & absorption parameters for our salmon
& tuna materials was an extremely time intensive process that involved
a lot of trial and error (more error.) It was difficult to get both the
color and amount of translucency correct -- deeper colors scattered less,
so it was especially difficult to reproduce the dark purplish color of the
|Procedurally Generated Vein Textures|
The veins on the fish are generated procedurally as a solid texture. Parameters in the scene file allow the user to specify the normals of the planes along which the veins should appear, as well as the spacing between them. The veins are then generated as splines centered along those planes. The points around which to interpolate the spline are generated from user-specified parameters with some perturbation from Perlin noise.
In order to determine the texture at a particular point, the fish is sectioned into different slices, with one spline per slice. The noise for the spline is based on which slice on the fish that the point is in. We generate the spline for the particular depth in the object of the point, and then test to see whether or not our point falls on the spline. The thickness and spacing of the veins is also randomly perturbed using Perlin noise. Overall, the noise factor ensures that different veins on the same fish, and the same vein on different fish vary slightly.
This solid texture was applied as the scattering texture for the fish,
so we were able to specify opaque veins within the translucent
To generate the models, we used AC3D. Our meshes were quite simple, but the translucency, textures, and specular reflection smoothed out some of the sharp edges somewhat. Also, we used the built-in pbrt FBm texture as a bumpmap for the fish to generate the slightly rough appearance.
This is what we started off with, using pbrt's translucent material plugin. The translucent side is the side facing the camera, and the spottiness is caused by the decision at each pixel whether or not to let light transmit through.
This is an image of a wax-like block using our subsurface surface algorithm. We used an area light in a vacuum, so the sides aren't well-illuminated.
Stripes on a block, to demonstrate our procedurally generated solid texture.
This picture demonstrates the effect of bump mapping, some scattering, and some veins. It resembles wrinkled skin, we think, but this shows what we could do just by changing parameters.
This is our final image. The tuna isn't as translucent as we would have
wished, the color's a little off, and there are some dark spots where
there shouldn't be thanks to the models and the fact that we used an area
light instead of an infinite light, but everything's there. For
comparison, here's our picture with none of our added effects, just our
meshes & lighting:
|Conclusions & Comments|
Looking at our final image, there are some things that we could have
done with extra time that would have improved our image. The first is
finding better coefficients to produce more realistic colors &
scattering in our fish. As we mentioned above, it was very difficult to
get coefficients that were even close to the correct color, so knowing
these numbers would enable us to produce a far better picture.
Additionally, experimenting with the parameters defining the veins might
have produced more natural variations.
David S. Ebert, Texturing & Modeling: a Procedural Approach, 3rd