"Ray Tracing Quadrics"
Final Project for CPE 473-01/02
Mike Murray
Winter 2010
Project Description:
This project implements quadrics (e.g. cones, paraboloids, saddles, etc.)
as specified in the Pov-ray documentation. The quadric formula is:
F(x,y,z) = Ax2 + By2 + Cz2 + Dxy + Exz + Fyz + Gx + Hy + Iz + J = 0
Different quadrics can be created by passing in different values. Since
quadrics extend infinitely, a bounding box is formed around each to limit
the size. The Pov-ray specification does not designate such a constraint, so
instead of putting the bounding box in the source .pov file (which would allow
the user to create a bounding box for each quadric), there are #defines which
specify the XYZ limits in Quadric.h. The default is a cube with length 5 for
each side, but each dimension can be easily adjusted.
Quadric intersection was determined by calculating
Aq = Adx2 + 2Ddxdy + 2Fdxdy +
Bdy2 + 2Edydz + Cdz2
Bq = 2 (Apxdx + D(pxdy + dxpy) + F(pxdz + dxpz) + Gdx +
Bpydy + E(pydz + dypz) + Hdy + Cpzdz + Idz)
Cq = Apx2 + 2Dpxpy + 2Fpxpz + 2Gpx + Bpy2 + 2Epypz + 2Hpy + Cpz2 + 2Ipz + J
Where p + td compose the ray testing the intersection. The intersection points are the results of solving for 't' in Aqt2 + Bqt + Cq = 0. This can be done by simply using the quadratic formula.
To calculate the normal vector for the object, take the partial derivatives of F(x,y,z) (the quadric equation). This turns out to be:
(Ax+Dy+Fz+G, By+Dx+Ez+H, Cx+Ey+Fx+J)
Warning: Be extremely careful when implementing these equations. Though the math is not too challenging,
there are many variables (with similar names). One minor mistake could lead to an hour of debugging.
Example POV-ray quadric object:
// Infinitely large saddle upright on the X axis
// y^2 - z^2 - x = 0
quadric {<0, 1, -1>, <0, 0, 0>, <-0.5, 0, 0>, 0
pigment { color rgb <1.0, 0.1, 1.0>}
finish {ambient 0.2 diffuse 0.4 specular 0.5 roughness 0.05}
rotate <0, 0, -90>
rotate <0, -90, 0>
}
Other:
Some time was also spent repairing bugs from previous versions, such as
the color equation for refracted objects, checking for epsilon in the box
collision detection, and calculating correct normals for triangles. In older
versions, the order of formulation of triangle vertices determined which way
the normal would face, leading some scenes to render improperly. This was
corrected by using the same technique used by backface culling - only instead of
culling, we will reverse the normal. To figure out if the normal is facing the
viewer, take the dot product of the vector from the eye to the hit point and
the normal of the hit point. If the value from this is positive, then the
object's normal is facing away from the viewer and it must be reversed.
Rendered Images:
Note: Each image was created by feeding the appropriate equation into the POV-ray 'quadric' type.
Cone with limited XYZ extents
Cylinder
Ellipsoid
Hyperboloid
Paraboloid
Saddle
Elliptic Cylinder with Light Source Inside
Three RGB Spotlights Shining on a Sphere (formed by placing point-lights in cylinders)
Future Ray Tracer Work:
The original goal of this project was to implement photon mapping, but
due to the time constraints, it was put aside. Photon mapping requires knowledge
from many disciplines and requires great care when attempting to implement. With
such limited time, I could envision the nightmare and frustration of trying to debug it under pressure.
In the near future I hope to return to photon mapping and include it in future version
of the ray tracer. I read several papers by Wann Jensen (the father of photon mapping)
and his book Realistic Image Synthesis Using Photon Mapping. These sources are listed
below in the references section and will prove invaluable when I attempt to implement photon
mapping for a second time.
References:
The Complete POV-ray File Format Specification
Wikipedia Table of Quadrics
Quadric Intersection Determination
Quadric Surfaces PowerPoint
Global Illumination using Photon Maps
Realistic Image Synthesis Using Photon Mapping
Information About Backface Culling
Zoe" Wood's Home Page