<html>
<head>
<title>
Project 2 Help Session
</title>
</head>
<body>
<h1>
Project 2 Help Session
</h1>
CS 348B - Computer Graphics: Image Synthesis Techniques<br>
Spring Quarter, 1997<br>
Mark Levoy<br>

<h3> Outline </h3>

<ul>
<li> Assignment overview
<li> Project 2 Requirements
<li> Acceleration Techniques (Overview)
<li> Major Acceleration Techniques
<li> Moderate Acceleration Techniques
<li> Minor Acceleration Techniques
<li> Questions
</ul>

<h3> Assignment overview </h3>

<ul>
<li> Why spend a whole project on optimization?
<table border=3>
<tr>
<th>			Test</th>
<th>			Polygons</th>
<th>			Unoptimized</th>
<th>			Octree</th>
<th>			Bounding Box</th>

<tr>
<td>			test1<br>
			(Table & 2 chess pieces)
<td align=middle>	6000
<td align=middle>	12 hours
<td align=middle>	50 seconds
<td align=middle>	21 seconds
</tr>

</tr>
<tr>
<td>			test2<br>
			(Barcelona Olympic Pavilion)
<td align=middle>	5000
<td align=middle>	1.3 hours
<td align=middle>	70 seconds
<td align=middle>	155 seconds
</tr>

<tr>
<td>			test3<br>
			(Mesh grid of dog's head)
<td align=middle>	10,000
<td align=middle>	2.1 hours
<td align=middle>	41 seconds
<td align=middle>	88 seconds
</tr>

</table>
<i> Two good raytracers from last year, rendering a 400x400 image, 5 levels
deep, on a 250MHz firebird. These raytracers did no off-line precomputation,
since it only took about 1 to 5 seconds. 
</i>
<p>

</ul>

<h3> 
Project 2 Requirements
</h3>
<ul>
<li> Command-line interface
	<ul>
	<li> Be able to run interactive or no-window mode
	<li> Required: input file, output file, image size
	<li> Suggested: be able to specify all slider / checkbox parameters
		with arguments, too. e.g.:
		<ul>
		<li> tree depth (5 for timing runs) 
		<li> min weight (0 for timing runs)
		<li> image size (400 for timing runs)
		<li> brightness scaling (or whatever other parameters your
			raytracer uses)
		<li> print usage (e.g. "raytrace -h")
		<li> ...
		</ul>
	</ul>
<li> Trace 5 levels ( eye -> hit<sub>1</sub> -> hit<sub>2</sub> -> 
	hit<sub>3</sub> -> hit<sub>4</sub> -> 	hit<sub>5</sub> )
	<ul>
	<li> cast shadow rays for hit<sub>5</sub>, not reflection rays
	<li> Stop only if K<sub>s</sub> is 0
	</ul>
<li> Per-Vertex normals
	<ul>
	<li> Use geometric normal for all intersection tests
	<li> Use interpolated normal for shading, reflection, refraction
	<li> Barycentric coordinates give interpolation
	</ul>
	
<li> Per-Vertex materials
	<ul>
	<li> Interpolate every field that changes (diffuse, ambient,
	specular, shininess, or ktran)
	<li> Barycentric coordinates give interpolation
	</ul>
<li> No Transparency in test cases
	<ul>
	<li> Your intersect routine will probably return only the closest
	    intersection, not every intersection
	<li> However, you probably will want to keep the refraction code,
	     for project3.
	<li> For shadow rays through transparent surfaces, you can call
	     Intersect multiple times, starting at the new surface.
	</ul>
	 
<li> Submission
	<ul>
	<li> Measure elapsed time: "time myraytracer args..."
	<li> Measure memory use: "top"
	<li> Measure precomputation time
		<ul>
		<li> This time doesn't count towards project2 grade
		<li> However, be careful of algorithms worse than 
			O(n<sup>2</sup>).  For the final project, this
			can cost you a lot of time in the scene development
			/ test cycle.
		</ul>
	<li> README (see assignment for detailed instructions)
	</ul>

</ul>


<h3> Acceleration Techniques (Overview) </h3>
<i>This is just an outline of the material in Chapter 6 of Glassner's
raytracing book, "A Survey of Ray Tracing Acceleration Techniques,"
by James Arvo and David Kirk. </i><p>

<ul>

<li> Faster intersections
	<ul>
	<li> Faster ray-object intersections
		<ul>
		<li> e.g. Object bounding volumes
		</ul>
	<li> Fewer ray-object intersections
		<ul>
		<li> e.g. Bounding volume hierarchies
		<li> Space subdivision
		<li> Directional Techniques
		</ul>
	</ul>
<li> Fewer rays (not allowed for project2... :-)
	<ul>
	<li> Adaptive tree-depth control
	<li> Statistical optimizations for anti-aliasing
	</ul>
<li> Generalized rays
	<ul>
	<li> Beam tracing
	<li> Cone tracing 
	<li> Pencil raytracing
	</ul>
</ul>


<h3> Major Acceleration Techniques </h3>
<i> These techniques can change the asymptotic order of your program,
and give huge savings for large scenes.</i>
<ul>
<li> Hierarchical Bounding Volumes
	<ul>
	<li> Bottom-Up
		<ul>
		<li> Use scene's native hierarchy
		<li> Easiest to implement
		<li> Can give horrible performance
		</ul>
	<li> Top-Down
		<ul>
		<li> Pool all polygons together, start clustering them
		<li> Critical issue: How (and when) to divide?
			<ul>
			<li> Let: t<sub>bound</sub> be the time to test 
				   intersection with the bound
			<li> Let:  t<sub>children</sub> be the time to test 
				   intersection with the children
		
			<li> Cost: t<sub>bound</sub> *
			 	(all rays tested against bound)
			<li> Benefit: t<sub>children</sub> *
				(number of rays that missed the bound)
			<li> Profit = Benefit - Cost <br>
				(t<sub>children</sub> - t<sub>bound</sub>) *
				(number of rays that missed the bound) - <br>
				t<sub>bound</sub> *
				(number of rays that hit bound)
			<li> Think Ferengi: Want to maximize profit
			</ul>
		</ul>
	</ul>
<li> Spatial Subdivision
	<ul>
	<li> Octrees
		<ul>
		<li> Uniform vs. Nonuniform
			<ul>
			<li> Uniform easier to traverse
			<li> Non-uniform can be far faster
			<li> Non-uniform can be more memory efficient
			</ul>
		<li> Generation: Subdivide each voxel into 8 subvoxels
			<ul>
			<li> Top-down
			<li> Each voxel lists objects that are partially
				or fully within the voxel
			<li> Stop subdividing when few (or no) primitives, 
				or when	voxel gets too small
			</ul>
		<li> Traversal: Walk through voxels
			<ul>
			<li> Want to avoid testing objects multiple
				times (see "mailboxes", Glassner, p.225)
			<li> If voxel points to an object, and ray
			     intersects that object, but the intersection
			  	is not in the current voxel, you must keep
				traversing voxels until you get to the voxel
				which contains that intersection.
			</ul>
		</ul>
	<li> BSP trees
		<ul>
		<li> Recursively cut the world in half with planes
		<li> When raytracing, break ray into two intervals
		<li> Do "close" interval first
		<li> Don't need to test anything in far half if an
			intersection is found in the close half
		<li> Often, the interval in one half is empty
		</ul>


	</ul>
</ul>


<h3> Moderate Acceleration Techniques </h3>
<i> These are techniques that can greatly improve a raytracer under
certain conditions.  However, they have only limited applicability
to project 2, where we're already optimizing intersections, and only
casting one ray per pixel. </i>

<ul>
<li> Directional Techniques
	<ul> 
	<li> The Direction Cube (Glassner pp. 228-231)
		<ul>
		<li> Given a point in space, surround it with a cube
		<li> Squares on cube face form "windows" through which
		     only some objects are visible
		<li> Given any ray from (to) that point, you can compute
		     which window that ray passes through
		</ul>
	<li> The Light Buffer (Glassner, pp. 231-234)
		<ul>
		<li> Form a direction cube around a pointlight
		<li> For each window, form list of objects
		<li> Sort them from closest to farthest
		<li> Cull backfacing, stop if completely opaque
		<li> When checking ray to the light, go through the list
			<ul>
			<li> Let t<sub>0</sub> be distance to our surface
			<li> If you find another intersection with t less
				than t<sub>0</sub>, then it's in shadow
			<li> If the closest intersection is t<sub>0</sub>,
				then the light hits our surface
			<li> Be careful of intersecting objects, which
			    	don't have a single ordering
			</ul>
		</ul>
	</ul>
<li> Generalized Rays
	<ul>
	<li> Cones  (Glassner pp. 242-243)
		<ul>
		<li> Calculate how much of cone blocked by each object
		<li> Secondary rays:  surface curvature affects spread
		     of the cone
		<li> Cone enables penumbra, dull reflections
		<li> Intersection tricky, limited to polygons and spheres
		</ul>
	<li> Beams  (Glassner pp. 243-246)
		<ul> 
		<li> Like cones, but with polygonal cross-section
		<li> For reflection, compute "virtual eyepoint" of new beam
		<li> Partial occlusion -> clip polygon of beam
		<li> Problems: Non-convex, fragmented beam polygons
		</ul>
	<li> Pencils (Glassner p.246)
		<ul>
		<li> Set of beams with some given deviation, assumed
		     close enough together that interaction with each
		     surface is linear
		<li> Edges, discontinuities mean you must trace individual
		     rays.
		</ul>
	</ul>
</ul>


<h3> Minor Acceleration Techniques </h3>
<i> These techniques only change the running time by a constant factor,
but many are easy to implement. </i>
<ul>
<li> Turn compiler optimization flags on, such as -O3.
	<i> (after you've finished debugging! :-)</i>
<li> Tune the code inside the inner loop of bottlenecks 
	(such as intersection)
	<ul> 
	<li> Whitted: generally over 95% of time spent doing intersection
	<li> Avoid unnecessary expensive operations, such as malloc,
	 	inside your inner loop
	<li> Use temporary variables to avoid repeating code (such as taking
		the square root of something twice in the same function)
	<li> Replace simple functions with macros
		<ul>
		<li> This allows the compiler to optimize the code better
		<li> Be careful about parentheses!!!
		</ul>

	</ul>
<li> Don't waste time tuning code that isn't a bottleneck.
	<ul>
	<li> If you don't know your bottlecks, try profiling your program.
		See "man prof".
	</ul>
</ul>


<h3> Questions </h3>


<p>
<hr>
<address>
lucasp@cs.stanford.edu
</address>
<b>Copyright &copy; 1997 Marc Levoy</b>
<br>
Last update: Friday, 2-May-97 
</body>
</html>
