Reference article: http://www.cnblogs.com/miloyip/archive/2010/03/29/1698953.html This article is about the traditional ray-Tracing rendering in computer graphics, with recursive, maximum reflection number of 3, Phong Materials. (1024* 1024) running speed = 0.09 frame/sec process: 1. Set up the scene 2. The camera emits a ray 3. Trace the Ray 4. Render based on illumination model and illumination direction Features in the code: 1. The code found, using the structure of the struct to define the data used for the calculation, the search for C + + inside the struct and class basic difference is not small, the most essential is access control, struct default access control is private, in fact, Changing each struct to a class in this code can also be run. 2. In this code a large number of inline inline functions are used, and inline function usage is similar to # define, eliminating the repeated calls of functions in registers, which can be more efficient. Core structure: Vector , color, Igeometry, Imaterial, Intersectresult, Perspectivecamera, ray There are also classes that save the rendering results for the search. The entire process: by giving a test function a value, test name, function name, number of runs three information, such as: Test ("raytracerecursive", Raytracerecursive,; ) The test function framework, first defines a pixels32 picture variable, sets the size, in a For loop inside, loops the number of runs passed in so many times, start timing. This time the function name passed in, the function name is const T_PROC type variable (t_proc definition typedef void (*t_proc) (const tpixels32ref& DST), A variable that is used directly as the name of a function to run the corresponding function. Gets the FPS value to be rendered when the for count is completed, the number of runs/elapsed time. Finally, tfileoutputstream gets the data variable of the output of the picture, tbmpfile::save the way to save the photo. Artboard Test Section:
void Canvastest (const tpixels32ref& CTX) {if (Ctx.getisempty ()) Return;long w = ctx.width;long h = Ctx.height;ctx.fill Color (Color32 (0, 0, 0, 0)); color32* pixels = ctx.pdata;for (long y = 0; y < h; ++y) {for (long x = 0; x < W; ++x) {PIXELS[X].R = (UInt8) (x * 255 /w);p ixels[x].g = (UInt8) (Y * 255/h);p ixels[x].b = 0;PIXELS[X].A = 255;} (uint8*&) pixels + = Ctx.byte_width;}}
Render Depth Test section:
void renderdepth (const tpixels32ref& CTX) {if (Ctx.getisempty ()) return; Union Scene;scene.push (New Sphere (Vector3 (0, -10)), Scene.push (New Plane (Vector3 (0, 1, 0), 0)); Perspectivecamera Camera (Vector3 (0), Vector3 (0, 0,-1), Vector3 (0, 1, 0), n); Long maxDepth = 20;long W = Ctx.widt H;long h = ctx.height;ctx.fillcolor (Color32 (0, 0, 0, 0)); color32* pixels = ctx.pdata;scene.initialize (); camera.initialize (); float dx = 1.0f/w;float dy = 1.0f/h;float DD = 255. 0f/maxdepth;for (Long y = 0; y < h; ++y) {Float sy = 1-dy*y;for (long x = 0; x < W; ++x) {float SX = dx*x; Ray3 Ray (Camera.generateray (SX, SY)), intersectresult result = Scene.intersect (Ray), if (result.geometry) {UInt8 depth = ( UInt8) (255-std::min (RESULT.DISTANCE*DD, 255.0f));p IXELS[X].R = DEPTH;PIXELS[X].G = depth;pixels[x].b = Depth;pixels[x ].A = 255;}} (uint8*&) pixels + = Ctx.byte_width;}}
Render Normal Test section:
void Rendernormal (const tpixels32ref& CTX) {if (Ctx.getisempty ()) return; Sphere Scene (Vector3 (0, 10,-10), 10); Perspectivecamera Camera (Vector3 (0), Vector3 (0, 0,-1), Vector3 (0, 1, 0), n); Long maxDepth = 20;long W = Ctx.widt H;long h = ctx.height;ctx.fillcolor (Color32 (0, 0, 0, 0)); color32* pixels = ctx.pdata;scene.initialize (); camera.initialize (); float dx = 1.0f/w;float dy = 1.0f/h;float DD = 255. 0f/maxdepth;for (Long y = 0; y < h; ++y) {Float sy = 1-dy*y;for (long x = 0; x < W; ++x) {float SX = dx*x; Ray3 Ray (Camera.generateray (SX, SY)), intersectresult result = Scene.intersect (Ray), if (result.geometry) {PIXELS[X].R = (UInt8) ((result.normal.x + 1) * +);p IXELS[X].G = (UInt8) ((RESULT.NORMAL.Y + 1) *);p ixels[x].b = (UInt8) ((Result.normal.z + 1) *;p ixels[x].a = 255;}} (uint8*&) pixels + = Ctx.byte_width;}}
Ray Tracing section:
void Raytrace (const tpixels32ref& CTX) {if (Ctx.getisempty ()) return; plane* Plane = new Plane (Vector3 (0, 1, 0), 0); sphere* sphere1 = new Sphere (Vector3 (-10, 10,-10), 10); sphere* sphere2 = new Sphere (Vector3 ( -10), ten);p lane->material = new Checkermaterial (0.1f);sphere1-> Material = new Phongmaterial (color::red (), Color::white (), +), sphere2->material = new Phongmaterial (Color::blue (), Color::white (), 16); Union Scene;scene.push (plane); Scene.push (Sphere1); Scene.push (Sphere2); Perspectivecamera Camera (Vector3 (0, 5, h), Vector3 (0, 0,-1), Vector3 (0, 1, 0), n); Long w = ctx.width;long h = Ctx.heigh T;ctx.fillcolor (Color32 (0, 0, 0, 0)); color32* pixels = ctx.pdata;scene.initialize (); camera.initialize (); float dx = 1.0f/w;float dy = 1.0f/h;for (Long y = 0 ; Y < H; ++y) {Float sy = 1-dy*y;for (long x = 0; x < W; ++x) {float SX = dx*x; Ray3 Ray (Camera.generateray (SX, SY)), intersectresult result = Scene.intersect (Ray), if (result.geometry) {Color color = result.geometry-≫material->sample (Ray, Result.position, Result.normal), Color.saturate ();p IXELS[X].R = (UInt8) (COLOR.R * 255); PIXELS[X].G = (UInt8) (COLOR.G * 255);p ixels[x].b = (UInt8) (COLOR.B * 255);p ixels[x].a = 255;}} (uint8*&) pixels + = Ctx.byte_width;}}
Recursive Light tracing section:
Color raytracerecursive (igeometry* scene, const ray3& Ray, long Maxreflect) {Intersectresult result = Scene->inter Sect (Ray), if (result.geometry) {Float reflectiveness = result.geometry->material->reflectiveness; Color color = Result.geometry->material->sample (Ray, result.position, result.normal); color = color.multiply (1- reflectiveness), if ((reflectiveness > 0) && (Maxreflect > 0)) {Vector3 R = result.normal.multiply ( -2 * resul T.normal.dot (Ray.direction)). Add (Ray.direction); Ray3 ray = Ray3 (result.position, R); Color Reflectedcolor = raytracerecursive (Scene, Ray, maxReflect-1); color = Color.add (reflectedcolor.multiply ( reflectiveness));} return color;} Elsereturn color::black ();} void raytracerecursive (const tpixels32ref& CTX) {if (Ctx.getisempty ()) return; plane* Plane = new Plane (Vector3 (0, 1, 0), 0); sphere* sphere1 = new Sphere (Vector3 (-10, 10,-10), 10); sphere* sphere2 = new Sphere (Vector3 (Ten, -10), ten);p lane->material = new Checkermaterial (0.1F, 0.5); sphere1->material = new Phongmaterial (color::red (), Color::white (), +, 0.25); sphere2->material = new Phongmaterial (Color::blue (), Color::white (), 16, 0.25); Union Scene;scene.push (plane); Scene.push (Sphere1); Scene.push (Sphere2); Perspectivecamera Camera (Vector3 (0, 5, N), Vector3 (0, 0,-1), Vector3 (0, 1, 0), +); Long Maxreflect = 3;long W = Ctx.widt H;long h = ctx.height;ctx.fillcolor (Color32 (0, 0, 0, 0)); color32* pixels = ctx.pdata;scene.initialize (); camera.initialize (); float dx = 1.0f/w;float dy = 1.0f/h;for (Long y = 0 ; Y < H; ++y) {Float sy = 1-dy*y;for (long x = 0; x < W; ++x) {float SX = dx*x; Ray3 Ray (Camera.generateray (SX, SY)); Color color = raytracerecursive (&scene, Ray, Maxreflect), Color.saturate ();p IXELS[X].R = (UInt8) (COLOR.R * 255); PIXELS[X].G = (UInt8) (COLOR.G * 255);p ixels[x].b = (UInt8) (COLOR.B * 255);p ixels[x].a = 255;} (uint8*&) pixels + = Ctx.byte_width;}}
Main function Implementation test:
int main () {std::cout << "Enter enter key to start the test (you can set the process priority to" live ") >"; Waitinputchar (); Std::cout << std::endl;test (" Canvastest ", Canvastest,"), Test ("renderdepth", renderdepth, +), test ("Rendernormal", Rendernormal, $), test (" Raytrace ", Raytrace, (), Test (" raytracerecursive ", Raytracerecursive," Std::cout << std::endl << "testing done.) ; Waitinputchar (); return 0;}
Design and implementation of basic ray tracing software