Пример #1
0
		void Process(const LightPoint &lightPoint){
			if(volumeMedia && lightPoint.photonType != Ray::INVOL)		return ;
			if(!volumeMedia && lightPoint.photonType != Ray::OUTVOL)	return ;	

			if(!lightPoint.pathThePointIn || lightPoint.indexInThePath < 0)
				return;

			Path &lightPath = *lightPoint.pathThePointIn;
			int index = lightPoint.indexInThePath;
			/*
			if (volumeMedia && lightPath[index].insideObject != outRay.insideObject)
			{
				printf("aye\n");
				return;
			}
			if (!volumeMedia && lightPath[index].contactObject != outRay.contactObject)
			{
				printf("aye\n");
				return;
			}
			*/
			vec3f photonThroughput(1,1,1);
			for(int i = 0; i < index; i++){
				photonThroughput *= lightPath[i].color / lightPath[i].directionProb / lightPath[i].originProb;
				photonThroughput *= lightPath[i].getCosineTerm();
				float dist = (lightPath[i].origin-lightPath[i+1].origin).length();
				photonThroughput *= lightPath[i].getRadianceDecay(dist);
			}
			photonThroughput /= lightPath[index].originProb;
			// runs here, photon's f/p is done.

			Ray photonRay = lightPath[index];
			photonRay.direction = lightPath[index-1].direction;
			vec3f color = photonThroughput * photonRay.getBSDF(outRay);
			float distSqr = powf((outRay.origin-lightPath[index].origin).length(), 2);
			if(intensity(color) < 1e-6f)	return ;
			float kernel = Kernel(distSqr, radius*radius);
			float normalization = volumeMedia ? kernel/(photonsNum*radius*radius*radius) : kernel/(photonsNum*radius*radius);
			//float normalization = volumeMedia==false ? 1.0 / (photonsNum*PI*radius*radius) : 1.0 / (photonsNum*PI*4.0/3*radius*radius*radius);
			contrib += color * normalization;
		}
Пример #2
0
Ray SceneObject::emit(bool isUniformOrigin , bool isUniformDir) const
{
	Ray ray;
	
	if(!areaValues.size())
	{
		ray.direction = vec3f(0, 0, 0);
		ray.directionProb = 1;
		ray.color = vec3f(0, 0, 0);
		return ray;
	}

	if (isUniformOrigin)
	{
		float rnd = RandGenerator::genFloat()*totalArea;
		unsigned index = (lower_bound(areaValues.begin(), areaValues.end(), rnd)-areaValues.begin());
		if(index >= areaValues.size())
			index = areaValues.size() - 1; 
		ray.contactObject = (SceneObject*)this;
		ray.contactObjectTriangleID = index;
		ray.origin = genRandTrianglePosition(ray.contactObjectTriangleID);
		ray.originProb = weight / totalArea;
	}
	else
	{
		float rnd = RandGenerator::genFloat()*totalEnergy;
		unsigned index = (lower_bound(energyDensity.begin(), energyDensity.end(), rnd)-energyDensity.begin());
		if(index >= energyDensity.size())
			index = energyDensity.size() - 1; 
		ray.contactObject = (SceneObject*)this;
		ray.contactObjectTriangleID = index;
		ray.origin = genRandTrianglePosition(ray.contactObjectTriangleID);

		float prob;
		if (index == 0)
			prob = energyDensity[index] / totalEnergy;
		else
			prob = (energyDensity[index] - energyDensity[index - 1]) / totalEnergy;
		ray.originProb = weight * prob / areaValues[index];
	}

	UniformSphericalSampler uniformSphericalSampler;
	CosineSphericalSampler cosineSphericalSampler;

	LocalFrame lf = ray.contactObject->getAutoGenWorldLocalFrame(ray.contactObjectTriangleID, ray.origin);

	if (isUniformDir)
		ray.direction = uniformSphericalSampler.genSample(lf);
	else
		ray.direction = cosineSphericalSampler.genSample(lf);

	if(ray.getContactNormal().dot(ray.direction) < 0)
		ray.direction = -ray.direction;

	ray.insideObject = scene->findInsideObject(ray, ray.contactObject);

	ray.current_tid = scene->getContactTreeTid(ray);
	ray.color = ray.getBSDF(ray);
	if(!emissive())
		ray.color = vec3f(1, 1, 1);

	if (isUniformDir)
		ray.directionProb = uniformSphericalSampler.getProbDensity(lf , ray.direction) * 2.f;
	else
		ray.directionProb = cosineSphericalSampler.getProbDensity(lf, ray.direction);

	ray.directionSampleType = ray.originSampleType = Ray::RANDOM;

	if(!scene->usingGPU())
	{
		Scene::ObjSourceInformation osi;
		NoSelfIntersectionCondition condition(scene, ray);
		float dist = scene->intersect(ray, osi, &condition);
		if(dist > 0)
		{
			ray.intersectDist = dist;
			ray.intersectObject = scene->objects[osi.objID];
			ray.intersectObjectTriangleID = osi.triangleID;
		}
	}
	return ray;
}
Пример #3
0
vec3f IptTracer::colorByConnectingLights(Ray lastRay , Ray ray , bool dirIlluWeight)
{
	Ray lightRay = genEmissiveSurfaceSample(true , false);
	lightRay.direction = (ray.origin - lightRay.origin);
	Real dist = lightRay.direction.length();
	dist = max(dist , 1e-6f);
	Real dist2 = dist * dist;
	lightRay.direction.normalize();
	Ray outRay = ray;
	outRay.direction = -lightRay.direction;

	vec3f decayFactor = outRay.getRadianceDecay(dist);

	if(!testVisibility(outRay, lightRay))
		return vec3f(0.f);

	//outRay.direction = -cameraState.lastRay->direction;
	//vec3f bsdfFactor2 = lightRay.getBSDF(outRay);
	vec3f bsdfFactor = lastRay.getBSDF(outRay);

	if (y(bsdfFactor) < 1e-7f)
		return vec3f(0.f);

	Real cosAtLight = clampf(lightRay.getContactNormal().dot(lightRay.direction) , 0.f , 1.f);

	Real cosToLight = clampf(ray.getContactNormal().dot(-lightRay.direction) , 0.f , 1.f);

	if (cosAtLight < 1e-6f || cosToLight < 1e-6f)
		return vec3f(0.f);

	vec3f tmp = lightRay.color * cosAtLight * bsdfFactor * cosToLight
		/ (lightRay.originProb * dist2);

	//fprintf(fp , "weight = %.8f , bsdfToLightPdf = %.8f , cosAtLight = %.8f ,\ntoLightOriginPdf = %.8f , originProb = %.8f , dist = %.8f\n" , 
	//	weightFactor , bsdfToLightPdf , cosAtLight , toLightOriginPdf , lightRay.originProb , dist);

	vec3f res = tmp * decayFactor;

	if (dirIlluWeight && useRayMarching)
	{
		Real p1 = lightRay.originProb;
		Real p2 = lightRay.originProb * (cosAtLight / M_PI) * cosToLight / dist2 * 
			(partialPathNum * gatherRadius * gatherRadius * M_PI);
		Real weightFactor = p1 / (p1 + p2);
		res *= weightFactor;
	}
	
	if (dirIlluWeight && !useRayMarching)
	{
		Real p1 = lastRay.getDirectionSampleProbDensity(outRay);
		Real p2 = lightRay.originProb * dist2 / cosAtLight;
		Real weightFactor = p2 / (p1 + p2);
		res *= weightFactor;
	}
	//printf("sur weight = %.8f\n" , weightFactor);

	/*
	vec3f resx = camera.eliminateVignetting(res , cameraState.index) * pixelNum;
	if (cameraState.ray->contactObject)//(resx[0] + resx[1] + resx[2] >= 2)
	{
		fprintf(fp , "=====================\n");
		fprintf(fp , "cosAtLight = %.8f, cosToLight = %.8f, originPdf = %.8f, pdf = %.8f, weight=%.8f,\nres=(%.10f,%.10f,%.10f)\nbsdf=(%.10f,%.10f,%.10f)\n" , 
			cosAtLight , cosToLight , originProb , pdf , weightFactor , resx[0] , resx[1] , resx[2] , bsdfFactor[0] , bsdfFactor[1] , bsdfFactor[2]);
	}
	*/
	return res;
}