Color Raytracer::CalnDiffusion( Collider* collider , int* hash, int rc, Color weight) {
	Primitive* pri = collider->GetPrimitive();
	Color color = pri->GetMaterial()->color;
	if (pri->GetMaterial()->texture != NULL)
	{
		if (pri->getName() == 0)
			color = color * pri->GetTexture(collider->C);
		else
			color = color * pri->GetTexture(Vector3(collider->u, collider->v, 0));
	}
		
	Color ret = color * scene->GetBackgroundColor() * pri->GetMaterial()->diff;
	for ( Light* light = scene->GetLightHead() ; light != NULL ; light = light->GetNext() )
		ret += color * light->GetIrradiance( collider , scene->GetPrimitiveHead() , scene->GetCamera()->GetShadeQuality() , hash );
	
	if (camera->GetAlgorithm() == "PM")
		ret += color * photonmap->GetIrradiance( collider , camera->GetSampleDist() , camera->GetSamplePhotons() );
	
	if (camera->GetAlgorithm() == "PPM" || camera->GetAlgorithm() == "SPPM") {
		Hitpoint hitpoint;
		hitpoint.pos = collider->C;
		hitpoint.dir = collider->I;
		hitpoint.N = collider->N;
		hitpoint.primitive = collider->GetPrimitive();
		hitpoint.rc = rc;
		hitpoint.weight = weight * color;
		hitpoint.R2 = photonmap->GetRadius2(collider, camera->GetSampleDist(), camera->GetSamplePhotons());
		hitpointMap->Store(hitpoint);
	}
	
	return ret;
}
예제 #2
0
// -----------------------------------------------------------
// Engine::Raytrace
// Naive ray tracing: Intersects the ray with every primitive
// in the scene to determine the closest intersection
// -----------------------------------------------------------
Primitive* Engine::Raytrace( Ray& a_Ray, Color& a_Acc, int a_Depth, float a_RIndex, float& a_Dist )
{
	if (a_Depth > TRACEDEPTH) return 0;
	// trace primary ray
	a_Dist = 1000000.0f;
	vector3 pi;
	Primitive* prim = 0;
	int result;
	// find the nearest intersection
	for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
	{
		Primitive* pr = m_Scene->GetPrimitive( s );
		int res;
		if (res = pr->Intersect( a_Ray, a_Dist )) 
		{
			prim = pr;
			result = res; // 0 = miss, 1 = hit, -1 = hit from inside primitive
		}
	}
	// no hit, terminate ray
	if (!prim) return 0;
	// handle intersection
	if (prim->IsLight())
	{
		// we hit a light, stop tracing
		a_Acc = Color( 1, 1, 1 );
	}
	else
	{
		// determine color at point of intersection
		pi = a_Ray.GetOrigin() + a_Ray.GetDirection() * a_Dist;
		// trace lights
		for ( int l = 0; l < m_Scene->GetNrPrimitives(); l++ )
		{
			Primitive* p = m_Scene->GetPrimitive( l );
			if (p->IsLight()) 
			{
				Primitive* light = p;
				// calculate diffuse shading
				vector3 L = ((Sphere*)light)->GetCentre() - pi;
				NORMALIZE( L );
				vector3 N = prim->GetNormal( pi );
				if (prim->GetMaterial()->GetDiffuse() > 0)
				{
					float dot = DOT( N, L );
					if (dot > 0)
					{
						float diff = dot * prim->GetMaterial()->GetDiffuse();
						// add diffuse component to ray color
						a_Acc += diff * prim->GetMaterial()->GetColor() * light->GetMaterial()->GetColor();
					}
				}
			}
		}
	}
	// return pointer to primitive hit by primary ray
	return prim;
}
Color Raytracer::CalnRefraction( Collider* collider , Vector3 ray_V , int dep , bool refracted , int* hash, int rc, Color weight) {
	Primitive* pri = collider->GetPrimitive();
	double n = pri->GetMaterial()->rindex;
	if ( !refracted ) n = 1 / n;
	
	bool nextRefracted = refracted;
	ray_V = ray_V.Refract( collider->N , n , &nextRefracted );
	
	Color alpha = Color(1, 1, 1) * pri->GetMaterial()->refr;
	if (refracted)
		alpha *= (pri->GetMaterial()->absor * -collider->dist).Exp();
	Color rcol = RayTracing( collider->C , ray_V , dep + 1 , nextRefracted , hash, rc, weight * alpha);
	return rcol * alpha;
}
예제 #4
0
/*!
	@brief		トレース
	@param[o]	out: 出力輝度
	@param[i]	ray: 光線
	@param[i]	depth: 深度
 */
void Renderer::Trace(Color& out, const Ray& ray, std::size_t depth)
{
	Primitive* prim = NULL;
	Primitive::Param param;

	if((depth >= max_depth) || !FindNearest(&prim, param, ray))
	{
		out = scene->GetBGColor();
		return;
	}

	Vertex v;
	prim->CalcVertex(v, param, ray);
	Material* mtrl = prim->GetMaterial();

	// emittance
	out = mtrl->e;
 #ifdef USE_LOCAL_ILLUMINATION
	// direct lighting
	Color direct;
	DirectLighting(direct, ray, v, *mtrl);
	ColorAdd3(&out, &out, &direct);
 #endif // USE_LOCAL_ILLUMINATION
 #ifdef USE_GLOBAL_ILLUMINATION
	// indirect lighting
	Color indirect;
	IndirectLighting(indirect, ray, v, *mtrl, depth);
	ColorAdd3(&out, &out, &indirect);
 #endif // USE_GLOBAL_ILLUMINATION
}
Color Raytracer::CalnReflection( Collider* collider , Vector3 ray_V , int dep , bool refracted , int* hash, int rc, Color weight) {
	Primitive* pri = collider->GetPrimitive();
	ray_V = ray_V.Reflect( collider->N );

	if ( pri->GetMaterial()->drefl < EPS || dep > MAX_DREFL_DEP ) {
		Color alpha = pri->GetMaterial()->color * pri->GetMaterial()->refl;
		return RayTracing( collider->C , ray_V , dep + 1 , refracted , hash, rc, weight * alpha) * alpha;
	}

	Vector3 Dx = ray_V.GetAnVerticalVector();
	Vector3 Dy = ray_V.Cross(Dx);
	Dx = Dx.GetUnitVector() * pri->GetMaterial()->drefl;
	Dy = Dy.GetUnitVector() * pri->GetMaterial()->drefl;
	
	int totalSample = camera->GetDreflQuality();
	Color rcol, alpha = pri->GetMaterial()->color * pri->GetMaterial()->refl / totalSample;
	for ( int k = 0 ; k < totalSample ; k++ ) {
		double x , y;
		do {
			x = ran() * 2 - 1;
			y = ran() * 2 - 1;
		} while ( x * x + y * y > 1 );
		x *= pri->GetMaterial()->drefl;
		y *= pri->GetMaterial()->drefl;

		rcol += RayTracing( collider->C , ray_V + Dx * x + Dy * y , dep + MAX_DREFL_DEP , refracted , NULL, rc, weight * alpha);
	}
	return rcol * alpha;
}
예제 #6
0
// ray tracing
Colour RayTracer::TraceRay(Ray& ray, int traceDepth)
{
	if (traceDepth > MAXTRACEDEPTH)
		return Colour();

	Colour		litColour, reflectedColour;
	float		distanceToIntersect = MAXDISTANCE;
	Vector3f		intersectionPoint;
	Primitive*	nearestPrimitive = 0;

	nearestPrimitive = mScene->GetFirstPrimitive(ray, distanceToIntersect);

	if (!nearestPrimitive)
		return Colour();

	else
	{
		// Ambient,Specular lighting
		intersectionPoint = ray.GetOrigin() + ray.GetDirection() * distanceToIntersect;
		litColour = mScene->CalculatePrimitiveLightingAtPoint((*nearestPrimitive), intersectionPoint, ray.GetDirection());

		//  reflection
		float reflectionFactor = nearestPrimitive->GetMaterial()->Reflection;

		if (reflectionFactor > 0.0f)
		{
			Vector3f normal = nearestPrimitive->GetNormal(intersectionPoint);
			Vector3f reflected = ray.GetDirection() - normal * (2.0f * (ray.GetDirection()*normal));

			Ray reflectedRay = Ray(intersectionPoint , reflected);
			reflectedColour = TraceRay(reflectedRay, traceDepth + 1) * reflectionFactor;
		}

		return litColour + reflectedColour;
	}
}
예제 #7
0
void Scene::Setup(params::InterfaceGlRef _params) {
	Primitive* primitive;
	float planeDist = 25;
	//ground plane
	primitive = new PlanePrimitive(ci::Vec3f(0, -planeDist, 0), ci::Vec3f(0, 1, 0));
	primitive->SetName("GroundPlane");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(1.0f, 0.2f, 0.2f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	m_primitives.push_back(primitive);
	//top plane
	primitive = new PlanePrimitive(ci::Vec3f(0, planeDist, 0), ci::Vec3f(0, -1, 0));
	primitive->SetName("TopPlane");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(0.2f, 1.0f, 0.2f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	m_primitives.push_back(primitive);

	//side plane
	primitive = new PlanePrimitive(ci::Vec3f(planeDist, 0, 0), ci::Vec3f(-1, 0, 0));
	primitive->SetName("RightPlane");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(0.2f, 0.2f, 1.0f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	m_primitives.push_back(primitive);
	//side plane
	primitive = new PlanePrimitive(ci::Vec3f(-planeDist, 0, 0), ci::Vec3f(1, 0, 0));
	primitive->SetName("LeftPlane");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(1.0f, 1.0f, 0.2f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	m_primitives.push_back(primitive);

	//side plane
	primitive = new PlanePrimitive(ci::Vec3f(0, 0, planeDist), ci::Vec3f(0, 0, -1));
	primitive->SetName("FrontPlane");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(1.0f, 0.2f, 1.0f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	m_primitives.push_back(primitive);
	//side plane
	primitive = new PlanePrimitive(ci::Vec3f(0, 0, -planeDist), ci::Vec3f(0, 0, 1));
	primitive->SetName("BackPlane");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(0.2f, 1.0f, 1.0f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	m_primitives.push_back(primitive);


	//big sphere
	primitive = new SpherePrimitive(ci::Vec3f(5, 7, 0), 7);
	primitive->SetName("BigSphere");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	primitive->GetMaterial().SetReflectionCoefficient(0.0f);
	primitive->GetMaterial().SetRefractionCoefficient(1.1f);
	m_primitives.push_back(primitive);
	//small sphere
	primitive = new SpherePrimitive(ci::Vec3f(-5, -5, -10), 5);
	primitive->SetName("SmallSphere");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(0.5f, 0.5f, 0.1f));
	primitive->GetMaterial().SetSpecularColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->GetMaterial().SetDiffuseCoefficient(1.0f);
	primitive->GetMaterial().SetSpecularCoefficient(0.0f);
	primitive->GetMaterial().SetReflectionCoefficient(0.1f);
	primitive->GetMaterial().SetRefractionCoefficient(0.0f);
	m_primitives.push_back(primitive);
	//light1
	primitive = new SpherePrimitive(ci::Vec3f(10, 24, 0), 2);
	primitive->SetName("Light1");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(1.0f, 1.0f, 1.0f));
	primitive->SetIsLight(true);
	m_primitives.push_back(primitive);
	////light2
	/*primitive = new SpherePrimitive(ci::Vec3f(-10, 10, -10), 1);
	primitive->SetName("Light 2");
	primitive->GetMaterial().SetDiffuseColor(ci::ColorA(0.7f, 0.7f, 0.7f));
	primitive->SetIsLight(true);
	m_primitives.push_back(primitive);*/

	for (int i=0; i<m_primitives.size(); i++)
		m_primitives[i]->AddParams(_params);	
}
예제 #8
0
ci::ColorA Scene::Raytrace(const ci::Ray& inRay, int inDepth, float& inDist, const float inRefractIndex) {
	if (inDepth > 3)
		return ci::ColorA::black();

	Primitive* hitPrim = NULL;
	Primitive::E_INTERSECT_RESULT result;
	float currentInDist = inDist;
	for (int i=0; i<m_primitives.size(); i++) {
		Primitive* prim = m_primitives[i];
		Primitive::E_INTERSECT_RESULT res = prim->Intersect(inRay, inDist);
		if (res != Primitive::MISS) {
			if (inDist <= currentInDist) {
				hitPrim = prim;
				result = res;
			}
		}
	}

	if (!hitPrim)
		return ci::ColorA::black();

	if (hitPrim->IsLight()) 
		return hitPrim->GetMaterial().GetDiffuseColor();
	else {
		ci::Vec3f hitPoint = inRay.getOrigin() + inRay.getDirection() * inDist;
		ci::ColorA accumColor(0, 0, 0, 0);
		{//shading
			for (int i=0; i<m_primitives.size(); i++) {
				Primitive* prim = m_primitives[i];
				if (prim->IsLight()) {
					Primitive* light = prim;
					//shadow feeler
					float shade = 1.0f;
					//get shadow feeler ray in direction of light
					ci::Vec3f L = (((SpherePrimitive*)light)->getCenter() - hitPoint).normalized();
					float lightToHitPointDist = (((SpherePrimitive*)light)->getCenter() - hitPoint).length();
					ci::Ray shadowFeelerRay(hitPoint + L * ci::EPSILON_VALUE, L);
					float LDist = 1000.0f;
					for (int j = 0; j<m_primitives.size(); j++) {
						Primitive* primJ = m_primitives[j];
						if (primJ->IsLight())
							break;
						else {
							Primitive::E_INTERSECT_RESULT result = primJ->Intersect(shadowFeelerRay, LDist);
							if (result == Primitive::HIT && LDist <= lightToHitPointDist) {
								shade = 0.0f;
								break;
							}
						}
					}

					ci::Vec3f N = hitPrim->GetNormal(hitPoint);
					float dotLN = L.dot(N);
					ci::Vec3f R = (L - 2.0f * dotLN * N).normalized();
					ci::Vec3f V = inRay.getDirection().normalized();
					if (dotLN > 0) {
						//calculate diffuse component
						float diffuseC = dotLN * hitPrim->GetMaterial().GetDiffuseCoefficient();
						accumColor += diffuseC 
										* hitPrim->GetMaterial().GetDiffuseColor() 
										* light->GetMaterial().GetDiffuseColor()
										* shade;

						float dotVR = V.dot(R);
						if (dotVR > 0) {
							//calculate specular component
							float specularC = ci::math<float>::pow(dotVR, 20) * hitPrim->GetMaterial().GetSpecularCoefficient();
							accumColor += specularC 
											* hitPrim->GetMaterial().GetSpecularColor() 
											* light->GetMaterial().GetDiffuseColor() 
											* shade;
						}
					}
				}
			}
		}

		{//reflection
			if (hitPrim->GetMaterial().GetReflectionCoefficient() > 0.0f) {
				ci::Vec3f N = hitPrim->GetNormal(hitPoint);
				ci::Vec3f V = inRay.getDirection().normalized();
				float dotVN = V.dot(N);
				ci::Vec3f R = (V - 2.0f * dotVN * N).normalized();
				float reflectDist = 10000.0f;
				ci::ColorA reflectedColor = Raytrace(ci::Ray(hitPoint + R * ci::EPSILON_VALUE * 2, R), inDepth + 1, reflectDist, inRefractIndex);
				accumColor += reflectedColor * hitPrim->GetMaterial().GetDiffuseColor() * hitPrim->GetMaterial().GetReflectionCoefficient();
			}
		}

		{//refraction
			if (hitPrim->GetMaterial().GetRefractionCoefficient() > 0.0f) {
				float refractIndex = hitPrim->GetMaterial().GetRefractionCoefficient();
				float n = inRefractIndex / refractIndex;
				ci::Vec3f N = hitPrim->GetNormal(hitPoint) * (int)result;
				float cosI = N.dot(inRay.getDirection());
				//float I = acos(cosI);
				float cosT2 = 1.0f - n * n * (1.0f - cosI * cosI);
				//float sinT2 = n * n * (1.0f - cosI * cosI);
				if (cosT2 >= 0.0f) {
				//if (sinT2 <= 1.0f) {
					//Vec3f T = ((n * inRay.getDirection()) - (n + sqrtf(1 - sinT2)) * N).normalized();
					float cosT = sqrtf(cosT2);
					Vec3f T = ((n * inRay.getDirection()) - (n * cosI + sqrtf(cosT2)) * N).normalized();
					float refractDist = 10000.0f;
					ci::ColorA refractedColor = Raytrace(ci::Ray(hitPoint + T * ci::EPSILON_VALUE * 1, T), inDepth + 1, refractDist, refractIndex);
					accumColor += refractedColor * hitPrim->GetMaterial().GetDiffuseColor() * hitPrim->GetMaterial().GetRefractionCoefficient();
				}
			}
		}

		{//diffuse reflection - for color bleeding, ambient occlusion
		}

		{//soft shadows
		}

		{//anti-aliasing my multi-sampling
		}

		return accumColor;
	}
}
예제 #9
0
Colour RayTracer::CalculateLighting(std::vector<Light*>* lights, Vector3* campos, RayHitResult* hitresult)
{
	Colour outcolour;
	std::vector<Light*>::iterator lit_iter = lights->begin();

	//Retrive the material for the intersected primitive
	Primitive* prim = (Primitive*)hitresult->data;
	Material* mat = prim->GetMaterial();

	//the default output colour is the ambient colour
	outcolour = mat->GetAmbientColour();
	
	// The hack f***s stuff up.
	//This is a hack to set a checker pattern on the planes
	//Do not modify it
	if (((Primitive*)hitresult->data)->m_primtype == Primitive::PRIMTYPE_Plane)
	{
		int dx = (hitresult->point[0]/2.0);
		int dy = (hitresult->point[1]/2.0);
		int dz = (hitresult->point[2]/2.0);

		if (dx % 2 || dy % 2 || dz % 2)
		{
			outcolour.red = 1.0;
			outcolour.green = 1.0;
			outcolour.blue = 1.0;

		}
		else
		{
			outcolour.red = 0.0;
			outcolour.green = 0.0;
			outcolour.blue = 0.0;
		}
	}

	////Go through all the light sources in the scene
	//and calculate the lighting at the intersection point
	if (m_traceflag & TRACE_DIFFUSE_AND_SPEC)
	{
		while (lit_iter != lights->end())
		{
			Vector3 light_pos = (*lit_iter)->GetLightPosition();  //position of the light source
			Vector3 normal = hitresult->normal; //surface normal at intersection
			Vector3 surface_point = hitresult->point; //location of the intersection on the surface
			
			//TODO: Calculate the surface colour using the illumination model from the lecture notes
			// 1. Compute the diffuse term
			// 2. Compute the specular term using either the Phong model or the Blinn-Phong model
			// 3. store the result in outcolour

			// DONE

			outcolour += CalculateDiffuseLighting((light_pos - surface_point).Normalise(), normal, **lit_iter, *mat);
			outcolour += CalculateSpecularLighting(surface_point, normal, light_pos - surface_point, *campos, **lit_iter, *mat);

			double dist = (light_pos - surface_point).Norm();
			double att = 1.0 / (1.0 + (0 * dist) + (0.002 * dist * dist));

			outcolour *= att;

			lit_iter++;
		}
	}
	// light and surface pont
	return outcolour;
}