/* Author: Jonathan Brumberg Date : April 6, 2006 File : p3.cpp */ /* Main file for application of Photon Map and Ray Tracer to rendering a Cornell Box via global illumination */ #include #include #include #include #include #include #include #include "RtObject.h" #include "Intersection.h" #include "Box.h" #include "BoundingBox.h" #include "Sphere.h" #include "BoxIntersection.h" #include "SphereIntersection.h" #include "Vector.h" #include "Ray.h" #include "PhotonMap.h" #include "jpegUI.h" #define WIDTH 600 #define HEIGHT 600 #define IM_WIDTH 400 #define IM_HEIGHT 400 #define NUM_PHOTONS 50000 #define DRAW_PHOT_MAP 1 #define MAX_PHOTON_DEPTH 5 #define MAX_PHOTONS NUM_PHOTONS*MAX_PHOTON_DEPTH #define DEBUG 0 #define NUM_RAYS IM_WIDTH*IM_HEIGHT float rtImg[IM_HEIGHT][IM_WIDTH][3]; // Ray trace rendering buffer float photImg[IM_HEIGHT][IM_WIDTH][3]; // Photon map rendering buffer int rendWindow; int photWindow; int rtWindow; Vector Isource(0.6,0.6,0.6); // light source for just Ray Tracing Vector light(0.5,1.0,-1.5); // light source center position Ray eyeRays[NUM_RAYS]; // Array of eye rays for ray tracing BoundingBox boundVol; // Bounding volume Box boxObj; // Box scene object Sphere sphereObj; // Sphere scene object PhotonMap pm(MAX_PHOTONS); // Photon map data structure Ray photRays[NUM_PHOTONS]; // Photon rays used to trace photon paths void tracePhoton(Ray pr, Vector power, int depth); void traceRay(Ray r); /*--------------------------------------------------*/ void initPhotonRays(void) { int i=0; float x,y,z; Vector power(1.0,1.0,1.0); Vector offset; printf("Tracing Photons\n"); for(i=0;i1 || y==0); photRays[i].setDirection(x,y,z); photRays[i].normalize(); /* store photons are origin for light source rendering */ pm.store(power.getVector(), photRays[i].getOrigin().getVector(), photRays[i].getDirection().getVector()); /* trace photons through scene */ tracePhoton(photRays[i],power,0); } /* photon map, kd-tree must be balanced before use */ pm.balance(); pm.scale_photon_power(1.0/NUM_PHOTONS); if(DEBUG) { printf("\n"); printf("Balanced!!!\n"); } } /*--------------------------------------------------*/ Vector diffuseReflection(Vector N) { float x,y,z; Vector dir; /* reject any direction that is opposite to the surface normal */ do { /* determine new direction by rejection sampling */ do { x=1.0*rand()/RAND_MAX; y=1.0*rand()/RAND_MAX; z=1.0*rand()/RAND_MAX; } while(x*x+y*y+z*z>1); x=2*(x-0.5); y=2*(y-0.5); z=2*(z-0.5); dir.setVector(x,y,z); } while(dir*N>=0); return dir; } /*--------------------------------------------------*/ void tracePhoton(Ray pr, Vector power, int depth) { Vector reflect_power; // reflected photon power float kd_avg, k_rand; // average diffuse reflectance Vector kd, N; /* local copies of normal vectors and reflectance */ BoxIntersection boundInt; /* bounding volume intersection storage */ BoxIntersection boxInt; /* box object intersection storage */ SphereIntersection sphereInt; /* sphere object intersection storage */ float t; Vector Rt; if(DEBUG) { printf("depth: %d\n",depth); } /* Test for maximum reflection depth */ if(depth