Ejemplo n.º 1
0
vec3 trace(const ray& theray, const world* world, const vec3& light_dir)
{
    range r(0, std::numeric_limits<float>::max());
    surface_hit hit;
    hit.t = std::numeric_limits<float>::max();

    ray object_ray = transform_ray(theray, world->object_matrix, world->object_normal_matrix);
    bool have_hit = world->root->intersect(object_ray, r, &hit);
    if(!have_hit)
        return world->background;

    vec4 n1(hit.normal.x, hit.normal.y, hit.normal.z, 0.0), n2;
    vec4 p1(hit.point.x, hit.point.y, hit.point.z, 1.0), p2;
    n2 = mat4_mult_vec4(world->object_normal_inverse, n1);
    p2 = mat4_mult_vec4(world->object_inverse, p1);
    vec3 normal = vec3(n2.x, n2.y, n2.z);
    vec3 point = vec3(p2.x, p2.y, p2.z);

    float brightness;

    float shadowed = false;

    if(cast_shadows)
    {
        struct ray shadowray;
        shadowray.o = vec3_add(point, vec3_scale(normal, .0001));
        shadowray.d = light_dir;
        surface_hit shadow_hit;
        shadow_hit.t = std::numeric_limits<float>::max();
        ray object_ray = transform_ray(shadowray, world->object_matrix, world->object_normal_matrix);
        shadowed = world->root->intersect(object_ray, range(0, std::numeric_limits<float>::max()), &shadow_hit);
    }

    if(shadowed) {

        brightness = .1;

    } else {

        brightness = vec3_dot(normal, light_dir);
        if(brightness < 0)
            brightness = 0;
        if(brightness > 1)
            brightness = 1;
    }

    return vec3_scale(hit.color, brightness);
}
Ejemplo n.º 2
0
float Sphere::intersectT(Ray ray) {

  ray = transform_ray(ray);

  Vector pos = ray.position;
  Vector dir = ray.direction;

  float a = Vector::dot(dir, dir);
  float b = 2 * (Vector::dot(dir, pos - center));
  float c = Vector::dot(pos - center, pos - center) - radius * radius;

  float discriminant = b * b - 4 * a * c;

  if (discriminant >= 0)  {

    float t1 = (-b - sqrt(discriminant)) / (2 * a);
    float t2 = (-b + sqrt(discriminant)) / (2 * a);

    if (t1 >= ray.t_min && t1 <= ray.t_max) {
      return t1;
    } else if (t2 >= ray.t_min && t2 <= ray.t_max) {
      return t2;
    } else {
      return -1;
    }

  }

  return -1;

}
Ejemplo n.º 3
0
void trace_image(int width, int height, float aspect, unsigned char *image, const world* world, const vec3& light_dir)
{
#pragma omp parallel for schedule(dynamic)
    for(int yloop = 0; yloop < height; yloop++) {
        unsigned char *row = image + (height - yloop - 1) * (((width * 3) + 3) & ~3);
        for(int xloop = 0; xloop < width; xloop++) {
            // printf("%d, %d\n", xloop, yloop);
            int cols = 0;
            vec3 color(0, 0, 0);
            for(int qky = 0; qky < world->ysub; qky++) {
                for(int qkx = 0; qkx < world->xsub; qkx++) {
                    float u = ((xloop + qkx / (float)world->xsub) + .5) / width;
                    float v = ((yloop + qky / (float)world->ysub) + .5) / height;
                    ray eye_ray;
                    eye_ray.d = make_eye_ray(u, v, aspect, world->cam.fov);
                    eye_ray.o = vec3(0, 0, 0);
                    ray world_ray = transform_ray(eye_ray, world->camera_matrix, world->camera_normal_matrix);
                    vec3 sample = trace(world_ray, world, light_dir);
                    color = vec3_add(color, sample);
                    ++cols;
                }
            }
            vec3 final_color = vec3_divide(color, cols);
            unsigned char *pixel = row + xloop * 3;
            pixel[0] = final_color.x * 255;
            pixel[1] = final_color.y * 255;
            pixel[2] = final_color.z * 255;
        }
    }
}
Ejemplo n.º 4
0
/*
 * Intersect with the ray, but do so in object space.
 *
 * First, transform ray into object space. Use the methods you have
 * implemented for this.
 * Then, intersect the object with the transformed ray.
 * Finally, make sure you transform the intersection back into world space.
 *
 * isect is guaranteed to be a valid pointer.
 * The method shall return true if an intersection was found and false otherwise.
 *
 * isect must be filled properly if an intersection was found.
 */
bool Object::
intersect(Ray const& ray, Intersection* isect) const
{
	cg_assert(isect);

	if (RaytracingContext::get_active()->params.transform_objects) {
		// TODO: transform ray, intersect object, transform intersection
		// information back
		Ray transformedRay = transform_ray(ray, Object::transform_world_to_object);
		if (geo->intersect(transformedRay, isect))
		{
			*isect = transform_intersection(*isect, Object::transform_object_to_world, Object::transform_object_to_world_normal);
			isect->t = glm::distance(ray.origin, isect->position);
			return true;
		}
		else return false;
	}
	return geo->intersect(ray, isect);
}
Ejemplo n.º 5
0
void			get_nearest_cylinder(t_vector ray, t_object *cylinder,
	t_surface *surface, t_scene *scene)
{
	t_double2		distance;
	t_surface		*tmp;
	t_vector		ray_s;

	ray_s = transform_ray(ray, cylinder);
	if (intersect_cylinder(ray_s, cylinder, &distance))
	{
		tmp = cut_object(ray, cylinder, distance, scene);
		if (tmp->object != NULL && (surface->distance == -1 || surface->distance > tmp->distance))
		{
			surface->object = tmp->object;
			surface->distance = tmp->distance;
			surface->normal = tmp->normal;
			// surface->color = tmp->object->color;
			surface->color = cylindrical_mapping(scene, surface, ray_s, cylinder);
			free(tmp);
		}
	}
}
Ejemplo n.º 6
0
roots intersection_with_ray(sphere s, ray r)
{
	// We need r in sphere-coordinates

	ray r_sphere_coordinates;
	matrix s_transform_inverse = inverse_of_matrix(s.transform);
	r_sphere_coordinates.point     = transform_point(s_transform_inverse, r.point);
	r_sphere_coordinates.direction = transform_ray(s_transform_inverse, r.direction);

	vector point_minus_center = subtract_vectors(r_sphere_coordinates.point, s.center);

	float polynomials[3];

	polynomials[2] = square_of_magnitude_of_vector(r_sphere_coordinates.direction);
	polynomials[1] = 2 * dot_product(point_minus_center, r_sphere_coordinates.direction);
	polynomials[0] = square_of_magnitude_of_vector(point_minus_center) - s.radius * s.radius;

	roots quad_roots;

	quad_roots = quadratic(polynomials[2], polynomials[1], polynomials[0]);

	return quad_roots;
}