示例#1
0
/**
 * Initializes the raytracer for the given scene. Overrides any previous
 * initializations. May be invoked before a previous raytrace completes.
 * @param scene The scene to raytrace.
 * @param width The width of the image being raytraced.
 * @param height The height of the image being raytraced.
 * @return true on success, false on error. The raytrace will abort if
 *  false is returned.
 */
bool Raytracer::initialize(Scene* _scene, size_t _width, size_t _height, bool _extras)
{
    this->scene = _scene;
    this->width = _width;
    this->height = _height;
    this->extras = _extras;

    size_t num_geometries = scene->num_geometries();

    // invert scene transformation matrices
    for (size_t i = 0; i < num_geometries; i++)
    {
        make_inverse_transformation_matrix(&scene->get_geometries()[i]->inverse_transform_matrix,
                                           scene->get_geometries()[i]->position,
                                           scene->get_geometries()[i]->orientation,
                                           scene->get_geometries()[i]->scale);
        make_transformation_matrix(&scene->get_geometries()[i]->transform_matrix,
                                   scene->get_geometries()[i]->position,
                                   scene->get_geometries()[i]->orientation,
                                   scene->get_geometries()[i]->scale);
        make_normal_matrix(&scene->get_geometries()[i]->normal_matrix,
                           scene->get_geometries()[i]->transform_matrix);

        // calculate bounding volume for models
        scene->get_geometries()[i]->make_bounding_volume();
        cout << "Created bounding volume for geometry " << i << endl;
    }

    //cout << scene->camera.orientation << endl;

    return true;
}
示例#2
0
bool Geometry::initialize()
{
    make_inverse_transformation_matrix(&invMat, position, orientation, scale);
    make_transformation_matrix(&mat, position, orientation, scale);
    make_normal_matrix(&normMat, mat);
    return true;
}
示例#3
0
/**
 * Initializes the raytracer for the given scene. Overrides any previous
 * initializations. May be invoked before a previous raytrace completes.
 * @param scene The scene to raytrace.
 * @param width The width of the image being raytraced.
 * @param height The height of the image being raytraced.
 * @return true on success, false on error. The raytrace will abort if
 *  false is returned.
 */
bool Raytracer::initialize( Scene* scene, size_t width, size_t height )
{
    this->scene = scene;
    this->width = width;
    this->height = height;
    this->camera = scene->camera; 
    
    // Compute basis vectors with information from camera 
    Vector3 g = camera.get_direction();
    Vector3 t = camera.get_up();  
    w = normalize(g); 
    u = normalize(cross(t,w)); 
    v = cross(w,u);
    u = -u;
    e = camera.get_position();
    //retrieve addition data for viewing frame 
    fov = camera.get_fov_radians();
    nearClip = camera.get_near_clip();
    current_row = 0;
    
    // compute bounds for the viewing frame 
    top = tan(fov/2.0)*fabs(nearClip); 
    right = ((1.0)*width/height)*top; 
    left = -right;
    bottom = -top; 

    Geometry* const* sceneObjects = scene->get_geometries();
    for(unsigned int i=0; i<scene->num_geometries(); i++){
	 Geometry* shape = sceneObjects[i]; 
	 make_inverse_transformation_matrix(&shape->inv_trans, shape->position, shape->orientation, shape->scale);
	 Matrix4 trans;
	 make_transformation_matrix(&trans, shape->position, shape->orientation, shape->scale);
         make_normal_matrix(&shape->norm_matrix,trans);
    }
    return true;
}	
示例#4
0
ray_t transform(ray_t curRay, const Geometry& geom) {

    Matrix4 transform;
    Vector4 eye;
    Vector4 direction;
    Vector4 end;

    eye = Vector4(curRay.eye.x, curRay.eye.y, curRay.eye.z, 1.0);
    end = Vector4(curRay.end.x, curRay.end.y, curRay.end.z, 1.0);

    make_inverse_transformation_matrix(&transform, geom.position, geom.orientation, geom.scale);

    eye = transform * eye;
    end = transform * end;

    curRay.eye = Vector3(eye.x, eye.y, eye.z);
    direction = end - eye;
    lastLength = length(direction);
    direction = normalize(direction);
    curRay.end = Vector3(end.x, end.y, end.z);
    curRay.direction = Vector3(direction.x, direction.y, direction.z);

    return curRay;
}
示例#5
0
static Color3 raycolor(const Scene* scene, RayInfo ray, int n)
{
	Geometry* const* geometry = scene->get_geometries();
	const PointLight* light = scene->get_lights();
	IntersectionInfo intersection;
	intersection.t0 = EP;
	intersection.t1 = 1000000;
	int index;
	for(int i=0; i<scene->num_geometries();i++)
	{
		Matrix4 inversematrix;
		make_inverse_transformation_matrix(&inversematrix, geometry[i]->position, geometry[i]->orientation, geometry[i]->scale );
		RayInfo rayinformation;
		rayinformation.origin = inversematrix.transform_point(ray.origin);
		rayinformation.direction = inversematrix.transform_vector(ray.direction);	
		bool check = geometry[i]->check_geometry(rayinformation,intersection);
		
		if(check)
		{
			index = i;
		}
	}

	Color3 color = Color3::Black;
	if(intersection.t1 != 1000000)
	{
			Matrix4 transmatrix;
		    make_transformation_matrix(&transmatrix, geometry[index]->position, geometry[index]->orientation, geometry[index]->scale );
		    intersection.worldposition = transmatrix.transform_point(intersection.localposition);
			Matrix3 normalmatrix;
			make_normal_matrix(&normalmatrix, transmatrix );
			intersection.worldnormal = normalize(normalmatrix*intersection.localnormal);
			color = intersection.material.ambient*scene->ambient_light;

			for(int i=0; i<scene->num_lights();i++)
			{   
				RayInfo shadowworldrayinfo;
				shadowworldrayinfo.origin = intersection.worldposition;
				shadowworldrayinfo.direction = normalize(light[i].position - intersection.worldposition);
				bool hit = false;
				IntersectionInfo shadowintersection;
				shadowintersection.t0 = EP;
				shadowintersection.t1 = length(light[i].position - intersection.worldposition);
				real_t d = dot(intersection.worldnormal,shadowworldrayinfo.direction);
				if(d > 0)
				{
					for(int j=0; j<scene->num_geometries();j++)
					{
						Matrix4 shadowinversematrix;
						make_inverse_transformation_matrix(&shadowinversematrix, geometry[j]->position, geometry[j]->orientation, geometry[j]->scale );
						RayInfo shadowlocalrayinfo;
						shadowlocalrayinfo.origin = shadowinversematrix.transform_point(shadowworldrayinfo.origin);
						shadowlocalrayinfo.direction = shadowinversematrix.transform_vector(shadowworldrayinfo.direction);	
						bool check = geometry[j]->check_geometry(shadowlocalrayinfo,shadowintersection);
						if(check == true)
						{
								hit = true;
								break;
						}
					 }
					if(hit == false)
					{
						color = color + intersection.material.diffuse*light[i].color*d;
					}
				}
			}
			RayInfo reflectionworldrayinfo;
			reflectionworldrayinfo.origin = intersection.worldposition;
			Vector3 r = ray.direction - 2*dot(ray.direction,intersection.worldnormal)*intersection.worldnormal;
			reflectionworldrayinfo.direction = normalize(r);
			n++;
			
			if(intersection.material.refractive_index != 0)
			{
				real_t judge = dot(ray.direction,intersection.worldnormal);
				real_t c;
				RayInfo refractionworldrayinfo;
				refractionworldrayinfo.origin = intersection.worldposition;
				real_t refractiveratio = scene->refractive_index/intersection.material.refractive_index;

				if(judge<0)
				{
					
					refract(ray, intersection.worldnormal, refractiveratio,refractionworldrayinfo);
					c = -dot(ray.direction,intersection.worldnormal);
				}
				else
				{
					if(refract(ray, -intersection.worldnormal, 1/refractiveratio,refractionworldrayinfo))
					{
						c = dot(refractionworldrayinfo.direction,intersection.worldnormal);
					}
					else
					{
						if(n<=MAXNUMBER)
						{
							return intersection.material.specular*raycolor(scene,reflectionworldrayinfo,n);
						}
					}
				}
				  real_t R0 = (intersection.material.refractive_index-1)*(intersection.material.refractive_index-1)/(intersection.material.refractive_index+1)/(intersection.material.refractive_index+1);
			      real_t R = R0 + (1-R0)*pow(1-c,5);
				  if(n<=MAXNUMBER)
				  {
					return intersection.material.specular*(R*raycolor(scene,reflectionworldrayinfo,n) + (1-R)*raycolor(scene,refractionworldrayinfo,n));
				  }
			}
			else
			{
				if(n<=MAXNUMBER)
				{
					color = color + intersection.material.specular*raycolor(scene,reflectionworldrayinfo,n);
				}
			}
			return color;
			
	}

	return scene->background_color;

}
示例#6
0
/**
 * Test for intersection with triangles and if there is, set the intersection data structure contents
 */
IntersectionData Triangle::intersection_test(Vector3 ray_position, Vector3 ray_direction)
{
    if(!calculated_matrices) // if the matrix calculations haven't been calculated, do so now
    {
        make_transformation_matrix(&matrix, position, orientation, scale);
        make_inverse_transformation_matrix(&inverse_matrix, position, orientation, scale);
        make_normal_matrix(&normal_matrix, matrix);
        calculated_matrices = true; // now they are cached
    }

    // transform the ray into local coordinates
    Vector3 ray_position_local = inverse_matrix.transform_point( ray_position );
    Vector3 ray_direction_local = inverse_matrix.transform_vector( ray_direction );

    Vector3 v1 = vertices[0].position;
    Vector3 v2 = vertices[1].position;
    Vector3 v3 = vertices[2].position;

    // all of the following calculations are based off of the Shirley text

    real_t a = v1.x - v2.x;
    real_t b = v1.y - v2.y;
    real_t c = v1.z - v2.z;

    real_t d = v1.x - v3.x;
    real_t e = v1.y - v3.y;
    real_t f = v1.z - v3.z;

    real_t g = ray_direction_local.x;
    real_t h = ray_direction_local.y;
    real_t i = ray_direction_local.z;

    real_t j = v1.x - ray_position_local.x;
    real_t k = v1.y - ray_position_local.y;
    real_t l = v1.z - ray_position_local.z;

    real_t M = a*(e*i - h*f) + b*(g*f - d*i) + c*(d*h - e*g);
    real_t t = -1*(f*(a*k - j*b) + e*(j*c - a*l) + d*(b*l - k*c))/M;

    IntersectionData intersection;
    intersection.was_intersection = false;

    if(t<0) // there was an intersection, but it occurred before the beginning point of the ray
        return intersection; // was_intersection is currently false, indicating no intersection

    real_t gamma = (i*(a*k - j*b) + h*(j*c - a*l) + g*(b*l - k*c))/M;
    if(gamma < 0 or gamma > 1)
        return intersection;
    real_t beta = (j*(e*i - h*f) + k*(g*f - d*i) + l*(d*h - e*g))/M;
    if(beta < 0 or beta > 1 - gamma)
        return intersection;
    real_t alpha = 1 - beta - gamma;

    intersection.was_intersection = true;

    // retrieve all of the properties of the vertices so we can interpolate them
    Vector3 v1n = vertices[0].normal;
    Vector3 v2n = vertices[1].normal;
    Vector3 v3n = vertices[2].normal;

    Color3 v1d = vertices[0].material->diffuse;
    Color3 v2d = vertices[1].material->diffuse;
    Color3 v3d = vertices[2].material->diffuse;

    Color3 v1a = vertices[0].material->ambient;
    Color3 v2a = vertices[1].material->ambient;
    Color3 v3a = vertices[2].material->ambient;

    Color3 v1s = vertices[0].material->specular;
    Color3 v2s = vertices[1].material->specular;
    Color3 v3s = vertices[2].material->specular;

    real_t v1i = vertices[0].material->refractive_index;
    real_t v2i = vertices[1].material->refractive_index;
    real_t v3i = vertices[2].material->refractive_index;

    Vector2 v1t = vertices[0].tex_coord;
    Vector2 v2t = vertices[1].tex_coord;
    Vector2 v3t = vertices[2].tex_coord;

    int tex_width1, tex_height1, tex_width2, tex_height2, tex_width3, tex_height3;
    vertices[0].material->get_texture_size(&tex_width1, &tex_height1);
    vertices[1].material->get_texture_size(&tex_width2, &tex_height2);
    vertices[2].material->get_texture_size(&tex_width3, &tex_height3);

    intersection.time = t;
    intersection.diffuse = v1d*alpha + v2d*beta + v3d*gamma;
    intersection.ambient = v1a*alpha + v2a*beta + v3a*gamma;
    intersection.specular = v1s*alpha + v2s*beta + v3s*gamma;
    intersection.refractive_index = v1i*alpha + v2i*beta + v3i*gamma;
    Vector2 tex_coord = v1t*alpha + v2t*beta + v3t*gamma;
    Vector3 normal_local = v1n*alpha + v2n*beta + v3n*gamma;
//    Vector3 normal_local = cross(Vector3(v1 - v2), Vector3(v2 - v3));

    // in case there is no texture, default the texture colors to white
    Color3 v1c = Color3(1.0,1.0,1.0);
    Color3 v2c = Color3(1.0,1.0,1.0);
    Color3 v3c = Color3(1.0,1.0,1.0);

    if(tex_width1 != 0 && tex_height1 != 0)
        v1c = vertices[0].material->get_texture_pixel((int)(tex_coord.x*tex_width1)%tex_width1, (int)(tex_coord.y*tex_height1)%tex_height1);
    if(tex_width2 != 0 && tex_height2 != 0)
        v2c = vertices[1].material->get_texture_pixel((int)(tex_coord.x*tex_width2)%tex_width2, (int)(tex_coord.y*tex_height2)%tex_height2);
    if(tex_width3 != 0 && tex_height3 != 0)
        v3c = vertices[2].material->get_texture_pixel((int)(tex_coord.x*tex_width3)%tex_width3, (int)(tex_coord.y*tex_height3)%tex_height3);

    intersection.texture_pixel = v1c*alpha + v2c*beta + v3c*gamma;

    intersection.normal = normal_matrix * normal_local;
    intersection.normal = normalize(intersection.normal); // normals have to be renormalized

    return intersection;
}
示例#7
0
bool Sphere::Hit(Ray ray, real_t t0, real_t t1, HitRecord &rec)
{
	
	Vector3 localPos;
	Matrix4 inverseMatrix, transMatrix;
	Matrix3 temp, normalMatrix;
	Ray localRay;

	// calculate transform/ transform inverse/ normal matrix
	make_transformation_matrix(&transMatrix, position, orientation, scale);
	make_inverse_transformation_matrix(&inverseMatrix, position, orientation, scale);
	make_normal_matrix(&normalMatrix, transMatrix);
	
	// get the local ray
	localRay.origin = inverseMatrix.transform_point(ray.origin);
	localRay.dir = inverseMatrix.transform_vector(ray.dir);

	// do the intersection calculation
	real_t result, x1, x2, oriDotOri , dirDotDir, oriDotDir;
	oriDotDir = dot(localRay.dir , localRay.origin); 
	dirDotDir = dot(localRay.dir , localRay.dir); 
	oriDotOri = dot(localRay.origin , localRay.origin); 
	result = oriDotDir*oriDotDir-dirDotDir*(oriDotOri-radius*radius);

	// no intersection
	if(result < 0)
		return false;
	else 
	{
		x1=(-oriDotDir - sqrt(result)) / dirDotDir;
		x2=(-oriDotDir + sqrt(result)) / dirDotDir;
		// x1 is the place is the intersection
		if(x1>t0 && x1<t1)
		{
			localPos = localRay.origin + x1*localRay.dir;
			// set material 
			SetMaterialColors(rec.ambientColor, rec.diffuseColor,rec.specularColor);
			rec.refractiveIdx = material->refractive_index;

			// set normal
			rec.normal=(localPos)/radius;
			rec.normal=normalize(normalMatrix*rec.normal);
			
			// set texture color
			rec.textureColor = GetTexture(localPos);

			// set position
			rec.position = transMatrix.transform_point(localPos);

			// set t
			rec.t = x1;
			return true;
		}
		else
		{
			// x2 is the place is the intersection
			if(x2>t0 && x2<t1)
			{
				localPos = localRay.origin + x2*localRay.dir;
				//set material
				SetMaterialColors(rec.ambientColor, rec.diffuseColor,rec.specularColor);
				rec.refractiveIdx = material->refractive_index;

				// set normal
				rec.normal=(localPos)/radius;
				rec.normal=normalize(normalMatrix*rec.normal);

				// set texture
				rec.textureColor = GetTexture(localPos);
				
				// set position
				rec.position = transMatrix.transform_point(localPos);
				
				// set t
				rec.t = x2;
				return true;
			}
			return false;
	}

	}
}