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
00062
00063
00064 double r1 = ESG_DBL_RAND;
00065 double rr = r1;
00066 avgRefl = 0.;
00067
00068
00069
00070
00071
00072
00073
00074
00075 rr = r1;
00076
00077 if ((rr -= avgDiffuse) < 0.) {
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.) {
00088 Vector3 prDir;
00089 _reflection_dir(surr, prDir);
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.) {
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.) {
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
00124