Rendering Competition 2007/2008

Participant: Verena Marold
Name of the animation: Snowy
Video: Snowy


General information: Some facts about the scene:
  • modeled without any object files
  • animation consists of a camera movement
  • no super sampling due to the 10 minute / frame time limit
  • length: 37.1 seconds with 890 images (24 frames per second)
  • total rendering time for
    • low resolution (320 x 256): 6h 41min
    • high resolution (800 x 600): 39h 7min
    AMD Athlon 64 3400+ (2.4 GHz), 1024 Mb Ram
  • scene consists of:
    • 264 primitives:
      infinite plane, sphere, box, cone, cylinder and triangle are used
    • 1 object:
      the mountain comprises 32.768 triangles
    • 68 light sources:
      point lights were set using instant radiosity
Image:


Included topics

Overview
Bump Mapping Depth of Field Tone Mapping Motion Blur Fractal Geometry
Constructive Solid Geometry Procedural Shading Transparency Shader Multithreading Volume Rendering
Instant Radiosity Axis aligned box Sphere Cylinder Cone
Random Shader Normal Perturbation Transparent Eyelight Shader Transformation

Topic: Texturing - Bump Mapping (30 points)
Description: Until now, it is only possible to apply textures onto objects to add more realism into the scene. However, there is no way to simulate the roughness of surfaces. To change this, I implemented the method introduced in Blinn's Paper (pdf), stating how to adapt the normal vector of each point, to model surfaces.

Given the surfaces' normal vectors, I adapt them by lengthening or shortening them according to the information which is gained by a height map. This is a simple bitmap, in which the change of gray values determines the new normal vectors.

In my implementation, also colorful bitmaps are supported, which can result in nice structures.

Source Code: BumpMapping

BumpMapped PhongShader

BumpMapped EyeLightShader

Sources: A very helpful website on Bump Mapping
Effect seen in: On the three spheres in front of the mountain (> 14 sec)
Image:

Topic: Advanced Camera Properties - Depth of Field (20 Points)
Description: A depth of field camera helps us to simulate the fact that a real camera has only a finitely large lens. Objects in the 'right' distance, the so called focus length of the camera, are well discernible, but all other items, no matter if they are closer to the camera or further away, appear blurred.

To obtain this effect, I need to determine the distance of the ray with the projection plane. By shooting multiple rays, I am then able to achieve that rays with randomly chosen origin are focused on the same point on the plane, if the object is in focus.

Source Code: Depth Of Field Camera
Sources: How to compute two uniformly distributed random numbers
Effect seen in: You can see this kind of camera at the end of the animation. First, the plane of focus is moved from afar closer to the camera and at the same time, the aperture is slowly increased. When the small white snowman in the front appears pin sharp, the focal length stays fixed and only the aperture increases to create a blurred surroundings.
Image:

Topic: Advanced Camera Properties - Tone mapping (30 points)
Description: The result of the rendered images is not always satisfying, depending on how light sources are placed and colors as well as parameters of the different functions are chosen. To display the scene onto the output device as it really is, Ward has suggested a constant, which describes the ratio between the display and the world luminance.

I therefore have to determine the world adaptation luminance, i.e. the average color of all pixel. If I know the desired maximum display luminance, I can calculate the scaling factor by Ward's formula. By then multiplying the color of every pixel with it, I get a mapping from one set of colors to another.

To be able to adjust the brightness of the animation, after the images are created, I implemented the class ToneMappingAnimation. By getting the scaling factor of all files of format 'image_number'.png in a specified folder, the average of those can be easily computed and the images are rewritten.
On this way, you can additionally avoid that the images are scaled with different scaling factors.

Source Code: Tone Mapping

Tone Mapping for image sequences

Sources: Ward's Contrast Based Scale-factor
Effect seen in: the whole animation
Images: Original image:

By changing the maximum display luminance, we have an influence on how bright our final image is. As you can see, it gets brighter for small values and darker for larger values.

Topic: Advanced Camera Properties - Motion Blur (20 points)
Description: While recording scenes with a camera, the so called 'motion blur' effect can appear. This is another way, how blurred pictures can arise. But while e.g. for the Depth Of Field camera, all objects outside the focal plane appear blurred, here only moving objects are affected.

The effect is simple to implement, if one gives a start point and an end point for a primitive. The vector between these two points, a translation vector, then indicates the direction in which the object is moving. By randomly locating the object for every ray between the start and the end point, the blur effect is produced.

Source Code: Motion Blur for a Sphere

Motion Blur for a Triangle

Effect seen in: You can see this at the smoke of the cottage's chimney, see Volume Rendering (> 20 seconds).
Image: The left textured sphere and the right bumpmapped sphere are moving while recording.

Topic: Modeling - Fractal Geometry (50 points)
Description: By the help of fractal geometry we can create mountains.

The implementation is done by considering a square ABCD, which is first subdivided into two triangles ABC and ACD.

Both are then recursively divided into four smaller ones. For this, I cut the triangles' side into halves and combine the new gained points.

By adapting the height of these three midpoints, a fractal structure is created. Since doing this randomly has the disadvantage that I have to store the adaptations in order to get connected triangles, I use a fixed formula for these translations.

In first place, I compute the highest point, which is set by default to the center of the square. The point is then dislocated depending on its distance to the highest point in the direction of the squares' normal. In order to avoid too symmetrical mountains, I further modify the height by incorporating the coordinates of the point.

Source Code: Fractal Geometry
Sources: Fractal Landscape
Effect seen in: The mountain in the background of the three bump mapped spheres and the cottage (> 15 seconds)
Image: Here you can see some results of the implemented algorithm with different recursion depth and different highest points.


Topic Modeling - Constructive solid geometry (60 points)
Description: The constructive solid geometry (CSG) permits to create complex looking objects out of simpler ones. I can therefore use our already implemented primitives in order to combine them by boolean set operators (intersection, union, difference).

To allow an easy modeling, I get the necessary information (primitives' location, color, ...) out of a file whose format is based on the reverse polish notation . This is a stack-based notation, meaning that operands are pushed onto the stack and each (binary) operator takes two operands from it. After the computation, the result is put onto the stack.

Cones, cylinders, spheres, infinite planes as well as boxes are supported. They are saved in a binary tree, where each node either contains an operator or a primitive.
The supported operators are performed in the following way:

  • Union:
    For the union operator, the ray must hit at least one of the objects. The properties of the ray as well as the shader of the object are then determined by checking which object lies in front.
  • Intersection:
    The intersection is performed in a very similar manner, with the only difference that the ray must of course hit both objects if it is part of the final object.
  • Difference:
    For the difference operator, all points are of interest, which belong to the first but not to the second object.
    Here, we have to distinguish a few cases, depending on the objects' position.
    • It is possible that the ray misses the objects.
    • Further it may only hit one of the objects.
    • And in case that the ray intersects both objects, the outcome is determined by which object is left first.

And of course I compute the bounding box of the object, by going over the tree and taking, depending on the operator, the primitives' bounding box.

Source Code: Constructive Solid Geometry
Sources: Constructive solid geometry

Constructive solid geometry (german, pdf)

Effect seen in: In the animation, three objects are modeled with the CSG.
  • The first one is a blue box where four different colored balls are cut out at the corners box. (> 5 seconds)
  • The second one is a transparent object build up of three cylinders. (> 10 seconds)
  • And the last one is again a blue box, where a pink sphere, lying in its middle, is cut out. (> 14 seconds)
Image:
Difference Union Intersection Difference
Things you can do with CSG:

Pacman Dice

Topic: Surface Shading - Procedural Shading (30 points)
Description: In order to create realistic looking surfaces without the usage of texture files, I use simple functions as texture map. On this way I can for instance model wood or marble surfaces.
In first place the color of the surface depends on the position, thus on the hitpoint of the ray with the object. By generating noise, e.g. by using Perlin noise, I can finally avoid regular structures and thus I can make the textures more interesting.

I implemented a wood shader, a marble shader and a structured shader. Therefore I had to extend the given PerlinNoise class for 2D to 3D.

Source Code: Procedural shading

Perlin Noise

Sources: Description of how to implement a wood shader (pdf)

Formulas for other shading types (marble, fire, ...)

Effect seen in: The wooden sphere ( > 9 seconds )
Image:
Wood: Marble: Marble: Structure:

Topic: Surface Shading - Reflective and Refractive Transparency (30 points)
Description: Light is in reality refracted and reflected in different directions, just consider light passing through glass or through water. To imitate this behavior, I implemented the class TransparencyShader.

Thus initially, I had to compute the angle of reflection and the angle of refraction.
The first one is, as we already knew, the same as the angle of the incoming ray. For the angle of refraction, I make use of Snells law which states that the sine ratio of the angle of incidence and the angle of refraction has to be equal to a material depending refraction value.
Finally I use the Fresnel Term to come to know how much light is reflected, depending on the angle of view.

Source Code: TransparencyShader
Sources: Snell's law

Fresnel equation

Effect seen in: The transparency cones and cylinders.
  • The first transparent cone is directly at the beginning.
  • Further, there is a transparent cylinder build up by CSG. (> 4 seconds)
Image:

The initial screen:

Topic: Optimization - Multithreading (30 points)
Description: In order to accelerate the raytracing procedure, I can optimize the implementation. This can for example be done by implementing a good data structure, using a rendering cache or in the case of multithreading by taking advantage of multiple processors which work independently of each other.
Since my animation does not use any object files, I decided to implement this kind of optimization instead.

Thus the aim is to accelerate the processing of large amounts of data on computers with multiple CPU cores. For this purpose, I take advantage of the library pthreads, which already does a large part of the required computation.
I just need an additional class MultiThreading, which allows threads to access the same memory. Doing so, they can exchange data and this is, in our case, important to ask for the next line to render. In the main class, the threads are then created, joined and the image can then be rendered.

Source Code: Multithreading

MicroTrace

Sources: An introduction to threads (german)
Effect seen in: Unfortunately, it is visible in the final image.

Topic: Volume Rendering - Integrated Intensity Volume Rendering (40 points)
Description: As the name already indicates the corresponding implementation should create volumes, e.g. smoke. We therefore take a primitive and replace its shader by a transparency one, with a default transparency of 1.0 and no reflection.

By reason that a simulation of volume requires to modify the transparency level at some points, I recompute this value for every ray, depending on the hit point location.

Source Code: Volume Rendering
Effect seen in: The smoke coming out of the cottage's chimney ( > 22 seconds )
Image:
Bubbles: Smoke:
in the animation:

Topic: Advanced Light Transport - Instant Radiosity (60 points)
Description: To get more realistic images by more realistic illumination, I implemented the Instant Radiosity algorithm proposed by Alexander Keller. The point light and the quad area light implemented in class, create dark shadows. In order to get more smoothed ones, I shoot rays from the light source in all possible directions.

The mentioned paper states how to generate the Pseudo Random numbers of the Halton Sequence, to restrict the number of shot rays. Further it states how to create new light sources.

Source Code: Instant Radiosity
Sources: Instant Radiosity - Alexander Keller (Uni Ulm) (pdf)
Effect seen in: Since this algorithm takes very long, there are only some point lights set by it, but with the same intensity. But see below to see how smoothed shadows would be possible.
Image:
with no light: with point light:
with 149 light sources (different intensities): with 20 light sources (same intensity):


Topic: Additional part - Axis aligned box
Description: I implemented the GetNormal function for an axis aligned box, in order to display the outlines of this primitive.
The result must be one of the unit vectors, respectively minus one of the unit vectors, for each of the six sides. The calculation is done, by simply checking where the largest entry in the vector from the center to the hitpoint is. This indicates which side is hit.

In addition, I added the GetUV function for this box. During the exercises we only implemented this method for triangles, but it is also desirable to apply textures onto boxes.
To get the UV values, again the side which is hit by the ray plays a huge role. It pays off to compute the normalized vector from the hitpoint to either the min- or the max-vector, to get values in between 0 and 1. Those determine the UV values.

Source Code: Implementation of an axis aligned box

Effect seen in: all boxes in the scene
Image:

Topic: Additional part - Sphere
Description: As for the axis aligned box, I implemented the GetUV function for a sphere. This was important in order to get nice bumpmap structures and nice texturing.

The implementation was done by computing the spherical coordinates out of the cartesian ones. Like this I get values for the azimuth (between 0 and 2*&Pi) and the polar angle (between 0 and &Pi). After a small adjustment of the angles, I obtain the desired UV values.

Source Code: Implementation of a sphere

Effect seen in: all texured and bumpmapped spheres in the scene

Topic: Additional part - Cylinder
Description: Since the scene should not be modeled by object files, I needed another way to model tree trunks. The easiest way to achieve this, was to extend the primitives by another class for an (axis aligned) cylinder.

  • The first step was to plug the ray in the general cylinder equation x + y < r in order to obtain a quadratic equation which could be solved by the ABC-formula.

  • The resulting object is an infinitely long cylinder, which has to be reduced to a certain height. I can take the z-dimension into account now by restricting z to [-h,h]. Like this, I get a both-side open pipe.

  • The base areas can then be computed by intersecting the ray with an infinite plane going through the center of the base caps upwards, respectively downwards, and the unit vector in z-dimension as normal. If this hitpoint lies within the desired radius, the cylinder is hit.
In my implementation, the cylinder can be aligned along the three axes.
Source Code: Implementation of a Cylinder
Sources: A good description on how to implement a cylinder
Effect seen in: all cylinders in the scene ;)
Image:
  • The first image shows the infinite long cylinder
  • On the second image is the shortened cylinder. You can see at the shadow that the base caps are missing.
  • The final result

Topic: Additional part - Cone
Description: A cone is performed in a very similar way as the cylinder.

I take the general cone equation which is given by x + y = (h/r) * (z-h), where h is the height of the cone and r is its radius. Afterwards, we only have to plug in the ray and again solve the resulting equation by the ABC-formula. Depending on the hitpoints' position, I truncate the cone. If the object is hit, its y-coordinate must be between 0 and the height.

Again I now have to compute the base, which can be done in exactly the same way as for a cylinder.

Source Code: Implementation of a cone
Sources: Some general information on cones

How to implement a cone

Effect seen in: all cones in the scene
Image:

Topic: Additional part - RandomShader
Description: Since I was interested in how a random shader might look like, I implemented this class consisting of only a few lines and here you can see the result :).
Source Code: RandomShader

Effect seen in: This effect cannot be seen in the animated scene. Since the colors are chosen randomly, they will change from image to image, what looks quiet confusing.
Image: This object was modeled with the CSG by computing the difference of two cylinders (which yields torus) and combining some of them.

Topic: Additional part - Normal Perturbation
Description: By randomly changing the normal vector of a given primitive, we get a snow-like surface.
Source Code: Normal Perturbation
Effect seen in: On the snowmen, the floor and the tree.
Image: The left image is the original one, the right image is the one with snow effect.

Topic: Additional part - Transparent Eyelight Shader
Description: As the FlatTransparentShader was already given, I used this code to implement a transparent eyelight shader. This way, we can add textures onto a primitive using the EyelightShader.
Source Code: Implementation of the Transparent Eyelight Shader
Effect seen in: You can see this effect on the blue textured sphere next to the snowman ( > 3 seconds ) and on the red/orange textured sphere in the cottage ( > 22 seconds ).
Image:

Topic: Additional part - Transformations
Description: In the lecture we already implemented an axis aligned box. This was on the one hand preferable, since it allowed a straight forward implementation. But on the other hand, the positioning of the primitive underlies severe restrictions. The same yields for the cylinder and the cone.

To overcome this problem, I implemented a class allowing the transformation of primitives, such as rotation, scaling, translation and shearing. Therefore I need a matrix class (for 4x4 matrix), which supports the multiplication of a matrix with a vector, respectively the multiplication of a matrix with a matrix. Further, it should create the transformation matrix as stated in the lecture (pdf) .

The given primitive is then translated by first computing the inverse mapping which is given in a quite intuitive way, as for example a rotation by a can be reversed by a rotation of -a and so on.
I am now able to adapt the ray by multiplying this inverse with the ray position and respectively with the ray direction. Pay attention that translations do not affect the ray direction.

Finally, I can do the intersection of the primitive with the transformed ray.

Source Code: Implementation of the transformation matrix

Computing the inverse mapping

Doing primitive-ray intersection and normal computation

Sources: How to transform primitives.
Effect seen in: There are two translated objects in the animation.

  • The first one is the object consisting of two spheres, where the first one is scaled by a factor of two in x direction, and the second one by a factor of two in y direction.
  • In addition you can see a rotated box in front of the cottage which was first rotated by 45 around the x-axis and then again by 45 around the y-axis.
Image:
Scaling: Shear: Shear:
Rotation: Rotation: Rotation:


Textures: Textures were taken from:


Verena Marold, January 2008, Saarland University - All rights reserved