Difficulty |
3 |
Prerequisites |
def scene_at(now)
{
var camera = Cameras.perspective( [ "eye": pos(0,0,5),
"look_at": pos(0,0,0) ] )
var floor_material = Materials.uniform( [ "ambient": Colors.white() * 0.1,
"diffuse": Colors.white() * 0.8,
"reflectivity": 0.5 ] )
var left_wall_material = Materials.uniform( [ "ambient": Colors.red() * 0.1,
"diffuse": Colors.red() * 0.8 ] )
var right_wall_material = Materials.uniform( [ "ambient": Colors.green() * 0.1,
"diffuse": Colors.green() * 0.8 ] )
var back_wall_material = Materials.uniform( [ "ambient": Colors.blue() * 0.1,
"diffuse": Colors.blue() * 0.8 ] )
var ceiling_material = floor_material
var sphere_material = Materials.uniform( [ "ambient": Colors.blue() * 0.1,
"diffuse": Colors.blue() * 0.8,
"specular": Colors.white() * 0.8,
"specular_exponent": 10,
"translucency": 0.5 ] )
var small_sphere_material = Materials.uniform( [ "ambient": Colors.white() * 0.1,
"diffuse": Colors.white() * 0.8,
"reflectivity": 0.8 ] )
var primitives = []
primitives.push_back( translate(vec(0,-2,0), decorate(floor_material, xz_plane())) )
primitives.push_back( translate(vec(0,2,0), decorate(ceiling_material, xz_plane())) )
primitives.push_back( translate(vec(-2,0,0), decorate(left_wall_material, yz_plane())) )
primitives.push_back( translate(vec(2,0,0), decorate(right_wall_material, yz_plane())) )
primitives.push_back( translate(vec(0,0,-2), decorate(back_wall_material, xy_plane())) )
var sphere_position = Animations.circular( [ "position": pos(0,0,1),
"around": pos(0,0,0),
"duration": seconds(5) ] )
primitives.push_back( decorate( sphere_material, translate(sphere_position[now] - pos(0,0,0), scale(0.5, 0.5, 0.5, sphere())) ) )
primitives.push_back( decorate( small_sphere_material, scale(0.25, 0.25, 0.25, sphere()) ) )
var root = union(primitives)
var lights = [ Lights.omnidirectional( pos(0,1.9,0), Colors.white() ) ]
create_scene(camera, root, lights)
}
var raytracer = Raytracers.v7()
var renderer = Renderers.standard( [ "width": 500,
"height": 500,
"sampler": Samplers.multijittered(2),
"ray_tracer": raytracer ] )
pipeline( scene_animation(scene_at, seconds(5)),
[ Pipeline.animation(30),
Pipeline.renderer(renderer),
Pipeline.studio() ] )
1. Background Information
This ray tracer version adds a simplified version of transparency. A more realistic form will be implemented in the next version.
The idea behind this ray tracer is very simple: if a ray hits a translucent object, the ray passes through and we simply continue tracing the same eye_ray
to the next object in the scene.
In the image below, the ray hits the red sphere at \(P_1\). The red sphere is translucent, so the ray goes through it and we continue tracing. We find a new second hit at \(P_2\). This is the same translucent material, so the ray continues. We bump into the blue sphere at \(P_3\). Because this blue sphere is not translucent, so tracing stops there.

Of course, the red sphere could also be reflective, in which case we would need to both trace the "penetrating" and the reflected ray and add the results together.
Important
|
Some people misinterpret the above description. They think that, when having found \(P_1\), they need to look for the matching \(P_2\) as that’s where the ray leaves the object. That is not the case. While it makes sense, it would be impossible to achieve given the current design of the ray tracer. Instead, the algorithm goes as follows:
|
2. MaterialProperties
First things first: we need a way to express the fact that a material can be translucent.
Let’s add it as an extra field to MaterialProperties
.
Add an extra field |
Update |
Update |
3. RayTracerV7
Create files |
3.1. compute_translucency
Let’s give compute_ambient
and compute_reflection
a little brother who will be responsible for dealing with translucent objects.
Add a protected method with signature
Implement it based on the following pseudocode:
|
3.2. determine_color
We need to update determine_color
so that is takes into account compute_translucency
.
Override
|
3.3. Finishing Touches
Implement the factory function |
Expose |
4. Evaluation
Reproduce the scene below. |