PathTracing.cc

Go to the documentation of this file.
00001 #include <gra/reflection/PathTracing.h>
00002 #include <assert.h>
00003 
00004 using namespace gra;
00005 
00006 void PathTracing::_cast_the_ray(PointEnv&      surr,
00007                                 unsigned       actDepth,
00008                                 bool           firstObjHit,
00009                                 Color3f&       contrib,
00010                                 const Vector3& nDir,
00011                                 const Vector3& refl)
00012 {
00013     PointEnv* pNewSurr = _cast_ray(surr.intersection, nDir);
00014     
00015     if (!pNewSurr) {
00016         contrib.add(_background);
00017         return;
00018     }
00019 
00020     pNewSurr->energy.set(surr.energy);
00021     pNewSurr->energy.x *= refl.x;
00022     pNewSurr->energy.y *= refl.y;
00023     pNewSurr->energy.z *= refl.z;
00024     pNewSurr->mask |= ENV_HAVE_ENERGY;
00025         
00026     if (((pNewSurr->energy.x +
00027           pNewSurr->energy.y +
00028           pNewSurr->energy.z) / 3.) > _minRayWeight)
00029     {
00030         _illuminate(*pNewSurr, actDepth+1, firstObjHit, contrib);
00031     }
00032     
00033     delete pNewSurr;
00034 }
00035 
00036 void PathTracing::_cast_secondary_rays(PointEnv&   surr,
00037                                        unsigned    actDepth,
00038                                        bool        firstObjHit,
00039                                        Color3f&    contribution,
00040                                        MatVisitor& matVisitor)
00041 {
00042     Vector3       nDir;
00043     Color3f       contrib(0.,0.,0);
00044     double        avgRefl;
00045     Vector3       refl;
00046     DiffuseBRDF*  pDiffBRDF     = surr.pVisitableObj->diffuseBRDF();
00047     SpecularBRDF* pSpecBRDF     = surr.pVisitableObj->specularBRDF();
00048     double        avgReflection = matVisitor.avgReflection();
00049     double        avgTransp     = matVisitor.avgTransparency();
00050     double        avgSpecular   = 0.;
00051     double        avgDiffuse    = 0.;
00052 
00053     if (!pDiffBRDF) pDiffBRDF   = _pDiffuseBRDF;
00054     if (!pSpecBRDF) pSpecBRDF   = _pSpecularBRDF;
00055     if (pDiffBRDF)  avgDiffuse  = matVisitor.avgDiffuse();
00056     if (pSpecBRDF)  avgSpecular = matVisitor.avgSpecular();
00057 
00058     for (unsigned i = 0; i < _photonsPerSurface; i++) {
00059 
00060         /*
00061          * Russian roulette
00062          */
00063 
00064         double r1 = ESG_DBL_RAND;
00065         double rr = r1;
00066         avgRefl = 0.;
00067         
00068         // rescale the [0,1) random number to [0,max_reflection)
00069         //double avgRR = (pBRDF->avgReflectance(matVisitor) +
00070         //      matVisitor.avgReflection() +
00071         //      matVisitor.avgTransparency());
00072         //r1 *= avgRR;
00073         //r1 *= avgRR + _refraction;
00074 
00075         rr = r1;
00076 
00077         if ((rr -= avgDiffuse) < 0.) { // sample diffuse BRDF
00078             pDiffBRDF->importanceSample(matVisitor,
00079                                         surr.normal,
00080                                         r1,
00081                                         ESG_DBL_RAND, 
00082                                         nDir,
00083                                         NULL);
00084             refl.set(matVisitor.diffuse());
00085             refl.scale(1. / avgDiffuse);
00086             _cast_the_ray(surr, actDepth, true, contrib, nDir, refl);
00087         } else if ((rr -= avgSpecular) < 0.) { // sample specular BRDF
00088             Vector3 prDir;
00089             _reflection_dir(surr, prDir); // prefered dir.
00090             pSpecBRDF->importanceSample(matVisitor,
00091                                         prDir,
00092                                         r1,
00093                                         ESG_DBL_RAND, 
00094                                         nDir,
00095                                         NULL);
00096             refl.set(matVisitor.specular());
00097             refl.scale(1. / avgSpecular);
00098             _cast_the_ray(surr, actDepth, true, contrib, nDir, refl);
00099         } else if ((rr -= avgReflection) < 0.) { // sample mirror reflection
00100             _reflection_dir(surr, nDir);
00101             refl.set(matVisitor.reflection());
00102             refl.scale(1. / avgReflection);
00103             _cast_the_ray(surr, actDepth, true, contrib, nDir, refl);
00104         } else if ((rr -= avgTransp) < 0.) { // sample refraction
00105             bool foh = ((_refraction_dir(surr,
00106                                          matVisitor,
00107                                          firstObjHit,
00108                                          nDir)
00109                          == RayTracing::REFR_DIR_REFLECTION)
00110                         ? false
00111                         : !firstObjHit);
00112             refl.set(matVisitor.transparency());
00113             refl.scale(1. / avgTransp);
00114             _cast_the_ray(surr, actDepth, foh, contrib, nDir, refl);
00115         } 
00116     }
00117     
00118     contrib.scale(1./_photonsPerSurface);
00119     contribution.add(contrib);
00120 }
00121 
00122 
00123 // --------- public ----------------
00124 

Generated on Tue Nov 21 15:11:42 2006 for gra by  doxygen 1.4.6