By making primitive types transformable and keeping track of all ray intersections (in and out) of primitives, CSG primitive types of union, intersection and difference were added. The image shows from left to right: union, intersection, cube difference with sphere, sphere difference with cube.
A very basic grid-based anti-aliasing method was employed. Rays are shot in a 5x5 grid for each pixel. This makes the pixel edges appear less jagged and harsh.
Textures are mapped to all basic primitives based on where the ray collides with the primitive. Flat surfaces map to positions on the texture based on the distance from a fixed corner. For round surfaces, the angle from the corresponding axis is used to determine the value of appropriate coordinate to lookup colours on the texture.
Cones and cylinders were added as additional basic primitive types.
Transparency was added by adding an additional transmittence property to materials. When rays collide with with such materials, an additional ray is fired through the material at an angle determined by the index of refraction of the material.
Glossy reflections were created by adding a roughness property to materials. When rays collide with a rough material, the reflected ray is perturbed randomly by an amount determined by the roughness. When multiple rays collide with the surface, the appearance of glossiness is given.
Glossy transmissions are implemented similarly to glossy reflections. Transmitted rays are perturbed randomly by an amount determined by the roughness of the material.
By making lights spherical (rather than just a single point), soft shadows were added by picking a random point on the spherical light and casting a shadow ray from the object to that random point. This simulates what would happen if a object is partially blocked from light sources and creates softer shadows.
Caustics and indirect lighting can be created using a Monte Carlo method of shooting rays from each point when colliding with diffuse materials. Assuming light mostly comes from the direction of the light sources, noise can be greatly reduced by shooting rays only within a certain set of angles about the direction of each light. These rays keep bouncing until they are able to reach a light, in which case we record the light contribution from that light.
Caustics can be achieved this way since we would normally only expect the rays pointed directly at the light to reach that light source. If more than just those rays eventually reach light sources, it must be the case that light is focussed at that point. Hence, the light shown there is adjusted to be much stronger.
In the sample scene, a light is emitted from inside a glass container. With the original ray tracing technique, shadow rays are unable to reach the light source, since the glass blocks the rays. This is clearly very unrealistic. Using the Monte Carlo method, rays are cast in the direction of the light source, are then refracted and finally reach the light. Caustics are also visible below the glass objects surrounding the light source.
The final scene incorporates elements from all of the previous objectives. All objects in the scene use only basic geometric primitives and CSG. The Monte Carlo method is used to illuminate objects inside the snowglobe as well as create caustics below the glass marbles.
In order to drastically improve the render times of the ray tracer, 8 threads were used, with each thread rendering every eighth pixel starting from a given offset to balance the workload as much as possible.
The results shown were produced on the lab machine gl33 for the image in the background.
Very similar to texture mapping, the reflective property of each material can also be mapped in order make certain parts of an object more reflective than others.
This was used in the final scene to make the wrapping paper more relfective at certain parts.
This feature is actually a result of the Monte Carlo method and can be described as the effect of amplifying directed light from a source, say a flashlight, by surrounding one side with a very reflective surface. This way, light that is emitted backwards into the flashlight is reflected back out, increasing the intensity.
This effect is not possible simply using shadow rays, since additional light paths need to be followed to account for the light reflected from the inside of the flashlight.