The Story Behind the 2007 Holiday Card

xmas (146K)






The image was created by a computer program that uses a computer graphics technique called ray tracing. I do my best to describe the technique here, in the 2006 writeup and here, in the 2005 writeup.

This year's card is very simple so I thought I'd show the actual script that results in the image you see.

The language of the scene description is C++. This is a computer programming language that is ideally suited to what is called "object-oriented" programming. Since the scene is a collection of objects, what better language to use...?

The scene:

The scene is made up of objects that are modeled by geometric shapes:

I start with a ground surface. It has to be 3-dimensional so I use a box. It's dimensions and position in the world are given by the positions of the diagonally opposite corners. It needs a color so I create a green texture and attach it to the box. Then I add the box to the scene.
Box* ground = new Box(Position(-100.,-1.,100.),
                      Position(100.,0.,-100.));
Texture* groundTxt = new Texture(ForestGreen);
ground->setTexture(groundTxt);
pScene->add(ground);

 

 

I create a simple ornament which is a Union (ie, a collection) of a ball and a stem.
The ball is a sphere. It gets a chrome finish texture except I change the color to red. The ball is added to the ornament.
Union* ornament = new Union;
Sphere* ball = new Sphere(Origin, 7.);
Texture* ballTxt = new Texture(T_Chrome_5E);
ballTxt->surfaceColor = Red;
ball->setTexture(ballTxt);
ornament->add(ball);

 

 

The stem is also a Union containing a ring to hang the ornament from and a collar where the ring and the ball join.
The collar is a cylinder positioned so that it sticks up out of the top of the sphere. It is added to the stem.
Union* stem = new Union;
Cylinder* collar = new Cylinder(Position(0.,6.,0.),
                                Position(0.,8.5,0.), 1.);  
stem->add(collar);

 

 

The ring is another cylinder lying horizontally across the top of the collar. The ring is made hollow (a tube) to allow a hook to pass through it and I turn it a little so it's easier to see. The ring is added to the stem.
Cylinder* ring = new Cylinder(Position(0.,9.,-.5),
                              Position(0.,9.,.5), 1.); 
ring->setInterior(GeoObject::hollow);
ring->rotate(0.,RADIANS(60.), 0.);
stem->add(ring);

 

 

I made the stem because I can change the texture, position or other characteristic of both the collar and the ring together by referring to the stem alone.
The stem is given a shiny gold color (which the collar and ring inherit). The stem is added to the ornament.
Texture* stemTxt = new Texture(T_Gold_5E);
stem->setTexture(stemTxt);
ornament->add(stem);

 

 

Now that there's one ornament, it's a simple matter to clone two more. Initially they all share the same characteristics including position. I move them apart and raise them off the ground. I add them to the scene (which is just another Union).
Union* ornament2 = new Union(ornament);
Union* ornament3 = new Union(ornament); 
ornament->move(-6.5, 10., 0.); 
pScene->add(ornament);
ornament2->move(6., 12., -40.); 
pScene->add(ornament2);
ornament3->move(-32., 15., -80.); 
pScene->add(ornament3);

 

 

Point light sources, spotlights and directional lighting affect the shading of a scene but they don't have any physical presence in the scene and have no shape. Lights are defined in the camera settings and are not part of the scene description.
I want a rectangular light reflected in the ornaments. To make any light source visible, it needs to be realized by a shape which acts as proxy for the light source. The named light and its proxy shape are associated by the meta object, ProxyLight, which is added to the scene.
Light* lightEmitter;
if (lightEmitter = pCam->lights->getNamedLight("boxlight")) { 
     Box* lightBox = new Box(Position(-40, 0, 40),
                             Position(40, 2, -40));            
     ProxyLight* boxLight = new ProxyLight(lightEmitter, 
                                           lightBox);
     boxLight->setAreaLight();      
     pScene->add(boxLight);         
     }
		 

 

 

After the image of the scene was rendered, I added the text using an image editing program.

 

The camera:

The camera settings are chosen interactively at rendering time. Below are screenshots of the camera dialog box used to create the image above. Click on a thumbnail image to see a larger view. Use your BACK button to return here.

Position
Position
ImagePlane
Image Plane
FocalLength
Focal Length
Lighting
Lighting
areaLight
Area Light
Dimensions
Dimensions
Processing
Processing
Mask
Tracing Mask

Return to Cards of Christmas Past