Chapter 12 A
Chapter 12 A
Chapter 12 A
1 0 0 2 1 0 0 2
0 4 0 4 1 0 1/ 4 0 1
M ,M
0 0 4 9 0 0 1 / 4 9 / 4
0 0 0 1 0 0 0 1
Example (3)
• The inverse transformed ray is (8,4,-1) + (-8,-
3,1)t.
• Use this to obtain (quadratic formula values) (A,
B, C) = (74,-77,80), so the discriminant is 9.
Hence there are two intersections.
• From the hit time equation for the sphere, we
obtain the hit times 1.1621 and 0.9189.
• The hit spot is found by using the smaller hit
time in the ray representation, (10, 20, 5) + (-8,
-12, 4)0.9189 = (2.649, 8.97, 8.67).
Organizing a Ray Tracer
Application
• We can now construct an actual ray tracer.
• We shall use the Scene class and the SDL
language since they provide an already
constructed object list for the scene where each
object has an associated affine transformation.
• A ray tracer has to deal with several different
interacting objects: the camera, the screen, rays
that emanate from the camera and migrate
through the scene, and the scene itself, which
contains many geometric objects and light
sources.
Organizing a Ray Tracer (2)
• In our approach, the camera is given the task of
doing the ray tracing, for which we add a method
to the existing Camera class: void Camera ::
raytrace(Scene& scn, int blockSize);
– The camera is given a scene to ray trace and a
certain blocksize, to be described.
• It generates a ray from its eye through each
pixel corner into the scene and determines the
color of the light coming back along that ray.
• It then draws the pixel in that color.
Organizing a Ray Tracer (3)
• We will use OpenGL to do the actual pixel
drawing and will have raytrace() set up the
modelview and projection matrices to draw
directly on the display.
• This makes the display() function in the
main loop of the application very simple; it
need only clear the screen and tell the
camera object cam to ray trace.
Organizing a Ray Tracer (4)
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT); //
clear the screen
cam.raytrace(scn, blockSize); // ray trace
the scene
}
• Helpful tip: Drawing a preview of the scene just
before ray tracing it assures that the camera is
aimed properly and the objects are in their proper
places.
Organizing a Ray Tracer (5)
• To add a preview of the scene, simply extend
display() to:
void display(void)
{ //clear the screen and reset the depth buffer
glClear(GL_COLOR_BUFFER_BIT|
GL_DEPTH_BUFFER_BIT);
cam.drawOpenGL(scn); // draw the preview
cam.raytrace(scn, blockSize); // ray trace over
the preview
}
Example of Ray Tracing in
Progress
• The preview has been drawn, and the
lower half of the screen has been ray
traced. The important point here is that the
ray tracing exactly overlays the preview
scene.
Organizing a Ray Tracer (6)
• The Camera class’s raytrace() method
implements ray-tracing.
• For each row r and column c a ray object
is created that emanates from the eye and
passes through the lower left corner of the
rc-th pixel into the scene.
• We need a Ray class for this.
Initial Ray Class
class Ray{
public:
Point3 start;
Vector3 dir;
void setStart(point3& p{start.x = p.x; etc..}
void setDir(Vector3& v){dir.x = v.x; etc..}
// other fields and methods
};
Raytrace() Skeleton
void Camera :: raytrace(Scene& scn, int blockSize)
{ Ray theRay;
theRay.setStart(eye);
// set up OpenGL for simple 2D drawing
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,nCols,0,nRows); // whole screen is the
window
glDisable(GL_LIGHTING); // so glColor3f() works
properly
Raytrace() Skeleton (2)
// begin raytracing
for (int row = 0; row < nRows; row += blockSize)
for (int col = 0; col < nCols; col += blockSize)
{ compute the ray’s direction
theRay.setDir(<direction>); //set the ray’s direction
Color3 clr = scn.shade(theRay); // find the color
glColor3f(clr.red, clr.green, clr.blue);
glRecti(col,row,col + blockSize, row + blockSize);
}
}
Organizing a Ray Tracer (7)
• The blockSize parameter determines the size of
the block of pixels being drawn at each step.
• Displaying pixel blocks is a time-saver for the
viewer during the development of a ray tracer.
• The images formed are rough but they appear
rapidly; instead of tracing a ray through every
pixel, wherein the picture emerges slowly pixel
by pixel, rays are traced only through the lower
left corner of each block of pixels.
Organizing a Ray Tracer (8)
• The figure (a) shows how this works for a
simple example of a display that has 16
rows and 32 columns of actual pixels, and
blockSize is set to 4. Each block consists
of 16 pixels.
Organizing a Ray Tracer (9)
• The color of the ray through the corner of the
block is determined, and the entire block (all 16
pixels) is set to this uniform color.
• The image would appear as a raster of four by
eight blocks, but it would draw very quickly.
• If this rough image suggests that everything is
working correctly, the viewer can re-trace the
scene at full resolution by setting blockSize to 1.
Block Size Example
• The figure (b) shows a simple scene ray
traced with a block size of 4, 2, and 1.
Organizing a Ray Tracer (10)
• raytrace() sets up OpenGL matrices for drawing the pixel
blocks.
• The modelview matrix is set to the identity matrix, and
the projection matrix does scaling of the window to the
viewport with no projection.
• The OpenGL pipeline is effectively transparent, so that a
square can be drawn directly into the viewport using
glRecti(). We assume the viewport has already been set
to the full screen window with a
glViewport(0,0,nCols,nRows) when the program is first
started.
• OpenGL’s lighting must also be disabled so that
glColor3f() will work properly.