Пример #1
0
void test_cast_ray(void){
   struct sphere s[2];
   struct color c1 = create_color(1,0,.3);
   s[0] = create_sphere(create_point(1.4,2.6,0), 2, c1);
   s[1] = create_sphere(create_point(4.5, 5, 0), 1,c1);

   struct ray r = create_ray(create_point(0,0,0), 
                             create_vector(1.4,2.6,0));

   struct ray r2 = create_ray(create_point(-123.2,-4,-.3),
                             create_vector(1.3,-2.9,-.3));

   struct ray r3 = create_ray(create_point(-4.5,-4.3,0),
                             create_vector(-23,-100,-100));

   checkit_int(cast_ray(r,s,2).r, 1);
   checkit_int(cast_ray(r,s,2).g, 0);
   checkit_int(cast_ray(r,s,2).b, .3);

   checkit_int(cast_ray(r2,s,2).r, 1);
   checkit_int(cast_ray(r2,s,2).g, 1);
   checkit_int(cast_ray(r2,s,2).b, 1);

   checkit_int(cast_ray(r3,s,2).r, 1);
   checkit_int(cast_ray(r3,s,2).g, 1);
   checkit_int(cast_ray(r3,s,2).b, 1);

}
Пример #2
0
color pathtracer::cast_ray(ray r, int step, bool internal) {
	intersection is = find_nearest(r);
	if (!is.object) // No intersection
		return *background_color;
	color out = color();
	for (std::shared_ptr<light> l : *lights) {
		color lcol = color();
		if (is.object.get() == dynamic_cast<const shape *>(l.get()))
			out += *is.object->shade(color(1, 1, 1), *is.norm, *is.norm, -r.d, *is.local_pos, internal);
		else {
			const std::shared_ptr<std::vector<intersection>> dirs = l->get_directions(*is.pos, cam->shadow_rays);
			for (intersection d : *dirs) {
				direction light_dir = (*is.pos - *d.pos) * 0.999;
				if (!cast_shadow(*is.pos, -light_dir)) {
					//light_dir = normalise(light_dir);
					lcol += *is.object->shade(*l->emit(light_dir, d), -normalise(light_dir), *is.norm, -r.d,
											  *is.local_pos, internal);
				}
			}
			if (dirs->size() > 0)
				out += lcol * (1.0f / dirs->size());
		}
	}
	if (step < cam->max_bounces - 1) {
		std::shared_ptr<ray> sctr_ray = is.object->scatter(-r.d, *is.norm, *is.pos);
		if (sctr_ray) {
			//color sctr_col = cast_ray(*sctr_ray, step + 1, internal);
			color sctr_col = *is.object->shade(cast_ray(*sctr_ray, step + 1, internal), sctr_ray->d, *is.norm, -r.d,
											   *is.local_pos, internal) * static_cast<float>(M_PI);
			out += sctr_col;
		}
		std::shared_ptr<ray> refl_ray = internal ? nullptr : is.object->reflect(-r.d, *is.norm, *is.pos);
		if (refl_ray) {
			color refl_col = cast_ray(*refl_ray, step + 1, internal);
			refl_col = refl_col * is.object->get_reflectance();
			out += refl_col;
		}
		std::shared_ptr<ray> refr_ray = is.object->refract(-r.d, internal ? -*is.norm : *is.norm, *is.pos,
														   internal);
		if (refr_ray) {
			color refr_col = color();
			refr_col += cast_ray(*refr_ray, step + 1,
								 dot(refr_ray->d, internal ? -*is.norm : *is.norm) < 0 == !internal);
			refr_col =
					refr_col * (internal ? std::exp(-(1 - is.object->get_transmittance()) * length(*is.pos - r.o))
										 : is.object->get_transmittance());
			out += refr_col;
		}
	}
	return out;
}
Пример #3
0
colour		get_the_scene(t_rt_client *rt, int x, int y)
{
  t_ray		ray;
  t_color	color;
  t_obj		*tmp;
  t_obj		*obj_result;

  tmp = rt->objs;
  obj_result = NULL;
  ray.color = &color;
  init_ray(rt, &ray, x, y);
  while (rt && tmp && tmp->color)
    {
      assign_ray(rt, &ray, tmp);
      obj_result = cast_ray(&ray, tmp, obj_result);
      tmp = tmp->next;
    }
  if (obj_result && obj_result->color)
    {
      assign_ray(rt, &ray, obj_result);
      obj_result->color->color = perlin_color(rt, &ray, obj_result);
      lighting(&ray, obj_result, rt->spot);
      shadows(rt, &ray, obj_result);
    }
  return (ray.color->color);
}
void cast_aa_ray(int x, int y)
{

    double color[3],color1[3],color2[3],color3[3],color4[3];


    /*Anti-Aliasing by super sampling for each pixel using grid algorithm method
    ---------
    | . . . |
    | . . . |
    | . . . |
    ---------
    */

    cast_ray(x+.25f, y+.5f, color1);
    cast_ray(x+.5f, y+.75f, color2);
    cast_ray(x+.5f, y+.25f, color3);
    cast_ray(x+.75f, y+.5f, color4);

    /* I am using only 4 grids i.e averaging by 4 per pixel */
    color[0] = (color1[0]+color2[0]+color3[0]+color4[0]) / 4;
    color[1] = (color1[1]+color2[1]+color3[1]+color4[1]) / 4;
    color[2] = (color1[2]+color2[2]+color3[2]+color4[2]) / 4;


    if(color[0] > 1)
        color[0] = 1;
    else if (color[0] < 0)
        color[0] = 0;
    color[0] *= 255;

    if(color[1] > 1)
        color[1] = 1;
    else if (color[1] < 0)
        color[1] = 0;
    color[1] *= 255;

    if(color[2] > 1)
        color[2] = 1;
    else if (color[2] < 0)
        color[2] = 0;
    color[2] *= 255;

    plot_pixel_jpeg(x,y,color[0],color[1],color[2]);

}
Пример #5
0
int		button_pess(int button, int x, int y, t_env *e)
{
	t_vect	ray;

	(void)button;
	e->test = 1;
	create_ray(e, &ray, x, y);
	cast_ray(e, &ray, x, y);
	e->test = 0;
	return (1);
}
Пример #6
0
void update_sight()
{
	list_node *c;
	line_point *p;
	memset(RAYS, 0, sizeof(RAYS));
	RAY_INDEX = 0;

	double dx, dy;
	for (c = CORNERS->next; c->next != NULL; c = c->next) {
		if (((line_point *) c->data) != NULL) {
			p = (line_point *) c->data;
			dx = p->x - get_player_x();
			dy = p->y - get_player_y();
			cast_ray(sqrt(dy*dy + dx*dx), atan2(dy, dx) - 0.01, false);
			cast_ray(sqrt(dy*dy + dx*dx), atan2(dy, dx), false);
			cast_ray(sqrt(dy*dy + dx*dx), atan2(dy, dx) + 0.01, false);
		}
	}
	qsort(RAYS, RAY_INDEX, sizeof(ray), thetacmp);
}
void TCOD_map_compute_fov_circular_raycastingi(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) {
	int xo,yo;
	map_t *m = (map_t *)map;
	/* circular ray casting */
	int xmin=0, ymin=0, xmax=m->width, ymax=m->height;
	int c;
	int r2=max_radius*max_radius;
	if ( max_radius > 0 ) {
		xmin=MAX(0,player_x-max_radius);
		ymin=MAX(0,player_y-max_radius);
		xmax=MIN(m->width,player_x+max_radius+1);
		ymax=MIN(m->height,player_y+max_radius+1);
	}
	for (c=m->nbcells-1; c >= 0; c--) {
		m->cells[c].fov=0;
	}
	xo=xmin; yo=ymin;
	while ( xo < xmax ) {
		cast_ray(m,player_x,player_y,xo++,yo,r2,light_walls);
	}
	xo=xmax-1;yo=ymin+1;
	while ( yo < ymax ) {
		cast_ray(m,player_x,player_y,xo,yo++,r2,light_walls);
	}
	xo=xmax-2;yo=ymax-1;
	while ( xo >= 0 ) {
		cast_ray(m,player_x,player_y,xo--,yo,r2,light_walls);
	}
	xo=xmin;yo=ymax-2;
	while ( yo > 0 ) {
		cast_ray(m,player_x,player_y,xo,yo--,r2,light_walls);
	}
	if ( light_walls ) {
		/* post-processing artefact fix */
		TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1);
		TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1);
		TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1);
		TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1);
	}
}
Пример #8
0
double
Get_Skew::histogram( const Raster &raster, double angle)
{
  int    i;
  double sum;
  double mean;
  double angle_diff  = tan(angle / (180.0 / M_PI));
  int    diff_y      = -static_cast<int>( raster.width() * angle_diff);
  int    min_y       = max( 0, diff_y);
  int    max_y       = min( static_cast<int>( raster.height())
                          , raster.height() + diff_y);
  int    num_rows;
  Fixed  dx;
  int    dy;


  if (raster.height() > m_max_rows) {
    delete []m_rows;
    m_rows = new unsigned[ raster.height()];
    m_max_rows = raster.height();
  }
  num_rows = (max_y - min_y) / m_sample_skip + 1;

  if (angle < 0) {
    dy = -1;
  } else {
    dy = +1;
  }
  if ((-0.05 < angle) && (angle < 0.05)) {
    dx = static_cast<int>( raster.width());
  } else {
    dx = dy / (tan( angle / (180.0 / M_PI)));
  }

  for (i = 0; i < num_rows; ++i) {
    m_rows[ i] = cast_ray( raster, min_y + i * m_sample_skip, dx, dy);
  }

  sum = 0.0;
  for (i = 0; i < num_rows; ++i) {
    sum += m_rows[ i];
  }
  mean = sum / num_rows;

  sum = 0.0;
  for (i = 0; i < num_rows; ++i) {
    sum += sqr( m_rows[ i] - mean);
  }

  return sum / num_rows;
}
Пример #9
0
void			draw_fov(t_env *env)
{
	double		angl;
	int			i;

	angl = LOOK_DIR + FOV_ANGL / 2;
	angl -= (angl > 2 * M_PI) ? 2 * M_PI : 0;
	i = 0;
	while (i < X_SZE)
	{
		cast_ray(env, angl, i);
		angl -= FOV_ANGL / X_SZE;
		angl += (angl < 0) ? 2 * M_PI : 0;
		i++;
	}
}
Пример #10
0
void		calc_color_alias(t_rt *img, t_ray *ray, t_obj *tmp)
{
  t_obj		*obj_result;

  init_alias(img, ray);
  obj_result = NULL;
  while (img && ray && tmp && tmp->color)
    {
      assign_ray(img, ray, tmp);
      obj_result = cast_ray(ray, tmp, obj_result);
      tmp = tmp->next;
    }
  if (obj_result != NULL && obj_result->color)
    {
      assign_ray(img, ray, obj_result);
      obj_result->color->color = perlin_color(img, ray, obj_result);
      lighting(ray, obj_result, img->spot);
      shadows(img, ray, obj_result);
    }
}
Пример #11
0
void		render_scene(t_interface *env)
{
	int		x;
	int		y;
	t_vec3f	*image;
	t_vec3f	*pixel;

	y = 0;
	image = (t_vec3f*)malloc(sizeof(t_vec3f) * (WIDTH * HEIGHT));
	if ((pixel = image) == NULL)
		return ;
	while (y < HEIGHT && !(x = 0))
	{
		while (x < WIDTH)
		{
			cast_ray(x, y, pixel++, env);
			x++;
		}
		y++;
	}
	paint_mlx(image, env->gui);
	free(image);
}
Пример #12
0
void Player::UpdateRays(const long elapsed_time)
{
    (void) elapsed_time;

    auto is_level_blocking = [&](const int map_x, const int map_y) {
        return mWorld.IsBlocking(map_x, map_y);
    };

    const auto ray_count = mRays.size();

    for (auto x = 0u; x < ray_count; x++)
    {
        // Current column position relative to the center of the screen.
        // Left edge is -1, right edge is 1, and center is 0.
        const double cam_x = 2.0 * x / ray_count - 1;

        // Starting direction of the current ray to be cast.
        const double ray_dir_x = mDirX + (mPlaneX * cam_x);
        const double ray_dir_y = mDirY + (mPlaneY * cam_x);

        cast_ray(mPosX, mPosY, ray_dir_x, ray_dir_y, is_level_blocking, mRays[x]);
    }
}
color scene_3D::cast_ray(line_3D line, double threshold, unsigned int recursion_depth)
  {
    unsigned int k, l, m;
    triangle_3D triangle;
    color final_color, helper_color, add_color;
    double depth, t;
    double *texture_coords_a, *texture_coords_b, *texture_coords_c;
    double barycentric_a, barycentric_b, barycentric_c;
    point_3D starting_point;
    point_3D normal,normal_a,normal_b,normal_c;
    point_3D reflection_vector, incoming_vector_reverse;
    material mat;
    int color_sum[3];

    line.get_point(0,starting_point);

    depth = 99999999;

    final_color.red = this->background_color.red;
    final_color.green = this->background_color.green;
    final_color.blue = this->background_color.blue;

    for (k = 0; k < this->meshes.size(); k++)
      {
        if (!line.intersects_sphere(this->meshes[k]->bounding_sphere_center,this->meshes[k]->bounding_sphere_radius))
          continue;

        for (l = 0; l < this->meshes[k]->triangle_indices.size(); l += 3)
          {
            triangle.a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].position;
            triangle.b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].position;
            triangle.c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].position;

            texture_coords_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].texture_coords;
            texture_coords_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].texture_coords;
            texture_coords_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].texture_coords;

            if (line.intersects_triangle(triangle,barycentric_a,barycentric_b,barycentric_c,t))
              {
                point_3D intersection;
                line.get_point(t,intersection);
                double distance = point_distance(starting_point,intersection);

                mat = this->meshes[k]->get_material();

                if (distance < depth && distance > threshold)  // depth test
                  {
                    depth = distance;

                    normal_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].normal;
                    normal_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].normal;
                    normal_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].normal;

                    normal.x = 0;
                    normal.y = 0;
                    normal.z = 0;

                    normal.x = barycentric_a * normal_a.x + barycentric_b * normal_b.x + barycentric_c * normal_c.x;
                    normal.y = barycentric_a * normal_a.y + barycentric_b * normal_b.y + barycentric_c * normal_c.y;
                    normal.z = barycentric_a * normal_a.z + barycentric_b * normal_b.z + barycentric_c * normal_c.z;
                    normalize(normal);  // interpolation breaks normalization

                    if (!this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture() != 0)        // 2d texture
                      {
                        double u,v;

                        u = barycentric_a * texture_coords_a[0] + barycentric_b * texture_coords_b[0] + barycentric_c * texture_coords_c[0];
                        v = barycentric_a * texture_coords_a[1] + barycentric_b * texture_coords_b[1] + barycentric_c * texture_coords_c[1];

                        color_buffer_get_pixel(this->meshes[k]->get_texture(),u * this->meshes[k]->get_texture()->width,v * this->meshes[k]->get_texture()->height,&final_color.red,&final_color.green,&final_color.blue);
                      }
                    else if (this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture_3D() != 0) // 3d texture
                      {
                        final_color = this->meshes[k]->get_texture_3D()->get_color(intersection.x,intersection.y,intersection.z);
                      }
                    else                                                                                // mesh color
                      {
                        final_color.red = 255;
                        final_color.green = 255;
                        final_color.blue = 255;
                      }

                    helper_color = compute_lighting(intersection,mat,normal);
                    final_color = multiply_colors(helper_color,final_color);

                    if (recursion_depth != 0)
                      {
                        incoming_vector_reverse = line.get_vector_to_origin();

                        if (mat.reflection > 0)                         // reflection
                          {
                            color_sum[0] = 0;
                            color_sum[1] = 0;
                            color_sum[2] = 0;

                            for (m = 0; m < this->reflection_rays; m++)
                              {
                                point_3D helper_point;
                                reflection_vector = make_reflection_vector(normal,incoming_vector_reverse);

                                reflection_vector.x *= -1;
                                reflection_vector.y *= -1;
                                reflection_vector.z *= -1;

                                if (m > 0) // alter the ray slightly
                                  alter_vector(reflection_vector,this->reflection_range);

                                helper_point.x = intersection.x + reflection_vector.x;
                                helper_point.y = intersection.y + reflection_vector.y;
                                helper_point.z = intersection.z + reflection_vector.z;

                                line_3D reflection_line(intersection,helper_point);

                                add_color = cast_ray(reflection_line,ERROR_OFFSET,recursion_depth - 1);

                                color_sum[0] += add_color.red;
                                color_sum[1] += add_color.green;
                                color_sum[2] += add_color.blue;
                              }

                            add_color.red = color_sum[0] / this->reflection_rays;
                            add_color.green = color_sum[1] / this->reflection_rays;
                            add_color.blue = color_sum[2] / this->reflection_rays;

                            final_color = interpolate_colors(final_color,add_color,mat.reflection);
                          }

                        if (mat.transparency > 0)                       // refraction
                          {
                            color_sum[0] = 0;
                            color_sum[1] = 0;
                            color_sum[2] = 0;

                            for (m = 0; m < this->refraction_rays; m++)
                              {
                                point_3D helper_point;
                                point_3D refraction_vector;
                                refraction_vector = make_refraction_vector(normal,incoming_vector_reverse,mat.refractive_index);

                                if (m > 0) // alter the ray slightly
                                  alter_vector(refraction_vector,this->refraction_range);

                                helper_point.x = intersection.x + refraction_vector.x;
                                helper_point.y = intersection.y + refraction_vector.y;
                                helper_point.z = intersection.z + refraction_vector.z;

                                line_3D refraction_line(intersection,helper_point);
                                add_color = cast_ray(refraction_line,ERROR_OFFSET,recursion_depth - 1);

                                color_sum[0] += add_color.red;
                                color_sum[1] += add_color.green;
                                color_sum[2] += add_color.blue;
                              }

                            add_color.red = color_sum[0] / this->refraction_rays;
                            add_color.green = color_sum[1] / this->refraction_rays;
                            add_color.blue = color_sum[2] / this->refraction_rays;

                            final_color = interpolate_colors(final_color,add_color,mat.transparency);
                          }
                      }
                  }
                }
              }
            }

    return final_color;
  }
Пример #14
0
void render( int width, int height, Point campos, EulerRotation camangle, std::vector<SceneObject>& scenedesc, Bitmap& bmp) {
  double fov = 90;

  double factor = (double(height)/2)/tan(fov*M_PI/360.0);

  Vector lightdir = Vector(0.0,-2.0,-1.0);
  lightdir.normalize_l2();

  // Construct a ray for each pixel.
  for (int i = 0; i < width; i++) {
    for (int j = 0; j < height; j++) {

      Color skycol(0x9E,0xE2,0xEA);

      Color col = skycol;

      // Sets up ray origin and direction in view space, 
      // image plane is at z = -1.
      Vector imagePlane;

      imagePlane[_X_] = (-double(width)/2 + j + 0.5)/factor;
      imagePlane[_Z_] = (-double(height)/2 + i + 0.5)/factor;
      imagePlane[_Y_] = -1;

      imagePlane = imagePlane.rotate(camangle);

      // TODO: Convert ray to world space and call 
      // shadeRay(ray) to generate pixel color.  
      
      Ray ray;
      // initialize ray and convert to world coords
      ray.origin = campos;
      ray.dir = imagePlane;
      ray.dir.normalize_l2();

      cast_ray( ray, scenedesc );

      double maxdist = 40;

      double occulddist = 0.1;

      if(ray.intersected) {
        Vector normal = -ray.gradient;
        normal.normalize_l2();

        double diffuse = fmax(normal.dot(-lightdir),0.0);

        Vector c = -(2.0 * normal.dot(lightdir) * normal - lightdir);

        double specular = fmax(ray.dir.dot(c),0.0);
        specular = pow(specular,10.0);

        // only cast if diffuse is nonzero
        // if(diffuse!=0){
        //   Ray lightray;
        //   lightray.origin = ray.intsec;// - 0.1*normal;
        //   lightray.dir = lightdir;
        //   cast_ray(lightray, scenedesc);

        //   if(lightray.intersected){
        //     diffuse = 0;
        //     specular = 0;
        //   }// } else {
        //   //   double umbra = clamp(8*lightray.mindist, 0, 1);
        //   //   diffuse *= umbra;
        //   //   specular *= umbra;
        //   // }
        // }


        // Vector normal2 = (2.0*normal/normal.linf() + Vector(1.0,1.0,1.0))/2.0;
        // Color normalcol;
        // normalcol[0] = normal2[0];
        // normalcol[1] = normal2[1];
        // normalcol[2] = normal2[2];

        // double ambient = fmax(f(ray.intsec - occulddist*normal) / occulddist, 0.0);
        // ambient = 1-pow(1-ambient,2.0);

        //only apply ambient when diffuse is low
        // ambient = fmax(ambient,diffuse);

        // col = ambient*0.1*Color(0.7,0.65,0.6) + diffuse*0.8 * Color(0.7,0.65,0.6) + 
          // pow(specular,50.0)*0.5 * Color(1.0,1.0,1.0);


        col = diffuse*Color(0.6,0.6,0.6) + specular*Color(1.0,1.0,1.0);

        double fog = (ray.intsec-campos).l2()/maxdist;
        fog = 1-pow(1-fog,2.0);

        col = fog * skycol + (1-fog) * col;

      }
      double sun = pow(fmax(ray.dir.dot(lightdir),0.0),200);
      col = col + sun*Color(1.0,1.0,0.8);

      col.clamp();
      bmp(i,j) = col;

      if(j%100 == 0){
        int percent = 100.0*(1.0*i*width + j) / (height*width);
        std::cerr << "\r"<< std::setw(3) << std::setfill('0') << percent << "% completed: ";

        std::cerr  << std::string(percent/2, '|');

        std::cerr.flush();
      }
    }
  }
}