See more images in the gallery
Introduction
For our final project, we tried to render a glass vase crafted by
Andrew Weiner 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.
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.
|
filled with milk |
filled with ink and coke |
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 + |
Diffuse Reflection Map |
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 api.cc 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 tessellated 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 exaggerated 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.
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 . Normals were interpolated for smooth shading. A Fresnel effect was included using Schlick’s approximation
![]()
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 |
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.
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 pleasing 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.
AcknowledgmentsThis 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