Ejemplo n.º 1
0
Point3D RayScene::GetColor(Ray3D ray,int rDepth,Point3D cLimit){
	if (rDepth == 0) {return Point3D();}
	if (cLimit[0] > 1 && cLimit[1] > 1 && cLimit[2] > 1) {return Point3D();}

	RayIntersectionInfo iInfo;
	double resp = group->intersect(ray, iInfo, -1);
	if (resp > 0) {

		//Calculating reflection values.
		Point3D reflectedDirection = Reflect(ray.direction, iInfo.normal);
		Ray3D reflectedRay(iInfo.iCoordinate+(reflectedDirection.unit()*0.0001), reflectedDirection.unit());
		//Calculating and finding the refraction values.
		Point3D refractedDirection;
		double refIndex;
		if (ray.direction.dot(iInfo.normal) < 0) {
			refIndex = iInfo.material->refind;
		} else {
			refIndex = 1/iInfo.material->refind;
		}
		int refract = Refract(ray.direction.unit(), iInfo.normal.unit(), refIndex, refractedDirection);
		Ray3D refractedRay(iInfo.iCoordinate+(refractedDirection.unit()*0.0001), refractedDirection.unit());
		Point3D refractedTransparency = iInfo.material->transparent;

		//Calculating light contributions to the point.
		Point3D diffuse = Point3D(0,0,0);
		Point3D specular = Point3D(0,0,0);
		for (int i=0; i<lightNum; i++) {
			RayIntersectionInfo iInfo2 = iInfo;
			int iSectCount = 0;
			Point3D diffuseResp = lights[i]->getDiffuse(camera->position, iInfo2);
			Point3D specularResp = lights[i]->getSpecular(camera->position, iInfo2);
			Point3D transparency = lights[i]->transparency(iInfo2, group, cLimit);
			diffuse += diffuseResp*transparency;
			specular += specularResp*transparency;
		}
		Point3D response = iInfo.material->ambient*ambient+iInfo.material->emissive + diffuse + specular
		 					+ GetColor(reflectedRay, rDepth-1, cLimit/iInfo.material->specular)
							+ GetColor(refractedRay, rDepth-1, cLimit/iInfo.material->specular)*refractedTransparency;

		for (int i = 0; i <3; i++) {
			if (response[i] < 0) {
				response[i] = 0;
			}
			if (response[i] > 1) {
				response[i] = 1;
			}
		}
		return response;
	}
	else if (ray.position[0]==camera->position[0] && ray.position[1]==camera->position[1] && ray.position[2]==camera->position[2]) {
		return background;
	} else return Point3D();
}
Ejemplo n.º 2
0
// Light that bounces multiple times before reaching the eye
Rgb Dielectric::indirectRadiance(Intersection *intersection, Ray ray, Scene *scene, int depth)
{
	/*
	 *	IDEA: Set index of refraction to be the same as the airs. In this event, should go straight through
	 *		  and the towardsViewer and refracted vector should differ in sign value (ie, they will be pointing 
	 *		  in opposite directions, but parallel)
	 */


	//TODO: Might as well store the surface normal with the intersection
	Vector3 towardsViewer = -ray.getDirection().normalized();
	Vector3 normal = intersection->getSurface()->computeSurfaceNormal(intersection->getIntersectionPoint()).normalized();

	Ray reflectedRay(intersection->getIntersectionPoint(),
					 -towardsViewer.reflect(normal),
					 ray.getRefractiveIndex(),
					 ray.getMaxDepth());

	// Add refracted ray
	bool isReflected = false;
	Vector3 refractedDirection = towardsViewer.refract(normal, ray.getRefractiveIndex(), refractiveIndex, isReflected);

	Ray refractedRay(intersection->getIntersectionPoint(),
					 refractedDirection,
					 refractiveIndex,
					 ray.getMaxDepth());

	// Compute fresnel
	double fresnel = computeFresnel(towardsViewer, normal, ray.getRefractiveIndex(),  refractiveIndex);

	Rgb radiance;
	if (fresnel >= 1.0 || isReflected == true)
	{
		radiance = scene->trace(reflectedRay, EPSILON, depth + 1).getPixelColor();
	}
	else
	{
		Rgb refractedColor = scene->trace(refractedRay, EPSILON, depth + 1).getPixelColor();
		Rgb reflectedColor = scene->trace(reflectedRay, EPSILON, depth + 1).getPixelColor();

		radiance.u.a[0] = (1.0 - fresnel) * refractedColor.u.a[0] + (fresnel) * reflectedColor.u.a[0];
		radiance.u.a[1] = (1.0 - fresnel) * refractedColor.u.a[1] + (fresnel) * reflectedColor.u.a[1];
		radiance.u.a[2] = (1.0 - fresnel) * refractedColor.u.a[2] + (fresnel) * reflectedColor.u.a[2];
	}
	return kAbsorption * radiance;
}
Ejemplo n.º 3
0
	float3 trace(const Ray& ray, int depth)
	{
        Hit hit = firstIntersect(ray);

        // If ray hits nothing, we return the aurora borealis
		if(hit.t < 0) {
            return ray.dir * ray.dir * float3(0,1,0.6);
        }
        
        float3 lightSum = {0,0,0};

        for(LightSource *l : lightSources) {
            float3 li = l->getLightDirAt(ray.origin);
            float dist = l->getDistanceFrom(hit.position);
            int maxDepth = 5;

            // Deals with shadows
            Ray shadowRay(hit.position + (hit.normal*0.1), li);
            Hit shadowHit = firstIntersect(shadowRay);
            if(shadowHit.t > 0 && shadowHit.t < dist)
                continue;
            
            // Handles types of materials differently
            if(depth > maxDepth) return lightSum;
            if(hit.material->reflective){   // for smooth surface
                float3 reflectionDir = hit.material->reflect(ray.dir, hit.normal);
                Ray reflectedRay(hit.position + hit.normal*0.1, reflectionDir );
                lightSum += trace(reflectedRay, depth+1)
                        * hit.material->getReflectance(ray.dir, hit.normal);
            }
            if(hit.material->refractive) {  // for smooth surface
                float3 refractionDir = hit.material->refract(ray.dir, hit.normal);
                Ray refractedRay(hit.position - hit.normal*0.1, refractionDir );
                lightSum += trace(refractedRay, depth+1) * (float3(1,1,1) - hit.material->getReflectance(ray.dir, hit.normal));
            } else {                        // for rough surface
                lightSum += hit.material->shade(hit.normal, -ray.dir, l->getLightDirAt(hit.position),
                                           l->getPowerDensityAt(hit.position));
            }
        }
        
		return lightSum;
	}
Ejemplo n.º 4
0
// Do recursive ray tracing!  You'll want to insert a lot of code here
// (or places called from here) to handle reflection, refraction, etc etc.
vec3f RayTracer::traceRay( Scene *scene, const ray& r, const vec3f& thresh, int depth )
{
	isect i;
	vec3f colorC;
	if (scene->intersect(r, i)) {
		// YOUR CODE HERE

		// An intersection occurred!  We've got work to do.  For now,
		// this code gets the material for the surface that was intersected,
		// and asks that material to provide a color for the ray.  

		// This is a great place to insert code for recursive ray tracing.
		// Instead of just returning the result of shade(), add some
		// more steps: add in the contributions from reflected and refracted
		// rays.

		const Material& m = i.getMaterial();
		vec3f intensity = m.shade(scene, r, i);
		if (depth == 0) return intensity;
		if (thresh.length() < AdaptiveThreshold) return intensity;

		vec3f Qpt = r.at(i.t);
		vec3f minusD = -1 * r.getDirection();
		vec3f cosVector = i.N * (minusD * i.N);
		vec3f sinVector = cosVector + r.getDirection();
		vec3f newThresh = thresh;

		// Reflected Ray
		if (!m.kr(i).iszero())
		{
			vec3f reflectedDirection = cosVector + sinVector;
			reflectedDirection.normalize();
			ray reflectedRay(Qpt, reflectedDirection, ray::REFLECTION);
			newThresh = prod(newThresh, i.getMaterial().kr(i)); // change the threshold value
			intensity = intensity + prod(m.kr(i), traceRay(scene, reflectedRay, newThresh, depth - 1));
		}

		//Refracted Ray
		if (!m.kt(i).iszero())
		{
			double cosineAngle = acos(i.N * r.getDirection()) * 180 / M_PI;
			double n_i, n_r;
			double criticalAngle = 360;
			int iDirection;
			// bool goingIn = true;
			// double cosThetaI = 0;
			if (cosineAngle > 90) // Coming into an object from air
			{
				n_i = 1;
				n_r = m.index(i);
				iDirection = 1;
				// cosThetaI = i.N * -1 * r.d;
			}
			else // Going out from object to air
			{
				n_i = m.index(i);
				n_r = 1;
				// goingIn = false;
				// cosThetaI = i.N * r.d;
				iDirection = -1;
			}
			
			double n = n_i / n_r;
			if (1 - n * n * (1 - (minusD * i.N) * (minusD * i.N)) > 0.0) // NO total internal refraction
			{
				vec3f sinT = n * sinVector;
				// vec3f cosT = (-1 * i.N) * sqrt(1 - sinT*sinT);
				// not sure if there are any differences between the two eqn, please check!!!!!!
				vec3f cosT = (-1 * i.N) * sqrt(1 - n * n * (1 - (minusD * i.N) * (minusD * i.N)));
				vec3f refractedDirection = cosT + iDirection*sinT;
				refractedDirection.normalize();
				ray refractedRay(Qpt, iDirection * refractedDirection, ray::REFRACTION);
				newThresh = prod(newThresh, i.getMaterial().kt(i)); // change the threshold value
				intensity = intensity + prod(m.kt(i), traceRay(scene, refractedRay, newThresh, depth - 1));
			}
		}
		colorC = intensity;
	}
	else {
		// No intersection.  This ray travels to infinity, so we color
		// it according to the background color, which in this (simple) case
		// is just black.
		colorC = vec3f (0.0, 0.0, 0.0);
	}
	return colorC;
}