See more images in the galleryIntroduction
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.
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
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.
|Vase filled with milk at degree||Vase 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 +
Specular Transmission Map
|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 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.
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
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 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.Acknowledgments
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