Stochastic Ray Tracing!
Here are the images:
(in uncompressed JPG instead of PPM for PC compatibility)
:
The first two images are the chrome spheres scenario from model1.c; initially
with specular power = 30 and then = 10. Both images have soft shadows enabled
as well (with the extended light source having radius 2.0 and 2.5) ,
and a brick texture on the large triangle that has replaced the plane
from program 1.
The third image is the glass ball and red ball scenario from model2.c;
the viewpoint is changed and a slight translucency (0.9) is introduced.
Note that here all lights are point sources and shadows are sharp.
The fourth image has a lot more translucency, thus the image of the texture on the plane looks highly blurred and distorted in the glass sphere on the left (and clear in the metal sphere on the right).
Effects implemented (and how):
- Texture mapping of triangles whose U,V coordinates are specified.
I calculate the color of the texture map at a point on a triangle by
linearly combining the (U,V) values at the vertices, weighting each value
by the value of barycentric coordinate for that vertex at that point.
- Antialiasing (removal of jagged edges) by oversampling by a factor of 64 (using an 8x8 jittered grid) for each pixel.
- Soft Shadows are done by shooting a randomly perturbed light ray so that it hits a point on the (spherical) light source. To better distribute rays, I implement a form of importance sampling by taking more samples in
areas where they contribute more, and then simply averaging them instead of Monte Carlo integration.
For this purpose I take a random point in the grid and map it to a point on the projected area of the light source, sampling using a function (1-u)^2 * theta_horizon that
approximates a probability of any theta being chosen being proportional to
cos(theta), between theta=0 and theta_horizon, the angle made by the tangent to the light source. The shadow looks kind of grainy at the edges instead of
really soft, though. We might attribute that to the inaccuracy of the importance sampling function or not enough samples being taken per pixel.
One trick used to speed things up is (suggested by Kenny Hoff) to oversample the eye ray to a pixel by a large amount, and then not shoot multiple rays for shadow feelers, reflection or refraction but shoot one
ray, probabilistically perturbed by a random amount. The jitter already introduced at the oversampling stage will create all the effects we need (by averaging a range of colors created by choosing different directions for the rays).
This saves us from an exponential growth in tracing time for every level of
recursion.
- Glossy Reflections are done by perturbing the reflected ray direction by a distribution (source: Ray Tracing News Vol 12, 1999) that approximates the Phong illumination model. This distribution is:
cos(theta)=pow(u,1/(spec_pow+1)) ; phi = 2*PI*v (u,v) E jittered grid
- Lastly, translucency (blurry transparency) is done by perturbing the
refracted ray in a similar way, except that the distribution is uniform in
theta as well as phi, and it is scaled to make sure the refracted ray does not bend to the other side of the normal. Coefficients R and T (reflectivity and
transmissivity) are used to calculate the contributions of reflected and transparent rays as before.
Problems
- Soft shadows seem a bit grainy & their intensity is less than the intensity of comparable sharp shadows. This could be attributed to the hacked distribution mapping (1-u)^2 * theta_horizon which only has a similar behavior to the
function we really want (whose probability of choosing angle theta is proportional to cos(theta), and which can be evaluated by doing a messy integral).
- Antialiasing of textures is not perfect, artifacts sometimes appear. May need some magnification filter to be applied to get rid of this.
- There is some confusion in how to combine diffuse lighting and texturing.
Should one add the texture to the ambient component and then diffuse-light
the material? Or only to the diffuse component (in which case shadow regions have no texture, very unrealistic)? Or should texture color be modulated (multiplied) with the result of diffuse lighting the ambient component? This last
is what I've done - there are nice shadows in the textured regions, but the
softer shadows almost fade into the background. This splits the texture up
into ambient and diffuse components, each of which is then modulated with the
material's color. Instead of modulating we could have replaced the color also (similarly to OpenGL's GL_DECAL setting).
Code
A copy of the code for the ray tracer (in C++) can be found in this directory.
Page created by Deepak Bandyopadhyay 10/3/2000 04:24AM EDT,
last updated 10/3/2000 04:39AM EDT.