Rendering Algorithms Final Project

"Sunset"

by Geoff Romer

Project Goal

The objective of my project was to render an image of a sunset, featuring clouds, a realistically colored sky, and volumetric light effects (a.k.a "god rays") from haze in the air.

Final Rendered Image

Renderer Features

Implementation/History

Ray marching

The main feature I had to add to my raytracer to achieve this image was the ability to simulate volumetric scattering effects. Traditional ray tracing models a scene as simply a collection of surfaces, and assumes that light travels in a straight line between those surfaces. To model effects such as haze in the air, however, we must take account of the way light scatters within the haze. Clouds, also, cannot convincingly be modeled as surfaces which reflect light, since much of their appearance derives from the way light scatters in their interior.

The basic technique for implementing volumetric scattering effects in a ray-tracer is called "ray marching", in which rather than tracing a ray through the entire distance between the eye and the nearest surface, we "march" the ray through the distance in small increments, simulating the effect of scattering at each step. In effect, this performs a numerical integration of the effects of scattering over the length of the ray.

The step sizes can either be uniform, or randomized. A uniform step size tends to produce a somewhat "layered" appearance to the haze, as though it were composed of a bunch of semi-transparent surfaces. Randomization eliminates these artifacts in favor of high-frequency visual noise. I opted for a hybrid method, in which the step length is randomized, but constrained to a certain (customizable) fraction of the total distance traveled, so that we are guaranteed a certain minimum number of steps (to ensure the image is somewhat accurate), and a certain maximum number of samples (to ensure the render does not take too long).

Above is an early test image, showing a sphere filled with a uniform volumetric haze. A light source is placed behind it, and a triangle between the light source and the haze casts a volumetric shadow through the haze.

Most real fogs, mists, hazes, and similar phenomena scatter light in a way that depends on the incoming light angle, for example scattering most light in a direction close to the incoming direction. The above image shows a test scene demonstrating this effect: the haze is now highly "forward-scattering", so that most light is scattered only a little from its original direction, resulting in the visible "glow" near the light source. Notice how this anisotropic scattering increases the realism of the image. Notice also how the haze not only scatters light, but attenuates it, so that away from the glow, the haze darkens the image visible behind it. This image uses the Schlick phase function to model anisotropic stattering.

This image shows a haze with non-uniform density- it is densest near the center of the sphere, falling off to zero density at the edges. The ability to vary the haze density is important for creating a convincing image of a cloud. Although it is not evident from this image, shadowing is not handled correctly yet; the haze is lit as though it had uniform density.

This image is a first attempt to approximate the appearance of a cloud. It uses a more complex density function to create a lumpy overall shape for the cloud, and much higher levels of scattering and attenuation to make the cloud appear more solid than previous images. The shadowing within the cloud is now correct.

A more sunset-like image of a cloud, with a yellowish-red light source behind the cloud producing a bright "halo" around a dark center, much like real clouds.

Perlin Turbulence

Real clouds, of course, are not well-modeled as a small collection of spheres with linearly decreasing internal density. A great deal of research exists on techniques for modeling clouds, but these techniques were generally to complex to implement in my timeframe. Instead, I chose to suggest the turbulent appearance of the cloud artistically, using a general "turbulence" function developed by Ken Perlin.

In essence, the turbulence function works by displacing the position used to calculate the local cloud density. The turbulence function is designed to give this displacement an appearance of being globally random, while keeping it locally continuous so that it does not appear as "noise"

This image is essentially the previous image, with the turbulence function applied (some lighting and scattering parameters have also been tweaked). The artificial "Mickey Mouse" appearance is gone, although the overall shape is similar. The speckling in some parts of the cloud is presumably a sampling error, which could be remedied by taking more samples ("marching" through the cloud in smaller steps). However, the primary drawback of Perlin turbulence is that it is slow to compute, and so with rendering times already multiple hours per image, I elected not to pursue this.

Sky Model

A sunset, of course, requires a sky. This could be faked with some sort of gradient as in the previous images, but this would probably not be convincing. Instead I elected to directly simulate the processes that give a sky at sunset its characteristic colors. In essence, the color of the sky is due to light scattering in the atmosphere by a process called Rayliegh scattering. This scattering is highly wavelength-dependent, so that blue colors are scattered all over the sky (which is why the sky is blue), while the red colors remain concentrated near the apparent location of the sun. This effect is exaggerated at sunset, when sunlight must travel a much longer distance through the atmosphere.

My original intent had been to build a sky model by solving the rendering equation analytically for a simplified model of the atmosphere, but this proved to be too time-consuming, although probably feasible, and so I fell back on numerical integration; effectively, more ray-marching. The details of the model are based on work by Mishima et al.

The results can be seen in the image below.

Putting it all together

This image shows all of the components combined into one image. This is a first attempt at the final rendered image.

Major Sources