void PhotonMap::BuildIndirectPhotonMap(int32_t n) { for ( LightIter iter = scene->mLights.begin(); iter != scene->mLights.end(); iter++ ) { Light *light = *iter; int32_t nPhotons = (int) (n * light->mIntensity); for ( int32_t i = 0; i < nPhotons; i++ ) { Color color; Vector pi, dir; Shape *shape = NULL; while ( true ) { if ( confEnableDirectedPhotons ) { Vector r(gRandom.Rand(), gRandom.Rand(), gRandom.Rand()); dir = confPhotonDirectedP1 + r * (confPhotonDirectedP2 - confPhotonDirectedP1) - light->GetCentroid(); dir.Normalize(); } else { dir = light->RandomDirection(gRandom); } float dist = MAXDISTANCE; if ( scene->FindNearest(Ray(light->GetCentroid(), dir), dist, shape) == IR_MISS ) continue; pi = light->GetCentroid() + dir * dist; color = light->Sample(pi); if ( !color.IsBlack() ) break; } ShootIndirectPhoton(dir, pi, color, shape, 0); } } }
void PhotonMap::BuildCausticsPhotonMap(int32_t n) { vector<Shape *> causticsShapes; uint32_t causticsCount; for ( ShapeIter iter = scene->mShapes.begin(); iter != scene->mShapes.end(); iter++ ) { Shape *shape = *iter; if ( shape->GetType() == SHAPE_TRIANGLE ) continue; if ( shape->mMaterial->MatchesBSDFFlags(BSDF_SPECULAR) ) { causticsShapes.push_back(shape); } } causticsCount = causticsShapes.size(); if ( causticsCount == 0 ) { Warning("No caustics shape."); return; } for ( LightIter iter = scene->mLights.begin(); iter != scene->mLights.end(); iter++ ) { Light *light = *iter; int32_t nPhotons = static_cast<int>(n * light->mIntensity); for ( int i = 0; i < nPhotons; i++ ) { Color color; Vector pi; Vector dir; Shape *shape = NULL; while ( true ) { uint32_t shapeNr = static_cast<uint32_t>(gRandom.Rand() * causticsCount); if ( shapeNr == causticsCount ) shapeNr = causticsCount-1; Shape *causticsShape = causticsShapes[shapeNr]; AABB box = causticsShape->GetAABB(); Vector r(gRandom.Rand(), gRandom.Rand(), gRandom.Rand()); dir = box.mPos + box.mSize * r - light->GetCentroid(); dir.Normalize(); float dist = MAXDISTANCE; if ( scene->FindNearest(Ray(light->GetCentroid(), dir), dist, shape) == IR_MISS ) continue; pi = light->GetCentroid() + dir * dist; color = light->Sample(pi); if ( !color.IsBlack() ) break; } ShootCausticsPhoton(dir, pi, color, shape, 0); } } }