Graphics Reference
In-Depth Information
23
24
25
26
27
28
29
30
31
32
shade(scene, T, P, n, w_o, radiance);
// Debugging intersect: set to white on any intersection
//radiance = Radiance3(1, 1, 1);
// Debugging barycentric
//radiance = Radiance3(weight[0], weight[1], weight[2]) / 15;
return true ;
}
The sampleRayTriangle routine returns false if there was no intersec-
tion closer than distance ; otherwise, it updates distance and radiance and
returns true .
When invoking this routine, the caller passes the distance to the clos-
est currently known intersection, which is initially INFINITY (let INFINITY
= std::numeric_limits<T>::infinity() in C++, or simply 1.0/0.0 ).
We will design the intersect routine to return INFINITY when no inter-
section exists between R and T so that a missed intersection will never cause
sampleRayTriangle to return true .
Placing the (d >= distance) test before the shading code is an optimiza-
tion. We would still obtain correct results if we always computed the shading
before testing whether the new intersection is in fact the closest. This is an impor-
tant optimization because the shade routine may be arbitrarily expensive. In fact,
in a full-featured ray tracer, almost all computation time is spent inside shade ,
which recursively samples additional rays. We won't discuss further shading opti-
mizations in this chapter, but you should be aware of the importance of an early
termination when another surface is known to be closer.
Note that the order of the triangles in the calling routine ( rayTrace ) affects
the performance of the routine. If the triangles are in back-to-front order, then we
will shade each one, only to reject all but the closest. This is the worst case. If
the triangles are in front-to-back order, then we will shade the first and reject the
rest without further shading effort. We could ensure the best performance always
by separating sampleRayTriangle into two auxiliary routines: one to find the
closest intersection and one to shade that intersection. This is a common practice
in ray tracers. Keep this in mind, but do not make the change yet. Once we have
written the rasterizer renderer, we will consider the space and time implications of
such optimizations under both ray casting and rasterization, which gives insights
into many variations on each algorithm.
We'll implement and test intersect first. To do so, comment out the call to
shade on line 23 and uncomment either of the debugging lines below it.
15.4.3 Ray-Triangle Intersection
We'll find the intersection of the eye ray and a triangle in two steps, following the
method described in Section 7.9 and implemented in Listing 15.16. This method
first intersects the line containing the ray with the plane containing the triangle. It
then solves for the barycentric weights to determine if the intersection is within the
triangle. We need to ignore intersections with the back of the single-sided triangle
and intersections that occur along the part of the line that is not on the ray.
The same weights that we use to determine if the intersection is within the
triangle are later useful for interpolating per-vertex properties, such as shading
 
 
 
Search WWH ::




Custom Search