00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "exphotonmap.h"
00025 #include "bxdf.h"
00026 #include "light.h"
00027 #include "paramset.h"
00028 #include "spectrumwavelengths.h"
00029 #include "dynload.h"
00030 #include "camera.h"
00031 #include "mc.h"
00032
00033 #include <boost/thread/xtime.hpp>
00034
00035 using namespace lux;
00036
00037 ExPhotonIntegrator::ExPhotonIntegrator(RenderingMode rm, LightStrategy st,
00038 int ndir, int ncaus, int nindir, int nrad, int nl,
00039 int mdepth, int mpdepth, float mdist, bool fg, int gs, float ga,
00040 PhotonMapRRStrategy rrstrategy, float rrcontprob, float distThreshold,
00041 string *mapsfn, bool dbgEnableDirect, bool dbgUseRadianceMap,
00042 bool dbgEnableCaustic, bool dbgEnableIndirect, bool dbgEnableSpecular)
00043 {
00044 renderingMode = rm;
00045 lightStrategy = st;
00046
00047 nDirectPhotons = ndir;
00048 nCausticPhotons = ncaus;
00049 nIndirectPhotons = nindir;
00050 nRadiancePhotons = nrad;
00051
00052 nLookup = nl;
00053 maxDistSquared = mdist * mdist;
00054 maxDepth = mdepth;
00055 maxPhotonDepth = mpdepth;
00056 causticMap = indirectMap = NULL;
00057 radianceMap = NULL;
00058 finalGather = fg;
00059 gatherSamples = gs;
00060 cosGatherAngle = cos(Radians(ga));
00061
00062 rrStrategy = rrstrategy;
00063 rrContinueProbability = rrcontprob;
00064
00065 distanceThreshold = distThreshold;
00066
00067 mapsFileName = mapsfn;
00068
00069 debugEnableDirect = dbgEnableDirect;
00070 debugUseRadianceMap = dbgUseRadianceMap;
00071 debugEnableCaustic = dbgEnableCaustic;
00072 debugEnableIndirect = dbgEnableIndirect;
00073 debugEnableSpecular = dbgEnableSpecular;
00074 }
00075
00076 ExPhotonIntegrator::~ExPhotonIntegrator()
00077 {
00078 delete mapsFileName;
00079 delete causticMap;
00080 delete indirectMap;
00081 delete radianceMap;
00082 }
00083
00084 void ExPhotonIntegrator::RequestSamples(Sample *sample, const Scene *scene)
00085 {
00086 if (lightStrategy == SAMPLE_AUTOMATIC) {
00087 if (scene->lights.size() > 5)
00088 lightStrategy = SAMPLE_ONE_UNIFORM;
00089 else
00090 lightStrategy = SAMPLE_ALL_UNIFORM;
00091 }
00092
00093
00094 if (renderingMode == RM_DIRECTLIGHTING) {
00095 vector<u_int> structure;
00096
00097 structure.push_back(2);
00098 structure.push_back(1);
00099 structure.push_back(2);
00100 structure.push_back(1);
00101
00102 structure.push_back(2);
00103 structure.push_back(1);
00104
00105 sampleOffset = sample->AddxD(structure, maxDepth + 1);
00106
00107 if (finalGather) {
00108
00109
00110
00111
00112 structure.clear();
00113 structure.push_back(2);
00114 structure.push_back(1);
00115 if (rrStrategy != RR_NONE)
00116 structure.push_back(1);
00117 sampleFinalGather1Offset = sample->AddxD(structure, gatherSamples);
00118
00119 structure.clear();
00120 structure.push_back(2);
00121 structure.push_back(1);
00122 if (rrStrategy != RR_NONE)
00123 structure.push_back(1);
00124 sampleFinalGather2Offset = sample->AddxD(structure, gatherSamples);
00125 }
00126 } else if (renderingMode == RM_PATH) {
00127 vector<u_int> structure;
00128 structure.push_back(2);
00129 structure.push_back(1);
00130 structure.push_back(2);
00131 structure.push_back(1);
00132 structure.push_back(2);
00133 structure.push_back(1);
00134 structure.push_back(2);
00135 structure.push_back(1);
00136
00137 if (rrStrategy != RR_NONE)
00138 structure.push_back(1);
00139
00140 sampleOffset = sample->AddxD(structure, maxDepth + 1);
00141 } else
00142 BOOST_ASSERT(false);
00143 }
00144
00145 void ExPhotonIntegrator::Preprocess(const TsPack *tspack, const Scene *scene) {
00146
00147 BufferType type = BUF_TYPE_PER_PIXEL;
00148 scene->sampler->GetBufferType(&type);
00149 bufferId = scene->camera->film->RequestBuffer(type, BUF_FRAMEBUFFER, "eye");
00150
00151
00152 causticMap = new LightPhotonMap(nLookup, maxDistSquared);
00153 indirectMap = new LightPhotonMap(nLookup, maxDistSquared);
00154
00155 if (finalGather)
00156 radianceMap = new RadiancePhotonMap(nLookup, maxDistSquared);
00157 else {
00158 nDirectPhotons = 0;
00159 nRadiancePhotons = 0;
00160 }
00161
00162 PhotonMapPreprocess(tspack, scene, mapsFileName,
00163 BxDFType(BSDF_DIFFUSE | BSDF_GLOSSY | BSDF_REFLECTION | BSDF_TRANSMISSION),
00164 BxDFType(BSDF_ALL),
00165 nDirectPhotons, nRadiancePhotons, radianceMap, nIndirectPhotons,
00166 indirectMap, nCausticPhotons, causticMap, maxPhotonDepth);
00167 }
00168
00169 int ExPhotonIntegrator::Li(const TsPack *tspack, const Scene *scene,
00170 const Sample *sample) const
00171 {
00172 RayDifferential ray;
00173 float rayWeight = tspack->camera->GenerateRay(*sample, &ray);
00174 if (rayWeight > 0.f) {
00175
00176 ++(sample->imageX);
00177 float wt1 = tspack->camera->GenerateRay(*sample, &ray.rx);
00178 --(sample->imageX);
00179 ++(sample->imageY);
00180 float wt2 = tspack->camera->GenerateRay(*sample, &ray.ry);
00181 ray.hasDifferentials = (wt1 > 0.f) && (wt2 > 0.f);
00182 --(sample->imageY);
00183 }
00184
00185 SWCSpectrum L(0.f);
00186 float alpha = 1.f;
00187 switch(renderingMode) {
00188 case RM_DIRECTLIGHTING:
00189 L = LiDirectLightingMode(tspack, scene, ray, sample, &alpha, 0, true);
00190 break;
00191 case RM_PATH:
00192 L = LiPathMode(tspack, scene, ray, sample, &alpha);
00193 break;
00194 default:
00195 BOOST_ASSERT(false);
00196 }
00197
00198 sample->AddContribution(sample->imageX, sample->imageY,
00199 L.ToXYZ(tspack) * rayWeight, alpha, bufferId);
00200
00201 return 1;
00202 }
00203
00204 SWCSpectrum ExPhotonIntegrator::LiDirectLightingMode(const TsPack *tspack,
00205 const Scene *scene, const RayDifferential &ray, const Sample *sample,
00206 float *alpha, const int reflectionDepth, const bool specularBounce) const
00207 {
00208
00209 SWCSpectrum L(0.f);
00210
00211 Intersection isect;
00212 if (scene->Intersect(ray, &isect)) {
00213
00214 float *sampleData = sample->sampler->GetLazyValues(const_cast<Sample *>(sample), sampleOffset, reflectionDepth);
00215 float *lightSample = &sampleData[0];
00216 float *bsdfSample = &sampleData[3];
00217 float *bsdfComponent = &sampleData[5];
00218
00219 float *reflectionSample = &sampleData[6];
00220 float *reflectionComponent = &sampleData[8];
00221
00222 float *lightNum = &sampleData[2];
00223
00224 Vector wo = -ray.d;
00225
00226
00227 if (specularBounce)
00228 L += isect.Le(tspack, wo);
00229
00230
00231 BSDF *bsdf = isect.GetBSDF(tspack, ray);
00232 const Point &p = bsdf->dgShading.p;
00233 const Normal &ns = bsdf->dgShading.nn;
00234 const Normal &ng = isect.dg.nn;
00235
00236 if (debugEnableDirect) {
00237
00238 switch (lightStrategy) {
00239 case SAMPLE_ALL_UNIFORM:
00240 L += UniformSampleAllLights(tspack,
00241 scene, p, ns, wo, bsdf, sample,
00242 lightSample, lightNum,
00243 bsdfSample, bsdfComponent);
00244 break;
00245 case SAMPLE_ONE_UNIFORM: {
00246 SWCSpectrum Ld;
00247 UniformSampleOneLight(tspack, scene, p,
00248 ns, wo, bsdf, sample,
00249 lightSample, lightNum,
00250 bsdfSample, bsdfComponent, &Ld);
00251 L += Ld;
00252 break;
00253 }
00254 default:
00255 break;
00256 }
00257 }
00258
00259 if (debugUseRadianceMap) {
00260
00261 Normal nGather = ng;
00262 if (Dot(nGather, wo) < 0.f)
00263 nGather = -nGather;
00264
00265 NearPhotonProcess<RadiancePhoton> proc(p, nGather);
00266 float md2 = radianceMap->maxDistSquared;
00267
00268 radianceMap->lookup(p, proc, md2);
00269 if (proc.photon)
00270 L += proc.photon->GetSWCSpectrum(tspack, 1);
00271 }
00272
00273 if (debugEnableCaustic && (!causticMap->isEmpty())) {
00274
00275 L += causticMap->LDiffusePhoton(tspack, bsdf, isect, wo);
00276 }
00277
00278 if (debugEnableIndirect) {
00279 if (finalGather)
00280 L += PhotonMapFinalGatherWithImportaceSampling(
00281 tspack, scene, sample,
00282 sampleFinalGather1Offset,
00283 sampleFinalGather2Offset, gatherSamples,
00284 cosGatherAngle, rrStrategy,
00285 rrContinueProbability, indirectMap,
00286 radianceMap, wo, bsdf,
00287 BxDFType(BSDF_DIFFUSE | BSDF_REFLECTION | BSDF_TRANSMISSION));
00288 else
00289 L += indirectMap->LDiffusePhoton(tspack, bsdf, isect, wo);
00290 }
00291
00292 if (debugEnableSpecular && (reflectionDepth < maxDepth)) {
00293 float u1 = reflectionSample[0];
00294 float u2 = reflectionSample[1];
00295 float u3 = reflectionComponent[0];
00296
00297 Vector wi;
00298 float pdf;
00299 SWCSpectrum f;
00300 BxDFType sampledType;
00301
00302 if (bsdf->Sample_f(tspack, wo, &wi, u1, u2, u3, &f, &pdf,
00303 BxDFType(BSDF_REFLECTION | BSDF_TRANSMISSION | BSDF_SPECULAR | BSDF_GLOSSY), &sampledType, NULL, true)) {
00304
00305 RayDifferential rd(p, wi);
00306 rd.hasDifferentials = true;
00307 rd.rx.o = p + isect.dg.dpdx;
00308 rd.ry.o = p + isect.dg.dpdy;
00309 if (sampledType & BSDF_REFLECTION) {
00310
00311 Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx +
00312 bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
00313 Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy +
00314 bsdf->dgShading.dndv * bsdf->dgShading.dvdy;
00315 Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo;
00316 float dDNdx = Dot(dwodx, ns) + Dot(wo, dndx);
00317 float dDNdy = Dot(dwody, ns) + Dot(wo, dndy);
00318 rd.rx.d = wi -
00319 dwodx + 2 * Vector(Dot(wo, ns) * dndx +
00320 dDNdx * ns);
00321 rd.ry.d = wi -
00322 dwody + 2 * Vector(Dot(wo, ns) * dndy +
00323 dDNdy * ns);
00324 } else if (sampledType & BSDF_TRANSMISSION) {
00325
00326 float eta = bsdf->eta;
00327 Vector w = -wo;
00328 if (Dot(wo, ns) < 0)
00329 eta = 1.f / eta;
00330
00331 Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx + bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
00332 Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy + bsdf->dgShading.dndv * bsdf->dgShading.dvdy;
00333
00334 Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo;
00335 float dDNdx = Dot(dwodx, ns) + Dot(wo, dndx);
00336 float dDNdy = Dot(dwody, ns) + Dot(wo, dndy);
00337
00338 float mu = eta * Dot(w, ns) - Dot(wi, ns);
00339 float dmudx = (eta - (eta * eta * Dot(w, ns)) / Dot(wi, ns)) * dDNdx;
00340 float dmudy = (eta - (eta * eta * Dot(w, ns)) / Dot(wi, ns)) * dDNdy;
00341
00342 rd.rx.d = wi + eta * dwodx - Vector(mu * dndx + dmudx * ns);
00343 rd.ry.d = wi + eta * dwody - Vector(mu * dndy + dmudy * ns);
00344 }
00345 L += LiDirectLightingMode(tspack, scene, rd,
00346 sample, alpha, reflectionDepth + 1,
00347 (sampledType & BSDF_SPECULAR) != 0) *
00348 f * (AbsDot(wi, ns) / pdf);
00349 }
00350 }
00351 } else {
00352
00353 if (specularBounce) {
00354 for (u_int i = 0; i < scene->lights.size(); ++i)
00355 L += scene->lights[i]->Le(tspack, ray);
00356 }
00357
00358 if (reflectionDepth == 0)
00359 *alpha = 0.f;
00360 }
00361
00362 scene->volumeIntegrator->Transmittance(tspack, scene, ray, sample, alpha, &L);
00363 SWCSpectrum Lv;
00364 scene->volumeIntegrator->Li(tspack, scene, ray, sample, &Lv, alpha);
00365 return L + Lv;
00366 }
00367
00368 SWCSpectrum ExPhotonIntegrator::LiPathMode(const TsPack *tspack,
00369 const Scene *scene, const RayDifferential &r, const Sample *sample,
00370 float *alpha) const
00371 {
00372 SWCSpectrum L(0.f);
00373
00374
00375 RayDifferential ray(r);
00376 SWCSpectrum pathThroughput(1.f);
00377 XYZColor color;
00378 bool specularBounce = true, specular = true;
00379
00380 for (int pathLength = 0; ; ++pathLength) {
00381
00382 Intersection isect;
00383 if (!scene->Intersect(ray, &isect)) {
00384
00385 SWCSpectrum Lv;
00386 scene->volumeIntegrator->Li(tspack, scene, ray, sample, &Lv, alpha);
00387 Lv *= pathThroughput;
00388 L += Lv;
00389
00390
00391 if (specularBounce) {
00392 scene->volumeIntegrator->Transmittance(tspack, scene, ray, sample, alpha, &pathThroughput);
00393
00394 SWCSpectrum Le(0.f);
00395 for (u_int i = 0; i < scene->lights.size(); ++i)
00396 Le += scene->lights[i]->Le(tspack, ray);
00397 L += Le * pathThroughput;
00398 }
00399
00400
00401 if (pathLength == 0)
00402 *alpha = 0.f;
00403 break;
00404 }
00405 if (pathLength == 0)
00406 r.maxt = ray.maxt;
00407
00408 SWCSpectrum Lv;
00409 scene->volumeIntegrator->Li(tspack, scene, ray, sample, &Lv, alpha);
00410 Lv *= pathThroughput;
00411 L += Lv;
00412
00413 scene->volumeIntegrator->Transmittance(tspack, scene, ray, sample, alpha, &pathThroughput);
00414
00415 SWCSpectrum currL(0.f);
00416
00417
00418 Vector wo(-ray.d);
00419 if (specularBounce)
00420 currL += isect.Le(tspack, wo);
00421
00422 if (pathLength == maxDepth) {
00423 L += currL * pathThroughput;
00424 break;
00425 }
00426
00427
00428 float *sampleData = sample->sampler->GetLazyValues(const_cast<Sample *>(sample), sampleOffset, pathLength);
00429 float *lightSample = &sampleData[0];
00430 float *bsdfSample = &sampleData[3];
00431 float *bsdfComponent = &sampleData[5];
00432 float *pathSample = &sampleData[6];
00433 float *pathComponent = &sampleData[8];
00434 float *indirectSample = &sampleData[9];
00435 float *indirectComponent = &sampleData[11];
00436
00437 float *lightNum = &sampleData[2];
00438
00439 float *rrSample;
00440 if (rrStrategy != RR_NONE)
00441 rrSample = &sampleData[12];
00442 else
00443 rrSample = NULL;
00444
00445
00446 BSDF *bsdf = isect.GetBSDF(tspack, ray);
00447
00448 const Point &p = bsdf->dgShading.p;
00449 const Normal &n = bsdf->dgShading.nn;
00450
00451
00452 if (debugEnableDirect) {
00453 switch (lightStrategy) {
00454 case SAMPLE_ALL_UNIFORM:
00455 currL += UniformSampleAllLights(tspack,
00456 scene, p, n, wo, bsdf, sample,
00457 lightSample, lightNum,
00458 bsdfSample, bsdfComponent);
00459 break;
00460 case SAMPLE_ONE_UNIFORM: {
00461 SWCSpectrum Ld;
00462 UniformSampleOneLight(tspack, scene, p,
00463 n, wo, bsdf, sample,
00464 lightSample, lightNum,
00465 bsdfSample, bsdfComponent, &Ld);
00466 currL += Ld;
00467 break;
00468 }
00469 default:
00470 BOOST_ASSERT(false);
00471 }
00472 }
00473
00474 if (debugUseRadianceMap) {
00475
00476 currL += radianceMap->LPhoton(tspack, isect, wo, BSDF_ALL);
00477 }
00478
00479 bool sampledDiffuse = true;
00480
00481
00482 if (debugEnableIndirect) {
00483 BxDFType diffuseType =
00484 BxDFType(BSDF_REFLECTION | BSDF_TRANSMISSION | BSDF_DIFFUSE);
00485 if (bsdf->NumComponents(diffuseType) > 0) {
00486
00487
00488
00489 if (specular) {
00490 Vector wi;
00491 float u1 = indirectSample[0];
00492 float u2 = indirectSample[1];
00493 float u3 = indirectComponent[0];
00494 float pdf;
00495 SWCSpectrum fr;
00496 if (bsdf->Sample_f(tspack, wo, &wi, u1, u2, u3, &fr, &pdf, diffuseType, NULL, NULL, true)) {
00497 RayDifferential bounceRay(p, wi);
00498
00499 Intersection gatherIsect;
00500 if (scene->Intersect(bounceRay, &gatherIsect)) {
00501
00502
00503
00504
00505 if (bounceRay.maxt > distanceThreshold) {
00506
00507 SWCSpectrum Lindir = radianceMap->LPhoton(tspack, gatherIsect,
00508 -bounceRay.d, BSDF_ALL);
00509 if (!Lindir.Black()) {
00510 scene->Transmittance(tspack, bounceRay, sample, &Lindir);
00511 currL += fr * Lindir * (AbsDot(wi, n) / pdf);
00512 }
00513 } else {
00514
00515
00516
00517 sampledDiffuse = false;
00518 }
00519 }
00520 }
00521 } else {
00522 currL += indirectMap->LDiffusePhoton(tspack, bsdf, isect, wo);
00523 }
00524 }
00525 }
00526
00527 BxDFType componentsToSample = BSDF_ALL;
00528 if (sampledDiffuse) {
00529
00530 if (debugEnableCaustic && (!causticMap->isEmpty())) {
00531 currL += causticMap->LDiffusePhoton(tspack, bsdf, isect, wo);
00532 }
00533
00534 componentsToSample = BxDFType(componentsToSample & (~BSDF_DIFFUSE));
00535 }
00536 if (!debugEnableSpecular)
00537 componentsToSample = BxDFType(componentsToSample & (~(BSDF_GLOSSY & BSDF_SPECULAR)));
00538
00539 L += currL * pathThroughput;
00540
00541 if (bsdf->NumComponents(componentsToSample) == 0)
00542 break;
00543
00544
00545 Vector wi;
00546 float pdf;
00547 BxDFType sampledType;
00548 SWCSpectrum f;
00549 if (!bsdf->Sample_f(tspack, wo, &wi, pathSample[0], pathSample[1], pathComponent[0],
00550 &f, &pdf, componentsToSample, &sampledType, NULL, true))
00551 break;
00552
00553 const float dp = AbsDot(wi, n) / pdf;
00554
00555
00556 if (pathLength > 3) {
00557 if (rrStrategy == RR_EFFICIENCY) {
00558 const float q = min<float>(1.f, f.Filter(tspack) * dp);
00559 if (q < rrSample[0])
00560 break;
00561
00562 pathThroughput /= q;
00563 } else if (rrStrategy == RR_PROBABILITY) {
00564 if (rrContinueProbability < rrSample[0])
00565 break;
00566
00567 pathThroughput /= rrContinueProbability;
00568 }
00569 }
00570
00571 specularBounce = (sampledType & BSDF_SPECULAR) != 0;
00572 specular = specular && specularBounce;
00573 pathThroughput *= f;
00574 pathThroughput *= dp;
00575
00576 ray = RayDifferential(p, wi);
00577 }
00578
00579 return L;
00580 }
00581
00582 SurfaceIntegrator* ExPhotonIntegrator::CreateSurfaceIntegrator(const ParamSet ¶ms) {
00583 LightStrategy estrategy;
00584 string st = params.FindOneString("strategy", "auto");
00585 if (st == "one") estrategy = SAMPLE_ONE_UNIFORM;
00586 else if (st == "all") estrategy = SAMPLE_ALL_UNIFORM;
00587 else if (st == "auto") estrategy = SAMPLE_AUTOMATIC;
00588 else {
00589 std::stringstream ss;
00590 ss<<"Strategy '"<<st<<"' for direct lighting unknown. Using \"auto\".";
00591 luxError(LUX_BADTOKEN,LUX_WARNING,ss.str().c_str());
00592 estrategy = SAMPLE_AUTOMATIC;
00593 }
00594
00595 int maxDepth = params.FindOneInt("maxdepth", 5);
00596 int maxPhotonDepth = params.FindOneInt("maxphotondepth", 10);
00597
00598 int nDirect = params.FindOneInt("directphotons", 200000);
00599 int nCaustic = params.FindOneInt("causticphotons", 20000);
00600 int nIndirect = params.FindOneInt("indirectphotons", 200000);
00601 int nRadiance = params.FindOneInt("radiancephotons", 200000);
00602
00603 int nUsed = params.FindOneInt("nphotonsused", 50);
00604 float maxDist = params.FindOneFloat("maxphotondist", 0.5f);
00605
00606 bool finalGather = params.FindOneBool("finalgather", true);
00607
00608
00609 int gatherSamples = params.FindOneInt("finalgathersamples", 32) / 2;
00610
00611 string smode = params.FindOneString("renderingmode", "directlighting");
00612
00613 RenderingMode renderingMode;
00614 if (smode == "directlighting") renderingMode = RM_DIRECTLIGHTING;
00615 else if (smode == "path") {
00616 renderingMode = RM_PATH;
00617 finalGather = true;
00618 } else {
00619 std::stringstream ss;
00620 ss<<"Strategy '" << smode << "' for rendering mode unknown. Using \"path\".";
00621 luxError(LUX_BADTOKEN,LUX_WARNING,ss.str().c_str());
00622 renderingMode = RM_PATH;
00623 }
00624
00625 float gatherAngle = params.FindOneFloat("gatherangle", 10.0f);
00626
00627 PhotonMapRRStrategy rstrategy;
00628 string rst = params.FindOneString("rrstrategy", "efficiency");
00629 if (rst == "efficiency") rstrategy = RR_EFFICIENCY;
00630 else if (rst == "probability") rstrategy = RR_PROBABILITY;
00631 else if (rst == "none") rstrategy = RR_NONE;
00632 else {
00633 std::stringstream ss;
00634 ss<<"Strategy '"<<st<<"' for russian roulette path termination unknown. Using \"efficiency\".";
00635 luxError(LUX_BADTOKEN,LUX_WARNING,ss.str().c_str());
00636 rstrategy = RR_EFFICIENCY;
00637 }
00638
00639 float rrcontinueProb = params.FindOneFloat("rrcontinueprob", 0.65f);
00640
00641 float distanceThreshold = params.FindOneFloat("distancethreshold", maxDist * 1.25f);
00642
00643 string *mapsFileName = NULL;
00644 string sfn = params.FindOneString("photonmapsfile", "");
00645 if (sfn != "")
00646 mapsFileName = new string(sfn);
00647
00648 bool debugEnableDirect = params.FindOneBool("dbg_enabledirect", true);
00649 bool debugUseRadianceMap = params.FindOneBool("dbg_enableradiancemap", false);
00650 bool debugEnableCaustic = params.FindOneBool("dbg_enableindircaustic", true);
00651 bool debugEnableIndirect = params.FindOneBool("dbg_enableindirdiffuse", true);
00652 bool debugEnableSpecular = params.FindOneBool("dbg_enableindirspecular", true);
00653
00654 return new ExPhotonIntegrator(renderingMode, estrategy,
00655 nDirect, nCaustic, nIndirect, nRadiance,
00656 nUsed, maxDepth, maxPhotonDepth, maxDist, finalGather, gatherSamples, gatherAngle,
00657 rstrategy, rrcontinueProb,
00658 distanceThreshold,
00659 mapsFileName,
00660 debugEnableDirect, debugUseRadianceMap, debugEnableCaustic,
00661 debugEnableIndirect, debugEnableSpecular);
00662 }
00663
00664 static DynamicLoader::RegisterSurfaceIntegrator<ExPhotonIntegrator> r("exphotonmap");