MP1 Glassware

Handin info

Spring 2006 Gallery

Spring 2005 Gallery

Spring 2004 Gallery

Spring 2003 Gallery

Spring 2002 Gallery

Spring 2001 Gallery

The goal of this machine problem is to understand and code up the intersection of a ray with (1) a composite object modeled using constructive solid geometry on primitives, and (2) an algebraic surface of arbitrary degree. These ray intersections will need to be written into a ray tracing system to generate images

You should write a ray tracer from scratch that supports refraction, CSG and algebraic surfaces. The ray tracer should cast shadow rays but for now it is ok if a glass object casts a dark shadow (as if it were opaque for the purposes of shadowing other objects).

Model an original piece of glassware using CSG operations on algebraic surfaces. For example, a glass is as simple as a cylinder, truncated by intersecting it with two planes, and hollowed by subtracting a paraboloid. You should also include a high degree algebraic surface in your scene. I'd like to see how creatively you can design drinking glassware, but other glass sculptures are also acceptable.

You will need to use robust methods for finding roots. Source is included here for the Graphics Gems I chapter on using Sturm Sequences to isolate the roots of a polynomial, by D.G. Hook and P.R. McAree. Once roots are isolated, you will need to refine them using either Newton's method, regula falsi or simple bisection. Code for finding the roots of a quadratic, cubic and quartic polynomial is provided here but I would like you to be able to intersect arbitrary algebraic surfaces.

I recommend you first implement refraction on something simple like spheres. Then implement CSG on spheres. Then implement more general algebraic surfaces.

Grades will be assigned according to the following scale:

My primary grading activity will be to look at the pictures (I'll check source only if I feel I have to). This means your pictures should demonstrate that you can cast rays correctly, intersect with algebraic surfaces correctly, etc. It would be wise to have notes with each picture explaining what the picture demonstrates and why.

The program is due:

10:00am, Monday,  11 Sep 2006.

The late penalty is 10% per day with a maximum of 5 days late


For those of you who want to use/modify the ray tracer from last semester's graphics course, look here for the CS318 mp4 code and libraries . There is an included makefile (for Unix/X11) that works on the csil-sunb xx machines (I have not tried the csil-sunaxx machines).

A version of the cs318 ray tracer starter kit that uses libgfx but not FLTK is available here . This version uses GLUT which doesn't have as many features but is a lot more portable.


Here is how to compute the normal of an algebraic surface. The algebraic surface is defined implicitly by a trivariate polynomial

f(x,y,z) = a + b x + c y + d z + e x^2 + f xy + g y^2 + h xz + i yz + j z^2 + ...

We find the intersecion by plugging the ray equation r(t ) = (x0,y0,z0) + t (xd,yd,zd ) into f, resulting in f(r(t)). You will find values t0,t1,t2,... that correspond to ray intersections with the algebraic surface. Let x0 = r(t0) be the first of these intersections.

The surface normal at x0 is given by the partial derivatives of f with respect to the coordinates. Hence N = (df/d x,df/dy,df/dz). This value is called the gradient of f at x, and denotes the direction of greatest change in f. Note that this is different than parametric surfaces (whose surface normal is df/du x df/dv). For the above equation, its partials are

df(x,y,z)/dx = b + 2 e x + f y + h z ...
df(x,y,z)/dy = c + f x + 2 g y + i z ...
df(x,y,z)/dz = d + h x + i y + 2 j z ...

If you implement an general method for representing trivariate polynomials, you will also need to implement a method to compute its partial derivatives. Partial derivatives can also be estimated using forward differences for arbitrary functions as

df(x,y,z)/dx = (f(x+h,y,z) - f (x,y,z))/h.
df(x,y,z)/dy = (f(x,y+h,z) - f ( x,y,z))/h.
df(x,y,z)/dz = (f(x,y,z+h) - f ( x,y,z))/h.

for some small positive h but the result is only approximate and this approximation can be problematic in some cases.



Here is an example ray intersection derivation for the cone defined by

f(x,y,z) = x^2 + y^2 - z^2.

You need to plug the parametric ray

x = x0 + t*xd,
y = y0 + t*yd,
z = z0 + t*zd

into the function, which will yield

(x0 + t*xd)^2 + (y0 + t*yd)^2 - (z0 + t*zd)^2.

Then you need to collect terms with similar powers of t, into

(xd^2 + yd^2 - zd^2)*t^2 + 2.0*(x0*xd + y*yd - z0*zd)*t + (x0^2 + y0^2 - z0^2).

That puts the equation into A t^2 + B t + C form to solve as a quadratic.


The field of graphics has had a chronic problem with the formula for a torus. Pat Hanrahan's solution in "An Introduction to Ray Tracing" had an error. Eric Haines and Larry Gritz came up with a different solution but there's too had an error. Here is the updated solution, from Ray Tracing News 3(7) :

A = (xd^2 + yd^2 + zd^2)^2
B = 4*(x0*xd + y0*yd + z0*zd)*(xd^2 + yd^2 + zd^2)
C = 2*(xd^2 + yd^2 + zd^2)*(x0^2 + y0^2 + z0^2 - R^2 - r^2) + 4*(x0*xd + y0*yd + z0*zd)^2 + 4*R^2*zd^2
D =  4*(x0*xd + y0yd + z0zd)*(x0^2 + y0^2 + z0^2 - R^2 - r^2) + 8*R^2*z0*zd
E = (x0^2 + y0^2 + z0^2 - R^2 - r^2)^2 - 4*R^2*(r^2 - z0^2)

These are the coefficients for the quartic At^4 + Bt^3 + Ct^2 + Dt + E.

You could use the fact that the ray direction is unitized to replace xd^2+yd^2+zd^2 with 1 but doing so prevents you from transforming the torus by applying the inverse transformation to the ray. While translations and rotations do not affect ray direction length, scaling does.