Example #1
0
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);*/
}
Example #2
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);
}