Final Project: Lava / Molten Material
Project Goal
Implementation
- Black Body Illumination
A true black body is an ideal diffuse radiator -- it emits light and absorbs all incoming light. Lava and other molten metals do emit an approximate black body spectrum. The black body power distribution function at each wavelength is specified completely by the temperature of the material.
Therefore, to determine the emitted light from a point on a surface of a given temperature, we integrated the product of the black body power distribution function and the XYZ response functions over the visible spectrum to end up with an XYZ color representation of the spectrum. This XYZ color was converted to RGB for use as the emitted light of an area light.
- Procedural Texturing for Temperature Lookup:
- Surface Shading:
As mentioned above, a black body radiator absorbs all incoming light. However, no materials are ideal black body radiators; as lava cools it becomes reflective. Looking at our reference images, we saw a broad specular highlight and a bumpy surface on the parts of the lava that had solidified. We decided to approximate this appearance by using a Blinn microfacet distribution with a high degree of roughness and a bump map. However, we wanted to correlate the reflectivity of the surface with the temperature -- high temperatures would be less reflective -- so we provided configuration parameters for smoothly transitioning the weight of the BSDF through a temperature range.
- Importance Sampling the area light source:
Our Lava Light was based off the Area Light implementation in PBRT. The default Area Lightassumes that the light source will emit light uniformly across its area, so it samples the shape uniformly by area -- choosing larger polygons more often in proportion to their areas. Because our light source does not emit light uniformly by area, we wanted to sample according to a different distribution that would be preferential to triangles which emitted more power (even if they were small).
To compute a sampling distribution, we extended the Shape Set to compute a Monte Carlo estimate of the power emitted per triangle. Then we built a CDF based on this. Then we changed the Sample method to choose a triangle based on the CDF of emitted power of a triangle rather than the area of the triangle, sampling uniformly across the selected triangle to choose the final sample point.
In the standard Shape Set, the base PDF is 1 / Total Area, because they have sampled uniformly by area. That is converted to a distribution per solid angle by using the dw/dA relationship. In order to return a proper PDF for our samples, we wanted to start with a base PDF of 1 / Total Power because we have sampled uniformly by power.
We need to convert that to an area distribution in order to continue using the dw/dA relationship to change variables to a solid angle distribution. The relationship dPower/dA is constant over a particular triangle, and is defined by Power of Triangle / Area of Triangle. So, given a particular triangle, we can compute dPower/dA and multiply by 1 / Total Power to get a weighting by area; then multiply by dw/dA to convert to solid angle.
Final Images
Challenges / Interesting Investigations
- Color representation of black body spectrum:
Our initial implementation of the black body code had a bug which made the emitted power far far too low for what PBRT was expecting. This led to a wide range of investigations trying to find out what techniques were used for color representation of black body radiation.
First, there are many black body radiation color-temperature gradients on the web. Here is an example: <example image>
However, these gradients are created by "self-normalizing" the color returned by the black body spectrum integration -- divide each of the XYZ color values by the sum of the XYZ values for a particular color. This means that you can represent the colors nicely, but it does not represent the intensity of the color properly at all. The emitted power of a black body increases as temperature4, so higher temperatures are orders of magnitude brighter than lower temperature, and the color gradients do not represent this. For instance, 1500K should be bright yellow, but the color gradients expect it to be orange.
The paper "Physically Based Modeling and Animation of Fire" by Nguyen, Fedkiw, Jensen called uses the black body radiation method as well, and then uses a von Kries transform to approximate chromatic adaptation. They assume that the fire in their scene is the primary illuminant, and use the von Kries transform to scale all colors to the color of the maximum temperature. This has the effect of saturating the color of the maximum temperature to white, which might be an okay idea for fire; but it does not apply well to lava or molten metal. For instance, we wanted to be able to represent metal at 800 kelvin, which should be a dark red. If this was the only illuminant in the scene, adapting to it would force it to white, which is really not correct.
The paper "Extending the Photon Mapping Method for Realistic Rendering of Hot Gaseous Fluids" by Kang, Ihm, and Bajaj, does two interesting tricks with the black body spectrum:
- 1. If they are looking for a particular color, they compute the temperature for which the maximum intensity is at a wavelength near that particular color, and then run their simulation at that temperature
- 2. Additionally, they allow artists to specify the range of wavelengths over which to evaluate the black body radiation, which biases the resulting color.
We chose not to apply either of these techniques because we wanted to base our results off a reasonable temperature for the materials we were looking at, instead of choosing a color and matching it.
As it turned out, our black body code just had one of the constants off by scale factor (m2 instead of nm2), which threw off the whole computation when it was divided by wavelength5. Going over the code in detail found this error and made the resulting Le in the right range and color.
- SPARKLES!
For a long time during development, we would get a number of VERY VERY bright pixels. We noticed that this problem was especially bad at the intersection of a light shape with a non-light-shape, although sometimes they would appear on the surface of the light shape itself. It turned out that the distance between the shading point and the light emitting point was so small that the PDF returned by the light was very close to 0 (but not quite zero), and was causing the returned radiance to be super high. We worked around this by changing the PDF computation to ignore rays where the distance squared was too near to zero and would cause these horrible sparkles.
Future work