ColorTimeCache World::runTimePhotonCache(vec origin, vec direction) const { ColorTimeCache ctc; HitInfo eyeInfo; objects->hit(&eyeInfo, origin, direction); if (!eyeInfo.hit) return ctc; Color initc = eyeInfo.mat->getColor(); for (int d = 0; d < depth; d++) { HitInfo newI; newI.follow(eyeInfo); vec newDirection = eyeInfo.mat->sample(eyeInfo.incoming, eyeInfo.normal); objects->hit(&newI, eyeInfo.location, newDirection); if (newI.hit) { Color newc = initc * eyeInfo.mat->getColor() * (1.0/depth) * eyeInfo.mat->sampledPdf(eyeInfo.incoming, newDirection, eyeInfo.normal); ctc.addWeighted(newI.distance + eyeInfo.distance, newc, pc->seenTimeValue(eyeInfo.location, newI.location, &newI, sampleRadius)); } } return ctc; }
Color World::runPhotonCache(vec origin, vec direction) const { HitInfo eyeInfo; objects->hit(&eyeInfo, origin, direction); if (!eyeInfo.hit) return Color(0,0,0); Color initc = eyeInfo.mat->getColor(); Color accum; for (int d = 0; d < depth; d++) { HitInfo newI; newI.follow(eyeInfo); vec newDirection = eyeInfo.mat->sample(eyeInfo.incoming, eyeInfo.normal); objects->hit(&newI, eyeInfo.location, newDirection); if (newI.hit) { Color newc = initc * eyeInfo.mat->getColor() * Color(1.0, 1.0, 1.0) * eyeInfo.mat->sampledPdf(eyeInfo.incoming, newDirection, eyeInfo.normal); accum += newc * pc->seenValue(eyeInfo.location, newI.location, &newI, sampleRadius) * (1.0 / depth); } } return accum; }
Color World::runBiDi(vec origin, vec direction) const { Thing *emitter = emitters[Random::upto(emitters.size())]; std::vector<Color> cumEmtWeight; std::vector<HitInfo> emtHits; std::vector<Color> cumEyeWeight; std::vector<HitInfo> eyeHits; std::vector<int> todo; cumEmtWeight.reserve(depth); emtHits.reserve(depth); cumEyeWeight.reserve(depth); eyeHits.reserve(depth); todo.reserve(depth); HitInfo emtInfo; vec emtN; vec source; source = emitter->randomSurfacePoint(emtN); emtInfo.hit = true; emtInfo.incoming = emtN; emtInfo.normal = emtN; emtInfo.location = source; emtInfo.mat = emitter->getMaterial(); cumEmtWeight.push_back(emitter->getMaterial()->getColor()); emtHits.push_back(emtInfo); bool done = false; for (int d = 1; d < depth && !done; d++) { HitInfo newI; newI.follow(emtHits[d-1]); vec newDirection = emtHits[d-1].mat->sample(emtHits[d-1].incoming, emtHits[d-1].normal); objects->hit(&newI, emtHits[d-1].location, newDirection); cumEmtWeight.push_back(emtHits[d-1].mat->combineColor( cumEmtWeight[d-1] * emtHits[d-1].mat->sampledPdf( emtHits[d-1].incoming, newDirection, emtHits[d-1].normal))); if (newI.hit) emtHits.push_back(newI); else done = true; } HitInfo eyeInfo; objects->hit(&eyeInfo, origin, direction); done = false; if (!eyeInfo.hit) return Color(0,0,0); cumEyeWeight.push_back(eyeInfo.mat->getColor()); eyeHits.push_back(eyeInfo); /*for (int d = 1; d < depth && !done; d++) { HitInfo newI; newI.follow(eyeHits[d-1]); vec newDirection = eyeHits[d-1].mat->sample(eyeHits[d-1].incoming, eyeHits[d-1].normal); objects->hit(&newI, eyeHits[d-1].location, newDirection); cumEyeWeight.push_back(eyeHits[d-1].mat->combineColor( cumEyeWeight[d-1] * eyeHits[d-1].mat->sampledPdf( eyeHits[d-1].incoming, newDirection, eyeHits[d-1].normal))); if (newI.hit) eyeHits.push_back(newI); else done = true; }*/ for (int d = 1; d < depth && !todo.empty(); d++) { HitInfo newI; int index = todo.back(); todo.pop_back(); newI.follow(eyeHits[index]); vec newDirection = eyeHits[index].mat->sample(eyeHits[index].incoming, eyeHits[index].normal); objects->hit(&newI, eyeHits[index].location, newDirection); if (newI.hit) { Color newc = eyeHits[index].mat->combineColor( cumEyeWeight[index] * eyeHits[index].mat->sampledPdf( eyeHits[index].incoming, newDirection, eyeHits[index].normal)); int ints = 1;//newc.intensity() * 5 + 1; for (int x=0; x<ints; x++) todo.push_back(eyeHits.size()); eyeHits.push_back(newI); cumEyeWeight.push_back(newc * (1.0/ints)); } else done = true; } Color accum; for (int x=0; x<emtHits.size(); x++) for (int y=0; y<eyeHits.size(); y++) { vec dir = eyeHits[y].location - emtHits[x].location; double dist = dir.magnitude(); dir.normalize(); HitInfo inf; inf.distanceOnly = true; inf.distance = dist; objects->hit(&inf, emtHits[x].location, dir); if (inf.distance >= dist - EPSILON || !inf.hit) { //hit accum += cumEyeWeight[y] * cumEmtWeight[x] * eyeHits[y].mat->pdf(eyeHits[y].incoming, dir * -1, eyeHits[y].normal) * emtHits[x].mat->pdf(emtHits[x].incoming, dir, emtHits[x].normal); } } return accum; /*if (eyeInfo.hit) { vec newn; vec dtl = eyeInfo.location - emitter->randomSurfacePoint(newn); return emitter->getMaterial()->getColor() * eyeInfo.mat->pdf(direction*-1, dtl, eyeInfo.normal); } else return Color(0,0,0);*/ }
void World::createCache() { Thing *emitter; HitInfo c; int length =0; int resetcount = 1; HitInfo emtInfo; vec emtN; vec source; emitter = emitters[Random::upto(emitters.size())]; source = emitter->randomSurfacePoint(emtN); emtInfo.hit = true; emtInfo.incoming = emtN; emtInfo.normal = emtN; emtInfo.location = source; emtInfo.mat = emitter->getMaterial(); colorcache.push_back(emitter->getMaterial()->getColor()); hicache.push_back(emtInfo); bool done = false; for (int d = 1; d < cacheSize; d++) { int i = d - 1; double ints = colorcache[i].intensity(); if (ints < .01 || length > 60 || done) { emitter = emitters[Random::upto(emitters.size())]; source = emitter->randomSurfacePoint(emtN); emtInfo.distance = 0; emtInfo.previousDistances = 0; emtInfo.hit = true; emtInfo.incoming = emtN; emtInfo.normal = emtN; emtInfo.location = source; emtInfo.mat = emitter->getMaterial(); int intes = 1;//emitter->getMaterial()->getColor().intensity() + 1; for (int x=0; x<intes; x++) { colorcache.push_back(emitter->getMaterial()->getColor() * (1.0/intes)); hicache.push_back(emtInfo); } resetcount++; d += intes-1; done = false; length = 0; continue; } length++; HitInfo newI; newI.follow(hicache[d-1]); vec newDirection = hicache[d-1].mat->sample(hicache[d-1].incoming, hicache[d-1].normal); objects->hit(&newI, hicache[d-1].location, newDirection); if (newI.hit) { Color newc = hicache[d-1].mat->combineColor(colorcache[d-1] * hicache[d-1].mat->sampledPdf(hicache[d-1].incoming, newDirection, hicache[d-1].normal)); int intes = 1;//newc.intensity()*3 + 1; for (int x=0; x<intes; x++) { hicache.push_back(newI); colorcache.push_back(newc * (1.0/intes)); } d += intes-1; } else { done = true; d--; } } cacheweight = (cacheSize * 1.0 / resetcount); }
ColorTimeCache World::runCache(vec origin, vec direction) const { ColorTimeCache accum; std::vector<Color> cumEyeWeight; std::vector<HitInfo> eyeHits; std::vector<int> todo; std::vector<double> mult; todo.reserve(depth); cumEyeWeight.reserve(depth); //8s without, 8s with, but should make a difference. eyeHits.reserve(depth); mult.reserve(depth); HitInfo eyeInfo; objects->hit(&eyeInfo, origin, direction); bool done = false; if (!eyeInfo.hit) return accum; Color newc = eyeInfo.mat->getColor(); int ints = 1;//newc.intensity() * (depth/2) + 1; for (int x=0; x<ints; x++) todo.push_back(eyeHits.size()); cumEyeWeight.push_back(newc); eyeHits.push_back(eyeInfo); mult.push_back(1.0/ints); for (int d = 1; d < depth && !todo.empty(); d++) { HitInfo newI; int index = todo.back(); todo.pop_back(); newI.follow(eyeHits[index]); vec newDirection = eyeHits[index].mat->sample(eyeHits[index].incoming, eyeHits[index].normal); objects->hit(&newI, eyeHits[index].location, newDirection); if (newI.hit) { Color newc = newI.mat->combineColor( cumEyeWeight[index] * eyeHits[index].mat->sampledPdf( eyeHits[index].incoming, newDirection, eyeHits[index].normal)); // newc *= mult[index]; int ints = 1;//newc.intensity() * (depth/2) + 1; for (int x=0; x<ints; x++) todo.push_back(eyeHits.size()); eyeHits.push_back(newI); cumEyeWeight.push_back(newc); mult.push_back(1.0/ints); } else done = true; } for (int x=0; x<depth; x++) { for (int y=0; y<eyeHits.size(); y++) { int index = Random::upto(cacheSize); vec dir = eyeHits[y].location - hicache[index].location; double dist = dir.magnitude(); if (dist < EPSILON) continue; dir.normalize(); HitInfo inf; inf.distanceOnly = true; inf.distance = dist; objects->hit(&inf, hicache[index].location, dir); if (inf.distance >= dist - EPSILON || !inf.hit) { //hit Color result = cumEyeWeight[y] * colorcache[index] * cacheweight * eyeHits[y].mat->pdf(eyeHits[y].incoming, dir * -1, eyeHits[y].normal) * hicache[index].mat->pdf(hicache[index].incoming, dir, hicache[index].normal) * (1/BOUNCE_MULT); accum.addSample(hicache[index].distance + hicache[index].previousDistances + eyeHits[y].distance + eyeHits[y].previousDistances + inf.distance, result); } } } return accum; }