See more images in the gallery


For our final project, we tried to render a glass vase crafted by Andrew Wiener which is shown on the left. We purchased this vase from the Rincon Hill Art Exchange as it looked deceptively simple, yet produced beautiful colorful shadows and caustics. Soon enough though we would learn that it is a Herculean challenge to get this object to render correctly on a computer screen.
In the following sections, we describe the steps we went through to achieve the stated goal. (Read the initial project proposal here).

Link to code and textures coming soon.

Data Acquisition

Looking closely at the vase, we can see that it is comprised of two main pieces. The outer layer is a clear thick coat of glass. The inside layer is very thin and composed of multicolored translucent and diffuse glass. This is where our main challenge lied: modeling a partially diffuse reflective, specular reflective and specular transmissive surface. Rather than modeling the vase as a single glass object with a texture map on it, we decided to model each layer separately. The outer layer was modeled as plane glass with a glossy (Blinn) specular reflection and specular transmission. The thin colored inner layer however we decided to acquire as a set of multiple material maps using the Stanford Spherical Gantry (link to Gantry). The setup we used is shown in here. We mounted the vase on the gantry, fixed the camera and light position such that no specular highlight was on the centerline of the images, then took an image for every 0.3 degree rotation about the objects center axis. We acquired the images in two steps. First we filled the vase with milk and then with black ink, taking 1200 image for each pass.

We took 2400 images rotating the vase through 360 degrees
Vase filled with milk at degree Vase filled with ink and coke

Problems Encountered Material Maps

Then we assembled our image maps by concatenating a 1-pixel wide center line from each image. This yielded  a 1200x480 wide map for the milk and ink run respectively. These textures form the basis of our inner layer material color calculation. The texture with black ink gives the diffuse reflectance of the inner layer, the white minus the black texture gives the specular transmission. Finally we brightened the milk run textured as a model for the specular reflectance map. These textures were then read in lrt as the inner layer's material properties for the purpose of shading calculations.

Diffuse Reflection +
Specular Transmission Map
Diffuse Reflection Map
Problems Encountered

For an alias free texture map we would have had to rotate the vase at 0.12 degree increments, which was prohibitively expensive in terms of time. Luckily though our map did not show any jaggies. This probably was due to the fact that the camera optics acted as a low pass filter blurring our image a bit. The final image maps looked great. 


As mentioned above, our model consisted of two surfaces. WE used lather NURBS surfaces built in 3DStudio Max and exported them as triangle mesh RIB file using Animal Logics free MaxMan. The output from 3D StudioMax contained vertex normals and texture coordinates as well. With a bit of coding in lrt’s file we were able to make lrt read all the information. Texture coordinates were generated by projecting cylindrical texture coordinates onto our vase model.

Problems Encountered

We didn't realize how finely tesselated of a model we needed. For shading calculations, normals were interpolated using Phong interpolation, so we got a very smoothly shaded vase in the final images. However, shadow ray and refraction calculations exaggerated the error due to coarse tessellation. In one of the final images the outer boundary of the dark shadow seems to be piecewise linear since shadow rays intersect with actual geometry. Caustics which are projected exaggerate this problem. Performing refraction calculations on a tessellated smooth object proved to be difficult. While in our calculation a ray is refracted "smoothly" about an interpolated normal, the intersection test still occurred against the actual geometry. Thus as the light passed through the glass interior, it would be directed as if the vase where round, however the displacement distance was set by the actual geometry which is a piece-wise linear surface. This is an inherent problem in ray tracing, which could be fixed by increased tessellation. However since we projected our caustics onto the floor or walls a small incorrect intersection delta would become large. Incorrect refraction would make parts of the scene appear in places in the vase where it should not. For example we would have part of the black surrounding included in the vase, were the inner and outer shells geometry diverged greatly from the objects shaded appearance. To ameliorate this problem we mounted the vase inside a enclose sphere. Also, it can be seen in figure ?? that our model didn’t stitch up properly, leaving a gap which causes a broken caustic ring.

Shading Calculations and Photon Mapping

Material properties were read in as textures and used in shading calculations. We modified lrt's Glass class to hold all the textures we needed. We also modified the getBSDF function for the Glass class to return all the required components (diffuse reflectance, glossy reflectance, specular transmittance etc etc). Normals were interpolated for smooth shading. A Fresnel effect was included using Schlick’s approximation

For our calculations, reflectance at the normal incidence was taken to be 4% as described by Stephen H. Westin

Problems Encountered

We encountered two main problems in the shading part. First, since two layers were modeled as different objects, some parts of the vase started to “self shadow” other parts, as can be seen below. Since glass is mostly transparent this self shadowing looks unrealistic. We avoided this by associating a AcceptShadowFlag with each object. Secondly, one of the inner layer's BRDF's component was diffuse reflectance. This diffuse layer is very thin an thus can be illuminated from the front and back. As a result we had to remove the SameHemiSphere test in the Lambertain reflectance f functions. The White strips for example actually are diffuse parts of the vase, and the looked too dark if not backlit. This is not the case in reality. Ideally, to correct this problem, we should have either included some ambient component, or included a Lambertian transmission component, but turning off the same hemisphere test worked just fine.

With hemispherical test
Diffuse Component is not backlit
Incorrect thin glass model
Object Self Shadows Final Correct Vase

Photon Mapping

The pinnacle of this project was to capture the beautiful colorful swirling shadows and caustics that the vase created on a diffuse surface. Since we were using a point light source, standard monte carlo sampling would have been prohibitively expensive for a completely noise free image. Since our scene was relatively simple (one or two matte surfaces with a glass vase) and most of the interesting features (color shadows and color caustics) were concentrated in a small region, photon mapping was an obvious choice. We generated a caustic photon map by emitting photons from a point light towards the caustics generating vase. First we obtained the bounding sphere of the vase and then took the projection of this sphere onto the unit sphere around the light source. This gave us the projected solid angle in which we needed to generate photons. Then we generated photons with directions uniformly distributed in this projected solid angle using the method described by Shirley (pg. 122, sec. 15.2, Sampling a Spherical Luminaire). This was an expensive computation, but it did give results far superior than random sampling the bounding sphere of the caustic generating object. Caustic photons were stored and terminated as soon as they hit diffuse surfaces after going through specular reflection or refraction.

Problems Encountered

lrt light power is not exactly the same as photon power. When we set light power and photon power to be the same we got highly over bright images. We adjusted the power balance experimentally until we got peleasing results. This process was long and tedious.  Secondly, determining the optimal number of photons for the density estimation and the maximum search distance required many attempts. As mentioned, we wanted sharp color caustics, which required us to take a limited number of photons in our density estimation. Taking too many would have resulted in blurry caustics and taking too few could generate too much noisy. Since we really wanted to show the beauty of the crisp swirling color caustics, we used a low number of 25 photons for the density estimation. Consequentially we had to generate a high number of photons. Four our final images we generated and stored about 4 million photons.


This project would not have been possible with out the great help and support of the following people

Created in June 2002 by Inam Rahman and Georg Petschnigg