glm::vec3 Transparent::shade(const ShadeRec& sr)const
{
	glm::vec3 L(Phong::shade(sr));

	glm::vec3 incoming = -sr.ray.getDirection();
	glm::vec3 reflected;
	glm::vec3 fr = reflectiveBrdf->sampleF(sr,incoming,reflected);
	Ray reflectedRay(sr.hitPoint,reflected);

	if(specularBtfd->tir(sr))
	{
		//comment this out to remove the reflection and get cool effects
		L +=  sr.world.getTracer()->traceRay(reflectedRay,sr.depth + 1);
		//kr = 1.0
	}
	else
	{
		glm::vec3 transmitted;
		glm::vec3 ft = specularBtfd->sampleF(sr,incoming,transmitted);
		Ray transmittedRay(sr.hitPoint,transmitted);

		glm::vec3 reflectedColor = sr.world.getTracer()->traceRay(reflectedRay,sr.depth + 1) * fabs(glm::dot(sr.normal,reflected));
		fr.x *= reflectedColor.x;
		fr.y *= reflectedColor.y;
		fr.z *= reflectedColor.z;
		glm::vec3 transmittedColor = sr.world.getTracer()->traceRay(transmittedRay,sr.depth + 1) * fabs(glm::dot(sr.normal,transmitted));
		ft.x *= transmittedColor.x;
		ft.y *= transmittedColor.y;
		ft.z *= transmittedColor.z;
		L += fr + ft;
	}

	return L;
}
Exemple #2
0
glm::vec3 Dielectric::shade(const ShadeRec& sr)const
{
	glm::vec3 L;
	//glm::vec3 L = Phong::shade(sr);
	glm::vec3 reflected;
	glm::vec3 incoming(-sr.ray.getDirection());
	glm::vec3 fr = fresnelBrdf->sampleF(sr,incoming,reflected);
	Ray reflectedRay(sr.hitPoint,reflected);
	float t = 0.0f;
	glm::vec3 Lr, Lt;
	float nDotR = glm::dot(sr.normal,reflected);

	if(fresnelBtdf->tir(sr))
	{
		if(nDotR < 0.0)
		{
			//reflected ray is inside
			Lr = sr.world.getTracer()->traceRay(reflectedRay,t,sr.depth + 1);
			glm::vec3 colorFilter = glm::pow(colorFilterIn,glm::vec3(t));
			L.x += colorFilter.x * Lr.x;
			L.y += colorFilter.y * Lr.y;
			L.z += colorFilter.z * Lr.z;
		}
		else
		{
			//reflected ray is outside
			Lr = sr.world.getTracer()->traceRay(reflectedRay,t,sr.depth + 1);
			glm::vec3 colorFilter = glm::pow(colorFilterOut,glm::vec3(t));			
			L.x += colorFilter.x * Lr.x;
			L.y += colorFilter.y * Lr.y;
			L.z += colorFilter.z * Lr.z;
		}
	}
	else
	{
		//no total internal reflection
		glm::vec3 transmitted;
		glm::vec3 ft = fresnelBtdf->sampleF(sr,incoming,transmitted);
		Ray transmittedRay(sr.hitPoint,transmitted);
		float nDotT = glm::dot(sr.normal,transmitted);

		if(nDotT > 0.0)
		{
			//reflected ray is inside
			Lr = sr.world.getTracer()->traceRay(reflectedRay,t,sr.depth +1) * fabs(nDotR);
			Lr.x *= fr.x;
			Lr.y *= fr.y;
			Lr.z *= fr.z;

			glm::vec3 colorFilterR = glm::pow(colorFilterIn,glm::vec3(t));
			L.x += colorFilterR.x * Lr.x;
			L.y += colorFilterR.y * Lr.y;
			L.z += colorFilterR.z * Lr.z;

			//transmitted ray is outside
			Lt = sr.world.getTracer()->traceRay(transmittedRay,t,sr.depth +1) * fabs(nDotT);
			Lt.x *= ft.x;
			Lt.y *= ft.y;
			Lt.z *= ft.z;

			glm::vec3 colorFilterT = glm::pow(colorFilterOut, glm::vec3(t));
			L.x += colorFilterT.x * Lt.x;
			L.y += colorFilterT.y * Lt.y;
			L.z += colorFilterT.z * Lt.z;
		}
		else
		{
			//reflected ray is outisde
			Lr = sr.world.getTracer()->traceRay(reflectedRay,t,sr.depth +1) * fabs(nDotR);
			Lr.x *= fr.x;
			Lr.y *= fr.y;
			Lr.z *= fr.z;

			glm::vec3 colorFilterR = glm::pow(colorFilterOut,glm::vec3(t));
			colorFilterR.x *= Lr.x;
			colorFilterR.y *= Lr.y;
			colorFilterR.z *= Lr.z;
			L += colorFilterR;

			//transmitted ray is inside
			Lt = sr.world.getTracer()->traceRay(transmittedRay,t,sr.depth +1) * fabs(nDotT);
			Lt.x *= ft.x;
			Lt.y *= ft.y;
			Lt.z *= ft.z;

			glm::vec3 colorFilterT = glm::pow(colorFilterIn,glm::vec3(t));
			colorFilterT.x *= Lt.x;
			colorFilterT.y *= Lt.y;
			colorFilterT.z *= Lt.z;
			L += colorFilterT;
		}
	}

	return L;
}
Exemple #3
0
    /**
     * Compute recursivly the color contribution of one ray.
     * @param currentRay the ray whose contribution is computed.
     * @return the color associated with the ray contribution.
     */
    glm::vec3 Scene::getColor(const ray::Ray & currentRay)
    {
	glm::vec3 color(0,0,0);
	scene::Intersection inter;
	if(intersect(currentRay,inter))
	{
	   glm::vec3 pointHit=inter.getPoint(); 
	   glm::vec3 normalHit=inter.getNormal();
	   glm::vec3 incident = currentRay.getDirection();
	   materials::Material * materialHit=inter.getMaterial();
	   float alpha = 1.0;
	
	    // Part 1 : Light contribution
	    for(iterator_light it=begin_light();
		it!=end_light();++it)
	    {
		glm::vec3 direction=(*it)->getPosition()-pointHit;
		ray::ShadowRay shadowRay(pointHit,direction,0.001,
					 getCamera()->getFarPlan(),1);
		scene::Intersection dummyInter;
		ray::ShadowRay dummyRay(shadowRay);

		float attenuation = 0.0;
		while(intersect(shadowRay,dummyInter))
		{
		    shadowRay.setOrigin(dummyInter.getPoint());
		    attenuation+=1-dummyInter.getMaterial()->getTransmissionAttenuation();
		    if(attenuation >= 1.0)
		    {
			attenuation=1.0;
			break;
		    }
		}

		glm::vec3 matColor= materialHit->computeBRDF(shadowRay,
							     normalHit);
		glm::vec3 lightColor=(*it)->powerAt(pointHit);
		glm::vec3 lightContribution=componentProduct(matColor,
							     lightColor);
		lightContribution = glm::clamp(lightContribution,
					       glm::vec3(0),glm::vec3(1));
		alpha = materialHit->getTransmissionAttenuation();
		color+=(1-attenuation)*(1-alpha)*lightContribution;
		
	    }

	    // Part 2 : Other rays
	    // 2 steps : computing ray direction then getting color recursively
	    if(currentRay.getBounces() > 0)
	    {
		float coeff=fabs(glm::dot(currentRay.getDirection(),normalHit));
		// Reflexion ray
		if(coeff*materialHit->getReflexionAttenuation()>EPSILON)
		{
		    ray::ReflexionRay reflexionRay(pointHit,glm::reflect(incident,normalHit),
						   0.001,getCamera()->getFarPlan(),
						   currentRay.getBounces()-1);
		    color+=coeff*materialHit->getReflexionAttenuation()*
			getColor(reflexionRay);
		}
		// Transmission ray

		float alpha = materialHit->getTransmissionAttenuation();
		alpha*=coeff;
		if(alpha>EPSILON)
		{
		    glm::vec3 dummyVec = glm::dot(incident,normalHit) * normalHit - incident;
		    float sinT1 = glm::dot(dummyVec,dummyVec);
		    float cosT1 = sqrt(fabs(1-sinT1*sinT1));

		    float eta12 = currentRay.getMRI()/materialHit->getMRI();
		    float c = 1-eta12*eta12*sinT1*sinT1;
		    c = (c>0) ? c : 0;
		    float dF1 = (eta12 * cosT1 - sqrt(c)); 
		    glm::vec3 transmittedDirection = eta12 * incident + (dF1 * normalHit); 
		    transmittedDirection = glm::normalize(transmittedDirection);

		    ray::TransmissionRay transmittedRay(pointHit,
							transmittedDirection,
							0.001,
							getCamera()->getFarPlan(),
							currentRay.getBounces()-1,
							(eta12==1.0) ? 1.0 : materialHit->getMRI()
			);	  

		    color+=alpha*getColor(transmittedRay);
		}
	    }
	       
	}
	return color;
    }