Esempio n. 1
0
	Ray AbstractObject::genSurfaceSample(){
		Ray ray;
		if(!areaThreshold.size()){
			ray.direction = vec3f(0,0,0);
			ray.radiance = vec3f(0,0,0);
			return ray;
		}

		float randArea = rng->genFloat() * boundArea;
		uint index = std::lower_bound(areaThreshold.begin(), areaThreshold.end(), randArea) - areaThreshold.begin();
		if(index == areaThreshold.size())	index--;
		
		ray.contactObj = this;
		ray.contactTriangleID = index;
		ray.origin = genRandTrianglePosition(ray.contactTriangleID);
		UniformSphereSampler uniformSampler;
		vec3f normal = ray.contactObj->getWorldNormal(ray.contactTriangleID, ray.origin);
		ray.direction = uniformSampler.sample(*rng, vec3f(), &ray.directionProb);
		if(ray.direction.dot(normal) < 0)	
			ray.direction = -ray.direction;
		ray.radiance = ray.evalBSDF(ray);
		ray.insideObj = scene->findInsideObject(ray, ray.contactObj);
		ray.directionProb *= 2;
		ray.originProb = 1 / boundArea * pickProb;

		Scene::ObjSourceInfo info;
		NoSelfCondition condition(scene, ray);
		float dist = scene->intersect(ray, info, &condition);
		if(dist > 0){
			ray.intersectObj = scene->objects[info.objID];
			ray.intersectDist = dist;
			ray.intersectTriangleID = info.triID;
		}
		return ray;
	}
Esempio n. 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;
}