228 lines
9.9 KiB
HTML
228 lines
9.9 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>FART Design Document</title>
|
|
<style type="text/css">
|
|
body {
|
|
margin: 0.2em 2ex;
|
|
background-color: #DEF;
|
|
}
|
|
.link {
|
|
padding: 0.2em 0.5ex;
|
|
text-decoration: none;
|
|
border: solid 1px black;
|
|
background-color: #CCC;
|
|
color: #000;
|
|
font-weight: bold;
|
|
}
|
|
.link:hover {
|
|
background-color: #999;
|
|
}
|
|
hr { margin: 2em auto; }
|
|
tt {
|
|
display: block;
|
|
margin: 0.4em 0px;
|
|
padding: 0.1em 0.8ex;
|
|
background-color: #FFF;
|
|
border-style: dashed;
|
|
border-width: 1px;
|
|
border-color: #900;
|
|
}
|
|
img { border-style: none; }
|
|
li { font-weight: bold; font-size: larger; }
|
|
.update { color: #F00; }
|
|
.mono { font-family: monospace; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1 style="text-align:center">FART (FART Ain't A RayTracer)</h1>
|
|
<div style="text-align:center">
|
|
<a class="link" href="index.html#description">Project Description</a>
|
|
|
|
<a class="link" href="index.html#code">Code</a>
|
|
|
|
<a class="link" href="design.html">Design Document</a>
|
|
|
|
<a class="link" href="index.html#screenshots">Screenshots</a>
|
|
|
|
<a class="link" href="report.html">Final Report</a>
|
|
</div>
|
|
|
|
<hr/>
|
|
<h2>FART Design Document</h2>
|
|
<ol>
|
|
<li>Overview</li>
|
|
<p>
|
|
FART is my semester project for the Computer Science 658 class at
|
|
Grand Valley State University.
|
|
My goal is for FART to be a distributed, object-oriented ray-tracer.
|
|
The name is a recursive acronym similar to "GNU" or "LAME."
|
|
</p>
|
|
|
|
<p>
|
|
FART will take in a scene-description file in a text-based
|
|
input file format.
|
|
After the scene file is parsed, it will be raytraced (rendered)
|
|
according to the render options.
|
|
Some of these options can be specified on the command line
|
|
and others can be specified in the scene description file.
|
|
When a given option can be specified both places,
|
|
the command-line options will override what is in the scene file.
|
|
</p>
|
|
|
|
<li>Distribution</li>
|
|
<p>
|
|
Rendering can be done using a built-in distributed algorithm.
|
|
Command-line options will be utilized to specify a "hosts file"
|
|
which can contain a list of hosts to use while rendering the scene.
|
|
The algorithm will be fault-tolerant so that if one of the
|
|
worker nodes goes down the work can be reorganized to complete
|
|
that section of the image.
|
|
</p>
|
|
|
|
<p>
|
|
The instance of the program which is directly invoked by the user
|
|
will be the "master" process.
|
|
If a hosts file is specified as an argument to the program, then
|
|
the master process will read a list of hosts to use as worker nodes.
|
|
It will spawn an instance of the program on each worker node,
|
|
and dole out chunks of the image to each worker node in a
|
|
master/slave, client/server manner.
|
|
</p>
|
|
|
|
<p>
|
|
Since the amount of time to render a given chunk of the image
|
|
can vary tremendously depending on the number of objects
|
|
in the scene, the maximum recursion depth, and the antialiasing
|
|
level, the master process does not know how long it should wait
|
|
to expect a reply from the worker nodes.
|
|
Therefore, a thread on the master node will be dedicated to
|
|
polling all the worker nodes at an interval of some number of seconds.
|
|
The worker nodes should respond to this polling message with
|
|
a "still working" message to indicate that they are still up
|
|
and are processing data. If a given worker node does not reply
|
|
to the polling message, it will be considered "down" and the
|
|
work it was processing will be doled out to another node.
|
|
</p>
|
|
<p>
|
|
<span class="update">
|
|
Update:
|
|
Instead of having a separate thread from the master poll the
|
|
slave nodes, a more straightforward solution was implemented.
|
|
When a slave node requests a task from the master, the master
|
|
will respond with the next available task and record that this
|
|
task is in progress.
|
|
If a request comes in for a task when all of the initial tasks
|
|
have been exhausted, but there are some in progress, the master
|
|
will respond with one of the tasks that is marked in progress
|
|
for the slave node to work on.
|
|
In this way, if the original slave node working on the task does
|
|
not respond and finish the task, the new slave node should respond
|
|
and complete the task.
|
|
This method also has the advantage that it will work whether a
|
|
slave node is extremely slow or truly unresponsive.
|
|
The master will use the data from whichever node responds first
|
|
announcing the completion of a given task.
|
|
</span>
|
|
</p>
|
|
|
|
<p>
|
|
In this way, the raytracer program will be fault-tolerant.
|
|
It can tolerate each <span class="update">(Update: all but one)</span>
|
|
of the worker nodes going down and still produce the final image.
|
|
</p>
|
|
|
|
<li>Program Organization</li>
|
|
<p>
|
|
The follows the object-oriented design paradigm.
|
|
It is made up of a collection of modules, which are organized
|
|
into functional groupings.
|
|
Each module implements one or more classes of objects for the system.
|
|
The groupings of modules are utility modules, scene description
|
|
file parsing modules, shape modules, program distribution modules,
|
|
and main program modules.
|
|
</p>
|
|
|
|
<li>Class Diagram</li>
|
|
<p>
|
|
<img src="class-diagram.png" />
|
|
</p>
|
|
|
|
<li>Ray-Tracing Algorithm</li>
|
|
<p>
|
|
The actual scene will be rendered by tracing rays from the
|
|
virtual camera's position in space through a virtual plane
|
|
perpendicular to the view direction which represents the image
|
|
being rendered.
|
|
For each pixel, a total of <em>m</em>^2 rays will be launched,
|
|
where <em>m</em> is the multi-sample level set by the user.
|
|
Setting a multi-sample level greater than 1 effectively produces
|
|
an anti-aliased image.
|
|
</p>
|
|
|
|
<p>
|
|
Rays are collided with objects in the scene, and the closest object
|
|
to the viewer that is hit by the ray is recorded.
|
|
When this object has been found, its material properties are examined
|
|
for lighting information, reflection levels, and transparency levels.
|
|
<span class="update">Update: If the object found is a boolean
|
|
object, made up of multiple sub-objects, then the material
|
|
properties of the actual sub-object at the intersection location
|
|
are what are used for lighting, etc...
|
|
</span>
|
|
</p>
|
|
<p>
|
|
Unless the object is completely transparent or 100% reflective,
|
|
for each light in the scene, a ray is launched from the contact
|
|
point on the surface of the closest object to the light source.
|
|
If the ray hits the light source then the Phong lighting model
|
|
is computed to calculate the color for that point on the surface.
|
|
If the ray instead hits another object instead of the light source,
|
|
then that light source does not add to the color at that point,
|
|
effectively producing a shadow.
|
|
</p>
|
|
|
|
<p>
|
|
After calculating the light source's contributions to the color,
|
|
the algorithm will recurse if the surface has non-zero
|
|
reflectivity or transparency.
|
|
This allows the scene to accurately be drawn from a reflected point
|
|
of view from a particular surface.
|
|
This is one of the major strengths of the ray-tracing algorithm.
|
|
</p>
|
|
|
|
<p>
|
|
When the scene attempts to determine if a given ray collides with
|
|
a shape, it calls the virtual function intersect() on the shape.
|
|
This function is overridden in all shape objects.
|
|
It returns a list of (shape, point) intersection pairs telling
|
|
which shape was hit and which point it was hit at.
|
|
<span class="update">
|
|
Update:
|
|
The <span class="mono">intersect()</span> method actually
|
|
returns three values: The actual shape hit, the intersection
|
|
point, and also the surface normal at the intersection point.
|
|
The surface normal is returned because it may not be equivalent
|
|
to the surface normal of the actual shape hit.
|
|
The reason for this is the <span class="mono">Subtract</span>
|
|
boolean object type.
|
|
When one object is subtracted from another (in the form A - B),
|
|
the effective surface normal of the composite object at a point
|
|
on the edge of object B will be the inverse of the true surface
|
|
normal on object B.
|
|
</span>
|
|
The reason it returns the shape hit is because the shape object
|
|
inquired may be a composite object of some sort (such as an
|
|
intersection, union, or subtraction of sub-shapes).
|
|
Thus, the caller knows which actual shape object was hit and can
|
|
thus use this shape object to determine material properties
|
|
<span class="update"><del>and the surface normal</del></span>
|
|
at the intersection point.
|
|
</p>
|
|
</ol>
|
|
|
|
</body>
|
|
</html>
|