[ LiB ] |
You already know how to shade a surface for diffuse interaction and specular highlights. Now you need to implement specular (mirror) reflections of light and the refraction of light on surfaces. The program that incorporates reflection and refraction resides in the folder /Ray Tracer 2 . The /Common folder contains all the underlying classes you've developed in the book. These files are used for the ray-tracing application. The only thing that's changed from the previous application is the addition of the Tray_Ray_In_Scene() method, which incorporates the new features for reflection and refraction. After a ray has been shaded, new rays are launched from the point of intersection. These new rays can be reflected or refracted. The new rays are spawned and will move through space until they hit other surfaces. Depending on the type of surface they encounter, the rays will either diffusively shade the surface or specu-larly reflect onto other surfaces. The process continues until the maximum trace depth is encountered .
NOTE
NOTE
Ray tracing is extremely good at mirror reflection and refraction.
Take a look at the new method that follows . The reflected and refracted directions are computed by using the vector reflection and vector refraction functions. The application then calls the same function again with the new reflected or refracted directional vector as its parameter. The process begins again with the new vector as the input direction. Its goal is to find any objects nearby that were intersected. If a new intersected point is found it is summed into the point in the previous recursion. After the reflected or refracted contribution is found, it is summed into the current pixel. The type of reflection or refraction that occurs is based on the material properties. The new code is listed in bold:
bool cScene::Tray_Ray_In_Scene(cRay ray, int depth, color3 *pColor) { cVector3 Hit, Normal; cVector3 Reflected_Dir, Refracted_Dir; int iClosestObject; color3 color_Object = color3::Black, intensity_Shade = color3::Black; color3 color = color3::Black; color3 reflected_Shade = color3::Black; color3 refracted_Shade = color3::Black; if( depth > MAX_TRACE_DEPTH ) { *pColor = color; return false; } // find closest object iClosestObject = Find_Closest_Object(ray, &Hit); // get object normal Normal = pObjectList[iClosestObject].Normal(Hit); // if object is in the local array list if( iClosestObject > -1 ) { // object color color_Object = pObjectList[iClosestObject].Color; // BEGIN RAY TRACING if ( this->Render_Algorithm & RAY_TRACING ) { color = ( color * pObjectList[iClosestObject].fAmbientFactor ); intensity_Shade = ShadePoint( Hit, Normal, iClosestObject ); color.r += color_Object.r * intensity_Shade.r; color.g += color_Object.g * intensity_Shade.g; color.b += color_Object.b * intensity_Shade.b; // Calculate Reflection if( RenderSetting.use_specular_reflection && pObjectList[iClosestObject].fSpecularFactor > 0.0f ) { Reflected_Dir = ray.direction.Vector_Reflection( Normal ) ; if(!Tray_Ray_In_Scene(cRay(Hit, Reflected_Dir), depth + 1, &reflected_Shade )) reflected_Shade = color3::Black; } color += (reflected_Shade * pObjectList[iClosestObject].fSpecularFactor); // Calculate Refraction // Mediums are currently : From Air (1.003) // to the Surface Refraction Index if( RenderSetting.use_refraction && pObjectList[iClosestObject].fOpacity < 1.0f ) { // surface - into air if(ray.direction.Vector_Refraction(Normal, 1.003f,pObjectList[iClosestObject].fIndex_Of_Refraction, &Refracted_Dir )) { if( !Tray_Ray_In_Scene(cRay(Hit, Refracted_Dir), depth + 1, &refracted_Shade )) refracted_Shade = color3::Black; } } color += ( refracted_Shade * pObjectList[iClosestObject].fOpacity ); } // end ray tracing color.Sat(); *pColor = color; } else { *pColor = color3::Black; return false; } return true; }
To use this program, you need to open the application in Microsoft Visual C++ 6.0, in debug mode. In order for the scene files to work in a relative path with the executable, you must run the application using Microsoft Visual C++. Recall that the /Common folder contains all the underlying classes used for the ray-tracing application. In the folder called /Ray Tracer 2 is another folder called /Scenes . The files included in the /Scenes folder are the input scene files you will type into the program.
The /Common folder is in /Book Code/Chapter 09/Ray Tracer 2/Common . The files in this folder are:
12/21/2002 04:48p 1,381 cLight.h 12/21/2002 04:38p 5,127 cObject.cpp 12/21/2002 04:58p 4,667 cObject.h 12/21/2002 04:39p 442 Color3.cpp 12/04/2002 12:33p 4,476 Color3.h 12/21/2002 04:39p 23 cRay.cpp 12/21/2002 04:59p 2,043 cRay.h 12/21/2002 04:39p 22,499 cScene.cpp 12/21/2002 04:59p 3,324 cScene.h 12/19/2002 05:29p 1,991 cVector3.cpp 12/21/2002 04:47p 5,171 cVector3.h 12/21/2002 04:59p 1,060 MathTools.h 12/21/2002 04:39p 1,108 PPM.cpp 12/21/2002 04:49p 154 PPM.h
To compile this program, follow these steps:
Open the project workspace ( Ray Tracer 2.dsw or Ray Tracer 2.dsp ).
From the File menu, choose Build, Rebuild All.
From the File menu, choose Build, !Execute Ray Tracer 2.exe.
To run the program directly instead, execute the following file:
/Book Code/Chapter 09/Ray Tracer 2/Ray Tracer 2.exe
The program begins running and will soon prompt you to enter the path for the scene definition file. When it asks "Enter Information:", you enter:
/scenes/reflect1.txt
or
/scenes/reflect2.txt
or
/scenes/refract1.txt
The program starts the ray-tracing process and then again will prompt you to enter the output path for the rendered file stored on the image plane. When it asks " Please Enter output Path and Filename:", you enter:
/scenes/myoutput1.ppm
or
/scenes/myoutput2.ppm
or
/scenes/myoutput3.ppm
You can then browse to that path and open the file in IrfanView. However, I've already created the exported files for you and placed them in the follow-ing folder:
/Book Code/Chapter 09/Ray Tracer 2/Output
The files in this folder are:
12/10/2002 11:22p 3,272,665 reflect1.ppm 12/10/2002 11:26p 3,153,601 reflect2.ppm 12/10/2002 11:34p 3,129,944 refract1.ppm
The files shown in Figures 9.12 and 9.13 are rendered using reflection and refraction lighting effects. Figure 9.12 shows two spheres rendered with diffuse interaction and mirror reflection.
Figure 9.13 shows an example of a table with a mirror and a sphere that is rendered with mirror reflection. If you look closely, you can see the table and sphere reflected in the mirror.
[ LiB ] |