MicroTrace.cpp

Go to the documentation of this file.
00001 
00012 #ifdef MT_OPENMP
00013 #include <omp.h>
00014 #endif
00015 
00019 #include <sstream>
00020 #include <iostream>
00021 
00025 #include "Image.h"
00026 
00030 #include "Object.h"
00031 #include "Scene.h"
00032 #include "Sphere.h"
00033 
00037 #include "PerspectiveCamera.h"
00038 #include "CylindricCamera.h"
00039 #include "DepthOfFieldCamera.h"
00040 
00044 #include "PointLight.h"
00045 #include "QuadAreaLight.h"
00046 
00050 #include "Texture2D.h"
00051 #include "FlatShader.h"
00052 #include "DebugShader.h"
00053 #include "EdgeShader.h"
00054 #include "FlatTransparentShader.h"
00055 #include "MirrorShader.h"
00056 #include "EyeLightShader.h"
00057 #include "PhongShader.h"
00058 #include "CloudShader.h"
00059 #include "PlasmaShader.h"
00060 #include "MarbleShader.h"
00061 #include "BumpMappedDebugShader.h"
00062 #include "BumpMappedPhongShader.h"
00063 #include "BumpMappedMarblePhongShader.h"
00064 #include "TransparentShader.h"
00065 #include "UniAxialCrystalShader.h"
00066 #include "MixShader.h"
00067 #include "MapShader.h"
00068 #include "WoodShader.h"
00069 #include "BumpMappedWoodPhongShader.h"
00070 #include "GoldShader.h"
00071 #include "SilverShader.h"
00072 #include "SteelShader.h"
00073 #include "CopperShader.h"
00074 
00078 #include "SampleGenerator.h"
00079 #include "RegularSampleGenerator.h"
00080 #include "RandomSampleGenerator.h"
00081 #include "StratifiedSampleGenerator.h"
00082 #include "PoissonDiskSampleGenerator.h"
00083 
00084 using namespace std;
00085 
00099 Object* AddObject(char* fileName, Scene& scene, bool useAcc = true, const Object::PrimitiveFactory& factory = Object::TriangleFactory() )
00100 {
00101     Object* obj = new Object(useAcc);
00102     obj->ParseOBJ(fileName, factory);
00103     obj->setColor(ColorRGBA(1,1,1));
00104     obj->BuildAccelStructure();
00105 
00106     scene.AddObject(obj);
00107 
00108     return obj;
00109 }
00110 
00119 Object* AddSphere(Sphere* sphere, Scene& scene, bool useAcc = true)
00120 {
00121     Object* obj = new Object(useAcc);
00122     obj->Add(sphere);
00123     obj->setColor(Vector3D(1,1,1));
00124     obj->BuildAccelStructure();
00125 
00126     scene.AddObject(obj);
00127 
00128     return obj;
00129 }
00130 
00146 void RenderFrame (Scene* scene, string prefix,
00147                   Vector3D pos, Vector3D dir, float angle,
00148                   int resX, int resY) 
00149 {
00150     // compute filename
00151     stringstream s;
00152     s << prefix << scene->timer.GetTime() << ".png";
00153 
00154     // print some debug info
00155     printf("render %s (%dx%d)\n", s.str().c_str(), resX, resY);
00156 
00157     // setup image
00158     Image img(resX, resY);
00159 
00160     // setup camera
00161     PerspectiveCamera camera(pos, dir, Vector3D(0,1,0), angle, resX, resY);
00162 
00163 #ifdef MT_OPENMP
00164 #pragma omp parallel
00165 {
00166 #pragma omp for schedule(dynamic) nowait
00167 #endif
00168 
00169     // now render the scene
00170     for (int y=0; y < resY; y++) {
00171     for (int x=0; x < resX; x++) {
00172         // primary ray to trace
00173         Ray ray = camera.InitRay(x, y);
00174 
00175         // ray trace one pixel 
00176             ColorRGBA color = scene->RayTrace(ray);
00177             color.normalize();
00178             img.setPixel(color, x, y);
00179     }
00180     }
00181 
00182 #ifdef MT_OPENMP
00183 }
00184 #endif
00185 
00186     // write final image
00187     img.WritePNG(s.str().c_str());
00188 }
00189 
00208 void RenderSupersampledFrame(Scene* scene, string prefix, 
00209                              Vector3D pos, Vector3D dir, float angle,
00210                              int resX, int resY, 
00211                              const SampleGenerator& sampler = SampleGenerator(), int sampleCount = 1)
00212 {    
00213     // compute filename
00214     stringstream s;
00215     s << prefix << scene->timer.GetTime() << ".png";
00216 
00217     // print some debug info
00218     printf("render supersampled %s (%dx%d)\n", s.str().c_str(), resX, resY);
00219 
00220     // setup image
00221     Image img(resX, resY);
00222 
00223     // setup camera
00224     PerspectiveCamera camera(pos, dir, Vector3D(0,1,0), angle, resX, resY);
00225 
00226 #ifdef MT_OPENMP
00227 #pragma omp parallel
00228 {
00229 #endif
00230 
00231     // prepare for supersampling 
00232     float* xv = new float[sampleCount];
00233     float* yv = new float[sampleCount];
00234     float* weight = new float[sampleCount];
00235 
00236 #ifdef MT_OPENMP
00237 #pragma omp for schedule(dynamic) nowait
00238 #endif
00239 
00240 // now render the scene
00241     for (int y=0; y < resY; y++) {
00242     for (int x=0; x < resX; x++) {
00243         ColorRGBA color(0,0,0);
00244         sampler.GetSamples(sampleCount, xv, yv, weight);
00245         for (int s=0; s < sampleCount; s++) {
00246             // primary ray to trace
00247         Ray ray = camera.InitRay(x + xv[s], y + yv[s]);
00248 
00249         // ray trace one pixel (supersampled)
00250         color = color + weight[s] * scene->RayTrace(ray);
00251         }
00252         color.normalize(); 
00253         img.setPixel(color, x, y);
00254     }
00255     }
00256 
00257     // cleanup
00258     delete [] xv;
00259     delete [] yv;
00260     delete [] weight;
00261 
00262 #ifdef MT_OPENMP
00263 }
00264 #endif
00265 
00266     // write final image
00267     img.WritePNG(s.str().c_str());
00268 }
00269 
00289 void RenderDepthOfFieldFrame(Scene* scene, string prefix, 
00290                              Vector3D pos, Vector3D dir, float angle,
00291                              int resX, int resY, 
00292                              float lensRadius, float focalDistance,
00293                              const SampleGenerator& sampler = SampleGenerator(), int sampleCount = 1)
00294 {    
00295     // compute filename
00296     stringstream s;
00297     s << prefix << scene->timer.GetTime() << ".png";
00298 
00299     // print some debug info
00300     printf("render %s (%dx%d)\n", s.str().c_str(), resX, resY);
00301 
00302     // setup image
00303     Image img(resX, resY);
00304 
00305 #ifdef MT_OPENMP
00306 #pragma omp parallel
00307 {
00308 #endif
00309 
00310     // prepare for supersampling 
00311     float* xv = new float[sampleCount];
00312     float* yv = new float[sampleCount];
00313     float* weight = new float[sampleCount];
00314 
00315 #ifdef MT_OPENMP
00316 #pragma omp for schedule(dynamic) nowait
00317 #endif
00318 
00319     // now render the scene
00320     for (int y=0; y < resY; y++) {
00321     for (int x=0; x < resX; x++) {
00322         ColorRGBA color(0,0,0);
00323         sampler.GetSamples(sampleCount, xv, yv, weight);
00324         for (int s=0; s < sampleCount; s++) {
00325                 // setup camera
00326                 DepthOfFieldCamera camera(pos, dir, Vector3D(0,1,0), angle, resX, resY, lensRadius, focalDistance, xv[s], yv[s]);
00327 
00328             // primary ray to trace
00329         Ray ray = camera.InitRay(x, y);
00330 
00331         // ray trace one pixel (supersampled)
00332         color = color + weight[s] * scene->RayTrace(ray);
00333         }
00334         color.normalize(); 
00335         img.setPixel(color, x, y);
00336     }
00337     }
00338 
00339     // cleanup
00340     delete [] xv;
00341     delete [] yv;
00342     delete [] weight;
00343 
00344 #ifdef MT_OPENMP
00345 }
00346 #endif
00347 
00348     // write final image
00349     img.WritePNG(s.str().c_str());
00350 }
00351 
00352 
00367 void RenderLinearFramePath (Scene* scene, string prefix,
00368                             Vector3D pos, Vector3D dir, float angle,
00369                             int resX, int resY, 
00370                             Vector3D path, int times)
00371 {
00372     // setup image
00373     Image img(resX, resY);
00374 
00375     for (int i=0; i < times; i++) {
00376         // compute filename
00377         stringstream s;
00378         s << prefix << scene->timer.GetTime() << ".png";
00379 
00380         // print some debug info
00381         printf("render %s (%dx%d)\n", s.str().c_str(), resX, resY);
00382 
00383         // setup camera
00384         PerspectiveCamera camera(pos + i * path, dir, Vector3D(0,1,0), angle, resX, resY);
00385 
00386 #ifdef MT_OPENMP
00387 #pragma omp parallel
00388 {
00389 #pragma omp for schedule(dynamic) nowait
00390 #endif
00391 
00392         // now render the scene
00393         for (int y=0; y < resY; y++) {
00394         for (int x=0; x < resX; x++) {
00395             // primary ray to trace
00396                 Ray ray = camera.InitRay(x, y);
00397     
00398             // ray trace one pixel 
00399                 ColorRGBA color = scene->RayTrace(ray);
00400                 color.normalize();
00401                 img.setPixel(color, x, y);
00402             }
00403         }
00404 
00405 #ifdef MT_OPENMP
00406 }
00407 #endif
00408 
00409     // write final image
00410     img.WritePNG(s.str().c_str());
00411     
00412     // next tick
00413     scene->timer.Tick();
00414     }
00415 }
00416     
00430 void RenderStereoFrame (Scene* scene, string prefix,
00431                         Vector3D pos, Vector3D dir, float angle,
00432                         int resX, int resY,
00433                         float distance = 0.01f) 
00434 {
00435     // compute filename
00436     stringstream s;
00437     s << prefix << scene->timer.GetTime() << ".png";
00438 
00439     // print some debug info
00440     printf("render %s (%dx%d)\n", s.str().c_str(), resX, resY);
00441 
00442     // setup image
00443     Image img(resX, resY);
00444 
00445     // setup cameras
00446     Vector3D greenpos = pos + Vector3D(distance,0,0);
00447     Vector3D greendir = (pos + dir) - greenpos;
00448     PerspectiveCamera red(pos, dir, Vector3D(0,1,0), angle, resX, resY);
00449     PerspectiveCamera green(greenpos, greendir, Vector3D(0,1,0), angle, resX, resY);
00450     
00451 #ifdef MT_OPENMP
00452 #pragma omp parallel
00453 {
00454 #pragma omp for schedule(dynamic) nowait
00455 #endif
00456 
00457     // now render the scene
00458     for (int y=0; y < resY; y++) {
00459     for (int x=0; x < resX; x++) {
00460         // primary ray to trace
00461         Ray redray = red.InitRay(x, y);
00462         Ray greenray = green.InitRay(x, y);
00463         
00464             // ray trace one pixel 
00465             ColorRGBA color;
00466             color.red() = scene->RayTrace(redray).average();
00467             color.green() = scene->RayTrace(greenray).average();
00468             color.normalize();
00469             img.setPixel(color, x, y);
00470     }
00471     }
00472                          
00473 #ifdef MT_OPENMP
00474 }
00475 #endif
00476 
00477     // write final image
00478     img.WritePNG(s.str().c_str());
00479 }
00480 
00489 void moveSphere(Sphere* sphere, float deltaRadius, float rotAngle, Vector3D posOffset)
00490 {
00491     rotAngle *= M_PI / 180;
00492     sphere->ChangeRadius(deltaRadius);
00493     Vector3D pos = sphere->GetPosition();
00494     sphere->SetPosition(Vector3D(posOffset.x() + (cos(rotAngle)*pos.x() + sin(rotAngle)*pos.z()), posOffset.y() + pos.y(), posOffset.z() + (-sin(rotAngle)*pos.x() + cos(rotAngle)*pos.z())));
00495 }
00496 
00504 Vector3D rotateVec(Vector3D vec, float rotAngle)
00505 {
00506     rotAngle *= M_PI / 180;
00507     return Vector3D((cos(rotAngle)*vec.x() + sin(rotAngle)*vec.z()), vec.y(), (-sin(rotAngle)*vec.x() + cos(rotAngle)*vec.z()));
00508 }
00509 
00515 void hideSphere(Sphere* sphere)
00516 {
00517     sphere->SetRadius(0.0);
00518 }
00519  
00520 #define USE_KDTREE 1
00521 
00533 #define USE_KDTREE 1
00534 int main (int argc, char **argv)
00535 {
00536     int resX, resY;
00537     if (argc > 2) {
00538         resX = atoi(argv[1]);
00539         resY = atoi(argv[2]);
00540     } else {
00541         resX = 320;
00542         resY = 256;
00543     }
00544 
00546 //  place scene description here
00547 //
00548     Scene* scene = new Scene();
00549     scene->setBgColor(Vector3D(0,0,0));
00550 //  
00551 //  setup lights
00552 //
00553     QuadAreaLight* light1 = new QuadAreaLight(ColorRGBA(250.0,250.0,250.0), Vector3D(0.1, 10.03, -20.2), Vector3D(2.0,0,0), Vector3D(0,1.5,1.5));
00554     PointLight* light2 = new PointLight(Vector3D(0, 10, 0), ColorRGBA(25));
00555 
00556     light1->SetNumberOfRays(25);
00557     scene->AddLight(light1);
00558     scene->AddLight(light2);
00559     scene->castShadows = true;
00560 //
00561 //  setup cow 
00562 //    
00563     Object* cow = AddObject("mesh/cow.obj", *scene, USE_KDTREE, Object::TexturedSmoothTriangleFactory());
00564     Texture* cowtex = new Texture2D("textures/cowspots.png");
00565     Shader* cowshader1 = new PhongShader(scene, Vector3D(0.8, 0.7, 0.6), 0, 0.8, 0.4, 12.0);
00566     cowshader1->addTexture(cowtex);
00567     Shader* cowshader2 = new BumpMappedWoodPhongShader(scene, ColorRGBA(0.9,0.9,1), 0, 1, 0, 0.5, cowtex, 0.2, Vector3D(0,0,0));
00568     Shader* cowshader3 = new PlasmaShader(scene);
00569     Shader* cowshader = new MixShader(scene, cowshader2, cowshader1);
00570     cow->setShader(cowshader1);
00571 //
00572 //  setup terrain
00573 //
00574     Object* ground = AddObject("mesh/plane.obj", *scene, USE_KDTREE, Object::TexturedSmoothTriangleFactory());
00575     Texture* bumptex = new Texture2D("textures/bump.png");
00576     bumptex->setWrapMode(Texture::REPEAT);
00577     bumptex->setInterpolationMode(Texture::LINEAR);
00578     Texture* mixmap = new Texture2D("textures/mandala.png");
00579     mixmap->setWrapMode(Texture::REPEAT);
00580     mixmap->setInterpolationMode(Texture::LINEAR);
00581     Shader* groundshader3 = new GoldShader(scene); 
00582     Shader* groundshader2 = new PhongShader(scene, ColorRGBA(0.9,0.9,1), 0, 1, 0, 0.5); 
00583     Shader* groundshader1 = new BumpMappedMarblePhongShader(scene, ColorRGBA(0,0.4,0.25), 0, 1, 0, 0.5, bumptex, 0, Vector3D(0,0,0));
00584     Shader* groundshader = new MapShader(scene, groundshader3, groundshader1, mixmap);
00585     ground->setShader(groundshader1);
00586 //
00587 //  setup sky
00588 //
00589     Object* sky = AddObject("mesh/skydome.obj", *scene, 0, Object::TexturedSmoothTriangleFactory());
00590 //  Shader* skyshader = new PlasmaShader(scene);
00591     Shader* skyshader = new CloudShader(scene);
00592     sky->setShader(skyshader);
00593 //
00594 //  setup balls
00595 //
00596     Object* b1 = AddSphere(Vector3D(-0.1,0.12,0.8), 0.05, *scene);
00597     Object* b2 = AddSphere(Vector3D(-0.1,0.11,0.6), 0.05, *scene);
00598     Object* b3 = AddSphere(Vector3D(-0.1,0.1,0.4), 0.05, *scene);
00599     Object* b4 = AddSphere(Vector3D(-0.1,0.065,0.2), 0.1, *scene);
00600     Object* b5 = AddSphere(Vector3D(-0.1,0.065,0.2), 0.05, *scene);
00601     Object* b6 = AddSphere(Vector3D(-0.1,0.05,-0.08), 0.05, *scene);
00602     Object* b7 = AddSphere(Vector3D(-0.1,0.04,-0.2), 0.05, *scene);
00603     Shader* s5 = new SilverShader(scene);
00604     Shader* s2 = new GoldShader(scene);
00605     Shader* s3 = new SteelShader(scene);
00606     Shader* s4 = new TransparentShader(scene, 1, 1.5);
00607     Shader* s1 = new BumpMappedWoodPhongShader(scene, ColorRGBA(0.9,0.9,1), 0, 1, 0, 0.5, bumptex, 0, Vector3D(0,0,0));
00608     Shader* s6 = new CopperShader(scene);
00609     Shader* s7 = new TransparentShader(scene, 1, 1.5);
00610     b1->setShader(s1);
00611     b2->setShader(s2);
00612     b3->setShader(s3);
00613     b4->setShader(s4);
00614     b5->setShader(s5);
00615     b6->setShader(s6);
00616     b7->setShader(s7);
00617 //
00618 //  end of scene description
00620    
00621 
00623 //  actual rendering
00624 //  RenderFrame(scene, "rf", Vector3D(0.35,0.1,-0.33), Vector3D(-0.1,-0.02,0.12), 60, resX, resY);
00625 //  RenderFrame(scene, "map", Vector3D(0,3,0), Vector3D(0,-1,0), 60, resX, resY);
00626 //  RenderSupersampledFrame(scene, "rssf", Vector3D(0.35,0.1,-0.33), Vector3D(-0.1,-0.02,0.12), 60, resX, resY, StratifiedSampleGenerator(), 16);
00627 //  RenderStereoFrame(scene, "rsf", Vector3D(0.35,0.1,-0.33), Vector3D(-0.1,-0.02,0.12), 60, resX, resY);
00628     float fl = (cow->center - Vector3D(0.35,0.1,-0.33)).Length();
00629     RenderDepthOfFieldFrame(scene, "rdoff", Vector3D(0.35,0.1,-0.33), Vector3D(-0.1,-0.02,0.12), 60, resX, resY, 0.001, fl, RandomSampleGenerator(), 36);
00630 //  RenderLinearFramePath(scene, "rlfp", Vector3D(0.35,0.1,-0.33), Vector3D(-0.1,-0.02,0.12), 60, resX, resY, Vector3D(0.01,0,0), 1000) ;
00632 
00633 
00635 //  cleanup unused scene data
00636     delete cowtex;
00637     delete cowshader1;
00638     delete cowshader2;
00639     delete cowshader;
00640     delete bumptex;
00641     delete groundshader;
00642     delete skyshader;
00643     delete s1;
00644     delete s2;
00645     delete s3;
00646     delete scene;
00648 }

Generated on Thu Jan 31 21:48:49 2008 for RayTracer by  doxygen 1.5.4