Ray tracing, implicit surface generation, and mesh manipulation. Written in the Processing (Java) language, implemented for Computer Graphics (CS-6491), Spring 2024, GA Tech.
Much of the documentation below was adapted from the assignment descriptions written by the course instructor, Dr. Greg Turk.
- Download Processing
- Open one of the project folders and hit the run button
- Use keys to load scenes (details below)
Ray tracing scenes are shown in pairs.
Pressing keys 1
to 9
causes the left (a) version of the scene to be rendered.
Pressing shift
+ 1
-9
(characters !@#$%^&*(
) causes the right (b) scene to be rendered.
Many (but not all) of the (b) scenes shoot more than one ray per pixel.
Below are the generated images:
(a) | (b) |
---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Pressing 0
renders the custom scene from the implicit_surfaces
project, rendered as a low-poly, single-colored instance with soft shadows, DOF, and glossy reflections:
Each scene is described by a text file with a .cli
suffix (Command Language Interpreter), with each nonempty line describing a scene command.
The following scene description commands are implemented:
-
background r g b
: Sets the background color. If a ray misses all the objects in the scene, the corresponding pixel is set to this color. -
fov angle
: Specifies the field of view (in degrees) of the virtual camera. -
light x y z r g b
: Create a point light source at position(x,y,z)
and its color(r, g, b)
. Any number of light sources is allowed. -
surface dr dg db
: Specifies a new surface material with diffuse color(dr, dg, db)
. -
begin
: Indicates the start of a triangle. -
vertex x y z
: Specifies one vertex of a triangle. Three such vertex commands in a row define a triangle. -
end
: Indicates the end of a triangle. -
render
: Ray traces the scene and displays the image in the drawing window. -
translate tx ty tz
: Create a translation matrix$T$ and multiply it on the right-hand side of the matrix stack,$C_{\text{new}} = C * T$ . -
scale sx sy sz
: Create a scale matrix$S$ and multiply it on the right-hand side of the matrix stack,$C_{\text{new}} = C * S$ . -
rotatex angle
,rotatey angle
,rotatez angle
,rotate x_angle y_angle z_angle
: Create a rotation matrix$R$ and multiply it on the right-hand side of the matrix stack,$C_{\text{new}} = C * R$ . Angles of rotation are specified in degrees. -
push
: Duplicate the matrix on top of the stack and push this duplicate onto the stack. This new top of the stack is the current transformation matrix$C$ . When the program starts with a single identity matrix$I$ on top of the stack. -
pop
: Pop off the top matrix from the stack and discard it. If the stack only has one element, an error is printed. -
vertex x y z
: The current transformation matrix$C$ (the top matrix on the stack) affects all triangles in the scene. -
box xmin ymin zmin xmax ymax zmax
: Create an axis-aligned box primitive and put it on the list of scene objects. Used for acceleration data structures. Just like triangles, boxes are modified by the current transformation matrix when the box is created. (Rotating an axis-aligned box will have unexpected results.) -
named_object <name>
: Remove the most recently created object from the list of scene objects, convert this object to a named object, and place it in the named objects collection. A named object can be a triangle, an axis-aligned box, or an acceleration data structure containing multiple objects. -
instance <name>
: Create an instance of a named object and add that object to the scene objects list. -
begin_accel
: Begin creating a list of objects separate from the list of scene objects. -
end_accel
: Finish putting objects into the separate acceleration list, place this list of objects into a bounding volume hierarchy, and ddd this new acceleration object into the scene. -
read filename
: Begin reading commands from another file (e.g.read bun500.cli
). -
sphere radius x y z
: Create a sphere with a given radius and center location. -
rays_per_pixel num
: Specify how many rays per pixel to shoot. One ray per pixel by default. Whennum > 1
, sub-pixel rays are created in random positions within each pixel. The colors of these rays are averaged together to determine the final color of the pixel. -
moving_object dx dy dz
: Change the last object that was defined into a moving object. The displacement(dx, dy, dz)
specifies the amount of translation this object undergoes during one frame. Rays shot at such an object are assigned a random time in [0, 1]. The moving object is translated by this random time amount times the displacement. When manyrays_per_pixel >> 1
, this gives the appearance of motion blur. -
disk_light x y z radius dx dy dz r g b
: Create a disk light source with a given center(x, y, z)
, radius, light direction(dx, dy, dz)
, and light color(r, g, b)
. Shadow rays are shot to random locations on this disk. When manyrays_per_pixel >> 1
, this creates soft shadows. -
lens radius dist
: Whenradius > 0
, creates depth-of-field (DOF) effects by shooting rays from a lens with eye rays originating from a random point on the lens. The lens is a disk that is centered at the origin of the given radius, perpendicular to the z-axis.dist
is the distance to the focal plane, perpendicular to the z-axis. All rays for a given pixel, no matter where they originate on the lens, pass through the same point on the focal plane. -
glossy dr dg db sr sg sb spec_pow k_refl gloss_radius
: Create a shiny surface material.(dr dg db)
are the diffuse color coefficients, just as in thesurface
command.(sr sg sb)
are the specular color coefficients and only affect the colors of the specular highlights.spec_pow
affects the apparent roughness of the surface, with higher values giving tighter highlights.k_refl > 0
indicates the surface is shiny enough to shoot reflected rays and indicates how much they contribute to the surface color. Whengloss_radius == 0
, the direction of the reflected rays travels in the perfect mirror direction. Whengloss_radius > 0
, a "fuzz factor" is added to the perfect mirror direction, taken from a random vector inside a sphere of the given radius. When multiple rays per pixel are used, this gives the impression of glossy reflections.
The following are the scene keys, descriptions, and renders for this project:
- 1: A single implicit sphere.
- !: A flattened sphere that looks like a flying saucer.
![]() |
![]() |
![]() |
![]() |
2: Pairs of blobby spheres that are partially blended together. | @: A bunch of 10 randomly placed blobby spheres that are colored randomly. |
---|---|
![]() |
![]() |
![]() |
![]() |
3: Create and draw an implicit line segment. | #: Four blobby implicit line segments that blend together to form a blobby square. |
---|---|
![]() |
![]() |
4: An implicit torus. | $: Three blobby tori that are stuck to each other. |
---|---|
![]() |
![]() |
5: Create one thin implicit line segment that has its long axis parallel to the x-axis. | %: Take the thin line segment from Key 5 and warp its shape using a twist deformation. |
---|---|
![]() |
![]() |
6: Implement the taper deformation and use it to create a tapered line segment. | ^: Use both taper and twist together to deform a line segment. |
---|---|
![]() |
![]() |
7: Perform a boolean intersection between two spheres to make a saucer shape that has sharp edges. | &: Perform a boolean subtraction that punches a hole through a sphere. |
---|---|
![]() |
![]() |
Allow interactive morphing between a sphere and three intersecting line segments:
![]() |
![]() |
![]() |
![]() |
- 0: My custom implicit surface scene incorporating all the above elements:
- 1-7: Read in a mesh file (octahedron, cube, icosahedron, dodecahedron, star, torus, S).
- f: Toggle between per-face and per-vertex normals.
- w: Toggle between white and randomly colored faces.
- e: Toggle between not showing and showing the mesh edges in black.
- v: Toggle visualization of a directed edge on/off
- n: Change the current edge using the "next" operator.
- p: Change the current edge using the "previous" operator.
- o: Change the current edge using the "opposite" operator.
- s: Change the current edge using the "swing" operator.
- d: Create and display the dual of the mesh (unlimited number of times).
- g: Perform geodesic (midpoint) subdivision of the mesh and project vertices to the unit sphere (unlimited number of times).
- c: Perform Catmull-Clark subdivision (unlimited number of times).
- r: Add random noise to the mesh by moving the vertices in the normal direction (both in and out).
- l (lower case "L"): Perform Laplacian smoothing (40 iterations).
- t: Perform Taubin smoothing (40 iterations).
Adjacency operators: In the top row, a directed edge is illustrated with three small spheres. The remaining four images show where this corner would be moved by each of the following operators: next, previous, opposite, and swing, respectively.
Directed Edge | Next | Previous | Opposite | Swing |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
Shading: These next images show each model using flat shading, flat shading with edges shown, colored faces, and vertex normals.
Octahedron | Octahedron (Edges) | Octahedron (Colored) | Octahedron (Normals) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Cube | Cube (Edges) | Cube (Colored) | Cube (Normals) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Icosahedron | Icosahedron (Edges) | Icosahedron (Colored) | Icosahedron (Normals) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Star | Star (Edges) | Star (Colored) | Star (Normals) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Dual meshes: Each of the next rows shows an original object on the left and its dual on the right.
Icosahedron | Icosahedron Dual |
---|---|
![]() |
![]() |
Star | Star Dual |
---|---|
![]() |
![]() |
Torus | Torus Dual |
---|---|
![]() |
![]() |
S | S Dual |
---|---|
![]() |
![]() |
Geodesic (midpoint) subdivision: Each row of the next images shows an original model, the model with one step of geodesic subdivision, two steps of geodesic subdivision, and three steps of geodesic subdivision. The two models at the left are the octahedron and the icosahedron.
Octahedron | Octahedron (1 Step) | Octahedron (2 Steps) | Octahedron (3 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Icosahedron | Icosahedron (1 Step) | Icosahedron (2 Steps) | Icosahedron (3 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Catmull-Clark subdivision: The next four images show an original model in each row, followed by the model with 1, 2, and 4 steps of Catmull-Clark subdivision.
Octahedron | Octahedron (1 Step) | Octahedron (2 Steps) | Octahedron (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Cube | Cube (1 Step) | Cube (2 Steps) | Cube (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Icosahedron | Icosahedron (1 Step) | Icosahedron (2 Steps) | Icosahedron (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Dodecahedron | Dodecahedron (1 Step) | Dodecahedron (2 Steps) | Dodecahedron (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Star | Star (1 Step) | Star (2 Steps) | Star (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Torus | Torus (1 Step) | Torus (2 Steps) | Torus (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
S | S (1 Step) | S (2 Steps) | S (4 Steps) |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Noise and smoothing: Each of the next two rows shows a subdivided mesh, noise added, noise and Laplacian smoothing, noise and Taubin smoothing. Laplacian smoothing: lambda = 0.6. Taubin smoothing: lambda1 = 0.6307, lambda2 = -0.67315.
Geodesic subdivision on icosahedron:
Original | With Noise | With Noise and Laplacian Smoothing | With Noise and Taubin Smoothing |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Catmull-Clark subdivision on star:
Original | With Noise | With Noise and Laplacian Smoothing | With Noise and Taubin Smoothing |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Smooth-shaded models: These next three images show smooth-shaded versions of models that were subdivided three times using Catmull-Clark. The models are the icosahedron, star, and the 'S'.
Icosahedron | Star | S |
---|---|---|
![]() |
![]() |
![]() |