Esempio n. 1
0
static inline	t_color	recursive_tracer(t_params p, t_ray *ray, t_objects *sp)
{
	t_f64	inside;
	t_f64	facingratio;
	t_f64	fresneleffect;
	t_vec3f	refldir;
	t_vec3f	refdir;
	t_color	reflection;
	t_color	refrac;
	t_ray	rx;

	if ((inside = dot_vec3f(&ray->dir, &p.nhit) > 0))
		p.nhit = scale_vec3f(&p.nhit, -1);
	facingratio = -dot_vec3f(&ray->dir, &p.nhit);
	fresneleffect = mix(pow(1 - facingratio, 3), 1, .1);
	refldir = get_reflection_dir(&p.nhit, &ray->dir);
	rx = reflected_ray(ray, &refldir, &p.nhit, &p.phit);
	reflection = trace_ray(&rx, sp, ++p.depth);
	if (p.sphere->transparency > 0)
	{
		refdir = compute_ideal_refractions(ray, inside, p);
		rx = refracted_ray(ray, &refdir, &p.nhit, &p.phit);
		refrac = trace_ray(&rx, sp, ++p.depth);
	}
	return (defualt_glossy_shading(&reflection,
				&refrac, fresneleffect, p.sphere));
}
Esempio n. 2
0
/*******
 Fonction à écrire par les etudiants
 ******/
Color trace_ray (Ray ray_) {
/**
 * \todo : recursive raytracing
 *
 * La fonction trace_ray() renvoie une couleur obtenue par la somme de l'éclairage direct (couleur calculée par la fonction 
 * compute_direct_lighting()) et des couleurs provenant des reflets et transparences éventuels aux points d'intersection. 
 * Dans la première partie du TP, seul l'éclairage direct sera calculé. Dans la seconde partie, les reflets et transparences seront rajoutés.
 *
 * Pour la première étape, la fonction trace_ray() ne calculant que les rayons primaires, l'intersection 
 * entre le rayon et la scène doit être calculée (fonction intersect_scene() du module \ref RayAPI).
 * S'il n'y a pas d'intersection, une couleur blanche (triplet RGB [1, 1, 1], élément neutre de la multiplication des couleurs) 
 * devra être retournée.
 * S'il y a une intersection, la couleur retournée sera la couleur résultante de l'éclairage direct du point d'intersection par les 
 * sources lumineuses de la scène et calculée par la fonction compute_direct_lighting() à écrire dans la suite.
 *
 * Pour la deuxième étape, à partir des fonctions définies dans le module \ref RayAPI et permettant d'accéder aux informations de 
 * profondeur et d'importance sur le rayon, définir un cas d'arêt dela récursivité et renvoyer si ce cas est vérifié la couleur 
 * résultante de l'éclairage direct. Si la récursivité n'est pas terminée, en utilisant les fonctions définies dans le module \ref LightAPI,
 * calculer la couleur réfléchie. Pour cela, il  faut tester si le matériau est réflechissant et, si c'est le cas, calculer le rayon 
 * réfléchi et le coefficient de réflexion (une couleur). La couleur calculée en lançant le rayon réfléchi devra alors être multipliée par ce coefficient avant d'être ajoutée
 * à la couleur renvoyée par trace_ray().
 *
 * Pour la troisème étape et de façon très similaire à la réflexion, utiliser les fonctions définies dans le module \ref LightAPI pour calculer la couleur réfractée.
 * Pour cela, il  faut tester si le matériau est transparent et, si c'est le cas, calculer le rayon réfracté et le coefficient de 
 * transparence (une couleur). La couleur calculée en lançant le rayon réfracté devra alors être multipliée par ce coefficient avant
 * d'être ajoutée à la couleur renvoyée par trace_ray().
 *
*/

	Color l = init_color (0.075f, 0.075f, 0.075f);
	Isect isect_;
	
	int isInter = intersect_scene (&ray_, &isect_ );
	
	if (isInter!=0){
	  l = compute_direct_lighting (ray_, isect_);
	}
	
	if (ray_depth(ray_)>10 || ray_importance(ray_)<0.01f)
	  return (l);
	
	//reflection
	if(isect_has_reflection(isect_)){
		Ray refl_ray;
		Color refl_col = reflect(ray_, isect_, &refl_ray);
		l = l+refl_col*(trace_ray(refl_ray));
	}
	//refraction
	if(isect_has_refraction(isect_)){
	 Ray rafr_ray;
	 Color rafr_col = refract(ray_, isect_, &rafr_ray);
	 if(color_is_black(rafr_col)==0)
	  l = l+rafr_col*(trace_ray(rafr_ray));
	}

	return l;
}
Esempio n. 3
0
/*
 * Trace a ray, calculating the color of this ray.
 * This function is called recursively for recursive light.
 *
 * @param scene     The scene object, which contains all geometries information.
 * @param recursion The level of recursive light. If the level is larger or 
 *                  equal to 4, stop recursion.
 * @param ray_dir   Direction vector of ray.
 * @param ray_pos   Start point of ray.
 * @param tMin      Minimum legal time cost for this ray.
 * @param tMax      Maximum legal time cost for this ray.
 *
 * @return  The color of this ray.
 */
Color3 Raytracer::trace_ray(Scene const*scene,      // geometries
                            const int recursion,    // recursion level
                            const Vector3 &ray_dir, const Vector3 &ray_pos, // ray
                            const float tMin,       const float tMax        // ray range
                           )
{
    // if this function go beyond the last recursive level, stop and return black color.
    if (recursion <= 0)
        return Color3(0, 0, 0);

    // intersection point information
    HitVertexInfor hit_vertex;

    // if not hit any geometry, return background color
    bool bHit = ray_hit(scene, ray_dir, ray_pos, tMin, tMax, hit_vertex);
    if (!bHit)
        return scene->background_color;

    // if hit, compute color and return it
    Color3 DI_light (0, 0, 0);
    Color3 reflected_light(0, 0, 0);
    Color3 refracted_light(0, 0, 0);

    // 1. direct illumination
    if (hit_vertex.refractive_index == 0)
        DI_light = calculate_DI_light(scene, hit_vertex);

    // 2. reflection light
    if (hit_vertex.specular != Color3(0, 0, 0)) // avoid non-necessary reflection calculation
    {
        // reflection ray direction
        Vector3 rfl_ray_dir = normalize(
            ray_dir - 2 * dot(ray_dir, hit_vertex.normal) * hit_vertex.normal);

        reflected_light = hit_vertex.specular * hit_vertex.tex_color *
                          trace_ray(scene, recursion-1, rfl_ray_dir, hit_vertex.position,
                                    SLOPE_FACTOR, 1000000);
    }

    if (hit_vertex.refractive_index == 0)   // avoid non-necessary refraction calculation
        return DI_light + reflected_light;

    // 3. refraction light
    Vector3 rfr_ray_dir; // refractive ray direction
    float R;
    if (refraction_happened(scene, ray_dir, hit_vertex, rfr_ray_dir, R))
        refracted_light = hit_vertex.tex_color *
                          trace_ray(scene, recursion-1, rfr_ray_dir, hit_vertex.position, 
                                    SLOPE_FACTOR, 1000000);

    return DI_light + R * reflected_light + (1-R) * refracted_light;
}
Esempio n. 4
0
/*******
 Fonction à écrire par les etudiants
 ******/
void compute_image () {
/**
 * \todo : main rendering loop
 *
 * Le calcul d'une image de synthèse consiste à calculer une couleur pour tous les pixels d'une image en fonction 
 * d'une modélisation d'un capteur virtuel.
 * Ce capteur est ici représenté par une Camera qui permet, à partir des coordonnées (x,y) d'un pixel d'une image, 
 * de créer le rayon passant par ce pixel. La manière dont est créé ce rayon dépend de la Camera. 
 * La scène étant crée avec une caméra par défaut de type \b pinhole, la fonction camera_ray() 
 * devra être utilisée afin de créer le rayon primaire. 
 * Ce rayon est ensuite tracé dans la scène (par la fonction trace_ray())
 * et la couleur calculée à l'aide de ce rayon doit être stockée sur le pixel (x,y).
*/

  int i,j, img_height, img_width;
  Ray ray_;
  Color col_;

  get_image_resolution(&img_width, &img_height);
  
  for(i=0; i<img_width; i++){
   for(j=0; j<img_height; j++){
     ray_ = camera_ray(i,j);
     col_ = trace_ray (ray_);
     set_pixel_color (i, j, col_);
   }
  }
}
//------------------------------------------------------------------ render_scene
// This is the main ray tracing loop over pixels!! Start here.
void
RenderEngine::render_scene()
{
    Camera *camera = world_ptr->camera_ptr;
    RGBColor pixel_color;

    // PART 1:
    for (int row=0; row < camera->xres; row++){
        for (int col=0; col< camera->yres; col++){
            Ray curRay = camera->pixRay(row, col);
            pixel_color = trace_ray(curRay, world_ptr->depth);
            int index = col * 3 * camera->xres + row*3 ;
            camera->image[index]   = pixel_color.r;
            camera->image[index+1] = pixel_color.g;
            camera->image[index+2] = pixel_color.b;
        }
    }
    // Loop over rows and columns of images (pixels)
        // Compute the ray from camera to the given pixel (see function in Camera class)
        // trace the ray to get pixel_color (i.e. call trace_ray)
        //       (Do you remember which class stores the depth? If not, find out.)
        // make sure color is in range (1,0)  - see max_to_one() function
        // set image pixel to this color as follows:
            //int index = row * 3 * camera->xres + col*3 ;
            //camera->image[index]   = pixel_color.r;
            //camera->image[index+1] = pixel_color.g;
            //camera->image[index+2] = pixel_color.b;

}
Esempio n. 6
0
int ray_trace(char* filename) {
  ray3_t primary_ray;
  int frame_z = 300;
  int frame_x = 0;
  int frame_y = 0;
  color_t hicolor;

  for (frame_x = 0; frame_x < frame_width; ++frame_x) {
    for (frame_y = 0; frame_y < frame_height; ++frame_y) {

      /* Primary Ray (test ray) */
      primary_ray.origin = eye_origin;
      primary_ray.vector.x = (frame_x - (frame_width/2) - primary_ray.origin.x);
      primary_ray.vector.y = (frame_y - (frame_height/2) - primary_ray.origin.y);
      primary_ray.vector.z = (frame_z - primary_ray.origin.z);
      normalize_vector(&primary_ray.vector);

      hicolor = trace_ray(&primary_ray, 0);
      frame_buffer[frame_y][frame_x].r = (uint8_t) (hicolor.r * 0xFF);
      frame_buffer[frame_y][frame_x].g = (uint8_t) (hicolor.g * 0xFF);
      frame_buffer[frame_y][frame_x].b = (uint8_t) (hicolor.b * 0xFF);
      frame_buffer[frame_y][frame_x].a = (uint8_t) (hicolor.a * 0xFF);
    }
  }

  write_bmp(filename, frame_width, frame_height, frame_buffer);
  return 0;
}
Esempio n. 7
0
bool trace_ray(const Ray& ray, const std::list<Sphere>& world, Color* color) {

  for (const Sphere& sphere: world) {
    if (trace_ray(ray, world, sphere, color)) {
      return true;
    }
  }

  return false;

}
Esempio n. 8
0
int main() {

  std::list<Sphere> world = { // front to back
    { { 1, 1, 1 }, .3 },
    { { -1, .5, 2 }, .4 },
    { { 0, 0, 0 }, 1 },
  };

  Ray ray;
  ray.direction = Vec3 { 0, 0, -1 };
  const float zoom = 2;

  const int width = 1920, height = 1080, oversampling = 4;
  const Color background { 0, 0, 0 };

  std::cout << "P3" << std::endl << width << ' ' << height << ' ' << 255 << std::endl;

  for (float y = 0; y < height; ++y) {

    std::cerr << '\r' << int(y * 100 / height) << " %";

    for (float x = 0; x < width; ++x) {

      Color color = background;

      for (int sy = 0; sy < oversampling; ++sy) {
        for (int sx = 0; sx < oversampling; ++sx) {

          ray.origin = Vec3 {
            zoom * ((x * oversampling + sx) / (width * oversampling) * 2 - 1),
            zoom * height / width * -((y * oversampling + sy) / (height * oversampling) * 2 - 1),
            10
          };

          Color sample = background;

          trace_ray(ray, world, &sample);

          color.r += sample.r / (oversampling * oversampling);
          color.g += sample.g / (oversampling * oversampling);
          color.b += sample.b / (oversampling * oversampling);

        }
      }

      std::cout << (int)color.r << ' ' << (int)color.g << ' ' << (int)color.b << ' ';

    }

    std::cout << std::endl;

  }

}
Esempio n. 9
0
void		cast_ray(int x, int y, t_vec3f *pixel, t_interface *env)
{
	t_vec3f	dir;
	t_ray	ray;
	t_f64	xx;
	t_f64	yy;

	xx = (2 * ((x + 0.5) * (1.0 / WIDTH)) - 1) * env->camera.angle * ARATIO;
	yy = (1 - 2 * ((y + 0.5) * (1.0 / HEIGHT))) * env->camera.angle;
	dir = new_vec3f(xx, yy, 0);
	dir = add_vec3f(&dir, &env->camera.up);
	ray = new_ray(env->camera.pos, normal_vec3f(&dir));
	*pixel = trace_ray(&ray, env->objects, 0);
}
Esempio n. 10
0
File: udray.cpp Progetto: ReeLiu/ray
void raytrace_one_pixel(int i, int j)
{
	double x, y;
	Vect eye_color;

	x = 0.5 + (double) i;   // the "center" of the pixel
	y = 0.5 + (double) j;

	set_pixel_ray_direction(x, y, ray_cam, eye_ray);

	eye_color[R] = eye_color[G] = eye_color[B] = 0.0;
	trace_ray(0, 1.0, eye_ray, eye_color);

	draw_point(i, j, eye_color, ray_cam->im);
}
Esempio n. 11
0
/**
 * Performs a raytrace on the given pixel on the current scene.
 * The pixel is relative to the bottom-left corner of the image.
 * @param scene The scene to trace.
 * @param x The x-coordinate of the pixel to trace.
 * @param y The y-coordinate of the pixel to trace.
 * @param width The width of the screen in pixels.
 * @param height The height of the screen in pixels.
 * @return The color of that pixel in the final image.
 */
Color3 Raytracer::trace_pixel( const Scene* scene, size_t x, size_t y, size_t width, size_t height )
{
    assert( 0 <= x && x < width );
    assert( 0 <= y && y < height );

    // get ray direction
    Vector3 position  = m_camera_pos;
    Vector3 direction = m_camera_dir +                    // camera direction
                        m_up_step    * (y*1.0f-height/2) + // vertical increasement
                        m_right_step * (x*1.0f-width /2);  // horizontal increasement
    direction = normalize(direction);

    // trace a ray and return its color
    return trace_ray( scene, 4, direction, position, m_near_clip, m_far_clip );
}
Esempio n. 12
0
/* render : runs trace_ray over each pixel, writes colors to file f */
void render(FILE *f, stage g)
{
  int x, y;
  xyz loc;
  ray r;
  r.origin = g.c.loc;

  fprintf(f, "P3 %d %d 255\n", g.c.w, g.c.h);

  for (y=0; y<g.c.h; y++) {
    for (x=0; x<g.c.w; x++) {
      loc = logical_loc(g.c, x, y);
      r.dir = xyz_sub(loc,r.origin);
      color_show_bytes(f, trace_ray(g.s, r));
    }
  }
}
Esempio n. 13
0
//-------------------------------------------------------------------------------------------
//      メインエントリーポイントです.
//-------------------------------------------------------------------------------------------
int main(int argc, char **argv) 
{
    auto w = 1280;      // 画像の横幅.
    auto h = 1080;      // 画像の縦幅.
    auto s = 10000;     // s * 1000 photon paths will be traced
    auto c = new Vector3[ w * h ];

    hpbbox.reset();

    trace_ray( w, h );
    trace_photon( s );
    density_estimation( c, s );

    save_to_bmp( "image.bmp", w, h, &c[0].x, 2.2 );

    delete [] c;
    c = nullptr;

    return 0;
}
Esempio n. 14
0
void render(stage g)
{
  int i, j;
  camera c = g.c;
  scene sc = g.s;
  printf("P3\n");
  printf("%d %d\n", c.w, c.h);
  printf("255\n");
  for(i=0; i < c.h; i++) {
    for(j=0; j < c.w; j++) {
      vec p = {j,i,0}; 
      vec loc = logical_loc(c, p);
      vec dir = vec_sub(loc, c.loc);
      vec normdir = vec_norm(dir);
      ray r = {c.loc, normdir};
      rgb col = trace_ray(sc, r);
      rgb_print_bytes(col);
    }
  }  
}
Esempio n. 15
0
void raytrace_one_pixel(int i, int j)
{
	double x, y;
	Vect eye_color;

	x = 0.5 + (double) i;   // the "center" of the pixel
	y = 0.5 + (double) j;

	set_pixel_ray_direction(x, y, ray_cam, eye_ray);

	eye_color[R] = eye_color[G] = eye_color[B] = 0.0;
	trace_ray(0, 1.0, eye_ray, eye_color);

	draw_point(i, j, eye_color, ray_cam->im);

	// image_i++;

	// if (image_i == ray_cam->im->w) {
	// 	image_i = 0;
	// 	image_j++;
	// }  

	// thread_count--;
}
Esempio n. 16
0
void render(msg_block_t *msg, rt_context_t *rtx, uint32_t *frame_buffer)
{
  uint32_t *pixel;
  float sy = rtx->sheight * 0.5f - rtx->ayc;
  unsigned int y;
  for (y = 0; y < rtx->height; y++)
  {
    uint32_t *src = frame_buffer + (y * SCALE + rtx->yoff) * msg->fbinfo.line_length / sizeof(uint32_t) + rtx->xoff;
    pixel = src;
    float sx = rtx->swidth * -0.5f;
    unsigned int x;
    for (x = 0; x < rtx->width; x++)
    {
      rtx->ray.pos = rtx->eye;
      rtx->ray.dir = normalize(vec3_sub(vec3_set(sx, sy, 0.0f), rtx->eye));
      vec3_t col = vec3_set(0.0f, 0.0f, 0.0f);
      unsigned int j;
      for (j = 0; j < MAXREF; j++)
      {
        trace_ray(rtx);
        if (rtx->hit != NOHIT)
        {
          vec3_t p, n;
          ray_t next;
          p = vec3_add(rtx->ray.pos, vec3_scale(rtx->ray.dir, rtx->dist));
          switch (rtx->obj[rtx->hit].type)
          {
            case SPHERE:
              n = normalize(vec3_sub(p, rtx->obj[rtx->hit].pos));
              break;
            case PLANE:
              n = rtx->obj[rtx->hit].norm;
              break;
            default:
              break;
          }
          next.pos = vec3_add(p, vec3_scale(n, EPSILON));
          vec3_t lv = vec3_sub(rtx->light.pos, p);
          vec3_t l = normalize(lv);
          next.dir = rtx->ray.dir;
          int prev_hit_index = rtx->hit;
          vec3_t hit_obj_col = rtx->obj[rtx->hit].col;
          float diffuse = dot(n, l);
          float specular = dot(rtx->ray.dir, vec3_sub(l, vec3_scale(n, 2.0f * diffuse)));
          diffuse = max(diffuse, 0.0f);
          specular = max(specular, 0.0f);
          specular = power_spec(specular);
          float s1 = 1.0f;
          float s2 = 1.0f;
          if (rtx->obj[rtx->hit].flag_shadow)
          {
            rtx->ray.dir = l;
            rtx->ray.pos = next.pos;
            trace_ray(rtx);
            int shadow = (rtx->dist < norm(lv));
            s1 = shadow ? 0.5f : s1;
            s2 = shadow ? 0.0f : s2;
          }
          col = vec3_add(col, vec3_add(vec3_scale(rtx->light.col, specular * s2), vec3_scale(hit_obj_col, diffuse * s1)));
          if (!rtx->obj[prev_hit_index].flag_refrect)
          {
            break;
          }
          rtx->ray.dir = vec3_sub(next.dir, vec3_scale(n, dot(next.dir, n) * 2.0f));
          rtx->ray.pos = next.pos;
        }
        else
        {
          break;
        }
      }
      col = vec3_min(vec3_max(col, 0.0f), 1.0f);
      uint32_t col2 = 0xff000000 + ((unsigned int)(col.x * 255.0f) << 16) + ((unsigned int)(col.y * 255.0f) << 8) + (unsigned int)(col.z * 255.0f);
      *pixel = col2;
#if SCALE > 1
      *(pixel + 1) = col2;
#endif
#if SCALE > 3
      *(pixel + 2) = col2;
      *(pixel + 3) = col2;
#endif
      pixel += SCALE;
      sx += rtx->ax;
    }
    uint32_t size = rtx->width * SCALE;
    unsigned int i;
    for (i = 1; i < SCALE; i++)
    {
      uint32_t *dst = src + i * msg->fbinfo.line_length / sizeof(uint32_t);
      unsigned int j;
      for (j = 0; j < size; j++)
      {
        dst[j] = src[j];
      }
    }
    sy -= rtx->ay;
  }
}
Esempio n. 17
0
/*******************************************************************************
 * For each pixel we must generate a primary ray and test for intersection with
 * all of the objects in the scene. If there is more than one ray-object
 * intersection then we must choose the closest intersection (the smallest
 * positive value of t).To ensure that there are no objects intersected in
 * front of the image plane (this is called near plane clipping), we keep the
 * distance of the primary ray to the screen and test all intersections against
 * this distance. If the t value is less than this distance, then we ignore the
 * object.
 *
 * If there is an intersection then we must compute the shadow rays and the
 * reflection rays. */
color_t trace_ray(ray3_t* test_ray, int depth) {
  int    occluded = 0;
  ray3_t shadow_ray;
  ray3_t reflected_ray;
  color_t ray_color = { 0.0, 0.0, 0.0, 0.0 };
  color_t nul_color = {0.0, 0.0, 0.0, 1.0};
  light_t* light_ptr = 0;
  double intersect_ray_length_curr = 0.0;
  double intersect_ray_length_close = 0.0;
  int     intersection_exists = 0;
  colored_sphere_t* sphere_close_ptr = 0;
  vector3_t intersection;
  vector3_t intersection_vector;
  int sphere_index = 0;
  int light_index = 0;
  int shadow_index;
  color_t add_color;

  /* test ray against all objects in scene, search until closest intersection
   * is found. */
  for (sphere_index = 0; sphere_index < sphere_list_count; ++sphere_index) {
    colored_sphere_t* sphere_ptr = &sphere_list[sphere_index];

    /* test for intersection between ray and scene object */
    if (1 == find_ray_sphere_intersect(test_ray, &sphere_ptr->sphere, &intersect_ray_length_curr)) {
      if (intersect_ray_length_curr < 0.0)
        continue;

      if (0 == intersection_exists) {
        intersection_exists = 1;
        intersect_ray_length_close = intersect_ray_length_curr;
        sphere_close_ptr = sphere_ptr;
      }
      else if (intersect_ray_length_curr < intersect_ray_length_close) {
        intersect_ray_length_curr = intersect_ray_length_close;
        sphere_close_ptr = sphere_ptr;
      }
    }
  }

  if (1 == intersection_exists) {
    intersection.x = test_ray->origin.x + test_ray->vector.x * intersect_ray_length_close;
    intersection.y = test_ray->origin.y + test_ray->vector.y * intersect_ray_length_close;
    intersection.z = test_ray->origin.z + test_ray->vector.z * intersect_ray_length_close;

    shadow_ray.origin = intersection;

    /* Shadow rays are sent towards all light sources to determine if any objects occlude the intersection spot. */
    for (light_index = 0; light_index < light_list_count; ++light_index) {
      occluded = 0;
      light_ptr = &light_list[light_index];
      shadow_ray.vector.x = (light_ptr->origin.x - shadow_ray.origin.x);
      shadow_ray.vector.y = (light_ptr->origin.y - shadow_ray.origin.y);
      shadow_ray.vector.z = (light_ptr->origin.z - shadow_ray.origin.z);
      normalize_vector(&shadow_ray.vector);

      /* Test intersection to determine if ray is in occlusion. */
      for (shadow_index = 0; shadow_index < sphere_list_count; ++shadow_index) {
        if (1 == find_ray_sphere_intersect(&shadow_ray, &sphere_list[shadow_index].sphere, &intersect_ray_length_curr)) {
          occluded = 1;
          break;
        }
      }

      if (occluded == 0) {
        /* Calculate the total light intensity. */
        double light_intensity = calc_dot_product(&shadow_ray.vector, &test_ray->vector);
        if (light_intensity < 0.0) light_intensity = -light_intensity;

        ray_color = mix_colors(&nul_color, &sphere_close_ptr->color, light_intensity);

        if (depth < 4) {
          reflected_ray.origin.x = intersection.x;
          reflected_ray.origin.y = intersection.y;
          reflected_ray.origin.z = intersection.z;

          intersection_vector.x = (intersection.x - sphere_close_ptr->sphere.center.x);
          intersection_vector.y = (intersection.y - sphere_close_ptr->sphere.center.y);
          intersection_vector.z = (intersection.z - sphere_close_ptr->sphere.center.z);

          normalize_vector(&intersection_vector);
          calc_reflected_vector(&reflected_ray.vector, &test_ray->vector, &intersection_vector);

          add_color = trace_ray(&reflected_ray, ++depth);
          if ((add_color.r != 0x00) ||
              (add_color.g != 0x00) ||
              (add_color.b != 0x00)) {
            double mix_ratio = calc_dot_product(&reflected_ray.vector, &intersection_vector);
            if (mix_ratio < 0.0) mix_ratio = -mix_ratio;
            ray_color = mix_colors(&ray_color, &add_color, mix_ratio);
          }
        }
      }
    }
  }

  return ray_color;
}
Esempio n. 18
0
int main(int argc, char* argv[])
{
    bool velocity, sym, escvar;
    int is, n[3], im, nm, order, nshot, ndim, two, na, nb;
    int nt, nt1, nr, ir, it, i, ia, ib;
    float t, dt, da=0., a0, amax, db=0., b0, bmax, v0;
    float x[3], p[3], d[3], o[3], **traj, *slow, **s, *a, *b;
    raytrace rt;
    sf_file shots, vel, rays, angles;

    sf_init (argc,argv);
    vel = sf_input("in");
    rays = sf_output("out");

    /* get 2-D grid parameters */
    if (!sf_histint(vel,"n1",n))     sf_error("No n1= in input");
    if (!sf_histint(vel,"n2",n+1))   sf_error("No n2= in input");
    if (!sf_histint(vel,"n3",n+2))   sf_error("No n3= in input");
    if (!sf_histfloat(vel,"d1",d))   sf_error("No d1= in input");
    if (!sf_histfloat(vel,"d2",d+1)) sf_error("No d2= in input");
    if (!sf_histfloat(vel,"d3",d+2)) sf_error("No d3= in input");
    if (!sf_histfloat(vel,"o1",o))   o[0]=0.;
    if (!sf_histfloat(vel,"o2",o+1)) o[1]=0.;
    if (!sf_histfloat(vel,"o3",o+2)) o[2]=0.;

    /* additional parameters */
    if(!sf_getbool("vel",&velocity)) velocity=true;
    /* If y, input is velocity; if n, slowness */
    if(!sf_getint("order",&order)) order=4;
    /* Interpolation order */

    if (!sf_getint("nt",&nt)) sf_error("Need nt=");
    /* Number of time steps */
    if (!sf_getfloat("dt",&dt)) sf_error("Need dt=");
    /* Sampling in time */

    if (!sf_getbool("sym",&sym)) sym=true;
    /* if y, use symplectic integrator */

    if(!sf_getbool("escvar",&escvar)) escvar=false;
    /* If y - output escape values, n - trajectories */

    /* get shot locations */
    if (NULL != sf_getstring("shotfile")) {
        /* file with shot locations */
        shots = sf_input("shotfile");
        if (!sf_histint(shots,"n1",&ndim) || 3 != ndim) 
            sf_error("Must have n1=2 in shotfile");
        if (!sf_histint(shots,"n2",&nshot)) 
            sf_error("No n2= in shotfile");
  
        s = sf_floatalloc2 (ndim,nshot);
        sf_floatread(s[0],ndim*nshot,shots);
        sf_fileclose (shots);
    } else {
        nshot = 1;
        ndim = 3;

        s = sf_floatalloc2 (ndim,nshot);

        if (!sf_getfloat("zshot",&s[0][0])) s[0][0]=o[0];
        /* shot location in depth (if shotfile is not specified) */
        if (!sf_getfloat("yshot",&s[0][1])) s[0][1]=o[1] + 0.5*(n[1]-1)*d[1];
        /* shot location inline (if shotfile is not specified) */
        if (!sf_getfloat("xshot",&s[0][2])) s[0][2]=o[2] + 0.5*(n[2]-1)*d[2];
        /* shot location crossline (if shotfile is not specified) */

        sf_warning("Shooting from z=%g, y=%g, x=%g",s[0][0],s[0][1],s[0][2]);
    }


    if (NULL != sf_getstring("anglefile")) {
        /* file with initial angles */
        angles = sf_input("anglefile");

        if (!sf_histint(angles,"n1",&nr)) sf_error("No n1= in anglefile");
        if (!sf_histint(angles,"n2",&two) || 2 != two) sf_error("Need n2=2 in anglefile");

        a = sf_floatalloc(nr);
        b = sf_floatalloc(nr);
    } else {
        angles = NULL;

        if (!sf_getint("na",&na)) sf_error("Need na=");
        /* Number of azimuths (if anglefile is not specified) */
        if (!sf_getint("nb",&nb)) sf_error("Need nb=");
        /* Number of inclinations (if anglefile is not specified) */

        if (!sf_getfloat("a0",&a0)) a0 = 0.; 
        /* First azimuth angle in degrees (if anglefile is not specified) */
        if (!sf_getfloat("amax",&amax)) amax=360.;
        /* Maximum azimuth angle in degrees (if anglefile is not specified) */

        if (!sf_getfloat("b0",&b0)) b0 = 0.; 
        /* First inclination angle in degrees (if anglefile is not specified) */
        if (!sf_getfloat("bmax",&bmax)) bmax=180.;
        /* Maximum inclination angle in degrees (if anglefile is not specified) */
        
        /* convert degrees to radians */
        a0 *= SF_PI/180.;
        amax *= SF_PI/180.;
        b0 *= SF_PI/180.;
        bmax *= SF_PI/180.;

        /* figure out angle spacing */
        da = (na > 1)? (amax - a0)/(na-1) : 0.;
        db = (nb > 1)? (bmax - b0)/(nb-1) : 0.;

        nr = na*nb;

        a = sf_floatalloc(nr);
        b = sf_floatalloc(nr);

        for (ir=ib=0; ib < nb; ib++) {
            for (ia=0; ia < na; ia++, ir++) {
                b[ir] = b0 + ib*db;
                a[ir] = a0 + ia*da;
            }
        }
    }

    /* specify output dimensions */
    nt1 = nt+1;
    if (escvar) {
        sf_putint (rays, "n1", 4);
        sf_putfloat (rays, "o1", 0.0);
        sf_putfloat (rays, "d1", 1.0);
        sf_putstring (rays, "label1", "Escape variable");
        sf_putstring (rays, "unit1", "");
        if (NULL == angles) {
            sf_putint (rays, "n2", na);
            sf_putfloat (rays, "d2", da*180.0/SF_PI);
            sf_putfloat (rays, "o2", a0*180.0/SF_PI);
            sf_putstring (rays, "label2", "Azimuth");
            sf_putstring (rays, "unit2", "Degrees");
            sf_putint (rays, "n3", nb);
            sf_putfloat (rays, "d3", db*180.0/SF_PI);
            sf_putfloat (rays, "o3", b0*180.0/SF_PI);
            sf_putstring (rays, "label3", "Inclination");
            sf_putstring (rays, "unit3", "Degrees");
            sf_putint (rays,"n4",nshot);
            sf_putfloat (rays, "d4", 1.0);
            sf_putfloat (rays, "o4", 0.0);
            sf_putstring (rays, "label4", "Shots");
            sf_putstring (rays, "unit4", "");
        } else {
            sf_putint (rays,"n2",nr);
            sf_putfloat (rays, "d2", 1.0);
            sf_putfloat (rays, "o2", 0.0);
            sf_putstring (rays, "label2", "Angles");
            sf_putstring (rays, "unit2", "");
            sf_putint (rays,"n3",nshot);
            sf_putfloat (rays, "d3", 1.0);
            sf_putfloat (rays, "o3", 0.0);
            sf_putstring (rays, "label3", "Shots");
            sf_putstring (rays, "unit3", "");
        }
    } else {
        sf_putint (rays,"n1",ndim);
        sf_putint (rays,"n2",nt1);
        sf_putint (rays,"n3",nr);
        sf_putint (rays,"n4",nshot);
    }
            
    /* get slowness squared */
    nm = n[0]*n[1]*n[2];
    slow = sf_floatalloc(nm);

    sf_floatread(slow,nm,vel);

    for(im = 0; im < nm; im++){
        v0 = slow[im];
        slow[im] = velocity? 1./(v0*v0): v0*v0;
    }

    /* initialize ray tracing object */
    rt = raytrace_init (3, sym, nt, dt, n, o, d, slow, order);
    
    free (slow);

    traj = sf_floatalloc2 (sym? ndim: 2*ndim,nt1);

    for( is = 0; is < nshot; is++) { /* loop over shots */
        /* initialize angles */
        if (NULL != angles) {
            sf_floatread(a,nr,angles);
            sf_floatread(b,nr,angles);
        } 
        
        for (ir = 0; ir < nr; ir++) { /* loop over rays */
            /* initialize position */
            x[0] = s[is][0]; 
            x[1] = s[is][1];
            x[2] = s[is][2];

            /* initialize direction */
            p[2] = +sinf(a[ir])*sinf(b[ir]);
            p[1] = -cosf(a[ir])*sinf(b[ir]);
            p[0] = cosf(b[ir]);

            it = trace_ray (rt, x, p, traj);
            if (it < 0) it = -it; /* keep side-exiting rays */

            if (escvar) {
                /* Write escape variables only */
                sf_floatwrite (traj[it],ndim,rays); /* z, x, y */
                t = it*dt; /* t */
                sf_floatwrite (&t, 1, rays);
            } else {
                for (i=0; i < nt1; i++) {
                    if (0==it || it > i) {
                        sf_floatwrite (traj[i],ndim,rays);
                    } else {
                        sf_floatwrite (traj[it],ndim,rays);
                    }
                }
            }
        }
    }

    exit (0);
}
Esempio n. 19
0
  printf("%.2lf %2.lf %.2lf\n",d1,d2,d1/d2);
  color c = color_expr(d1/d2,0,0);
  color_show(stdout,c);

  printf("\n\n *** testing logica_loc *** \n");
  xyz_show(stdout,loc1);
  xyz_show(stdout,loc2);
  xyz_show(stdout,loc3);

  printf("\n\n *** testing texture *** \n");
  color tx = tex_green(&o1, htpt);
  color_show(stdout,tx);
  xyz dirrr = xyz_sub(loc1,cam.loc);
  xyz_show(stdout,dirrr);
  ray tr = {cam.loc,dirrr};
  color trc = trace_ray(scn,tr);
  hit_test ht2 = intersect(tr,o1);
  xyz htpt22 = ht2.hit_point;
  xyz htpt2 = ray_position(tr,ht2.t);
  printf("\n\n");
  printf("===ray from cam (0,0,-5) to physical (60,51)\nray:");
  ray_show(stdout,tr);
  hit_test_show(stdout,ht2);
  printf("\n");
  xyz_show(stdout,htpt2);
  xyz_show(stdout,htpt22);
  printf("\n");
  color tx2 = tex_green(&o1, htpt2);
  color_show(stdout,tx2);
  printf("\n");
  color_show(stdout,trc);
Esempio n. 20
0
bool trace_ray(const Ray& ray, const std::list<Sphere>& world, const Sphere& sphere, Color* color) {

  const float a = dot(ray.direction, ray.direction);
  const Vec3 c2o = ray.origin - sphere.center;
  const float b = 2 * dot(c2o, ray.direction);
  const float c = dot(c2o, c2o) - sphere.radius * sphere.radius;

  const float delta = b * b - 4 * a * c;

  if (delta < 0) {
    return false;
  }

  const float delta_root = std::sqrt(delta);

  const float roots[2] = {
    (-b - delta_root) / (2 * a),
    (-b + delta_root) / (2 * a),
  };

  if (roots[0] < 0 && roots[1] < 0) {
    return false;
  } else if (!color) {
    return true;
  }

  float root;

  if (roots[0] < 0 || roots[1] < 0) {
    root = std::max(roots[0], roots[1]);
  } else {
    root = std::min(roots[0], roots[1]);
  }

  const Vec3 intersection = ray.origin + root * ray.direction;
  const Vec3 normal = intersection - sphere.center;
  const Vec3 tan1 = (normal.y != 0 || normal.z != 0) ? cross(normal, Vec3 { 1, 0, 0 }) : Vec3 { 0, 1, 0 };
  const Vec3 tan2 = cross(normal, tan1);

  const unsigned tests = 100;
  float occlusion = 0;

  #pragma omp parallel for
  for (int i = 0; i < tests; ++i) {

    const float inclination = dis(gen) / 2;
    const float azimuth = 2 * dis(gen);

    const Vec3 spherical {
      std::cos(azimuth) * std::sin(inclination),
      std::sin(azimuth) * std::sin(inclination),
      std::cos(inclination),
    };

    const Vec3 direction = spherical.x * tan1 + spherical.y * tan2 + spherical.z * normal;

    const Ray test_ray {
      intersection + 0.001f * direction,
      direction,
    };

    if (trace_ray(test_ray, world, nullptr)) {
      occlusion += 1.f / tests;
    }

  }

  color->r = color->g = color->b = 255 * (1 - occlusion) * (1 - occlusion);

  return true;

}