std::pair< T, T > intersection( const ray<T,2u>& ray, const circle<T>& circle )
    { 
      // check for no intersection
    
      const T a = dot( ray.direction(), ray.direction() );
      const T b = T(2.) * sum( ray.direction() * ( ray.source() - circle.center() ) );
      const T c =   dot( circle.center(), circle.center() ) 
                  + dot( ray.source(), ray.source() ) 
                  - T(2.) * dot( ray.source(), circle.center() )
                  - sqr( circle.radius() );

      return solve_quadratic_equation(a,b,c);
    }
Example #2
0
bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const
{
    vec3 oc = r.origin() - center;
    
    float v2 = dot(r.direction(), r.direction());
    float voc = dot(oc, r.direction());

    // 判別式.
    float discriminant = voc * voc - v2 * (dot(oc, oc) - radius*radius);

    if (discriminant > 0) {
        // 手前.
        float temp = (-voc - sqrt(discriminant)) / v2;

        if (temp < t_max && temp > t_min) {
            rec.t = temp;
            rec.p = r.org + rec.t * r.dir;
            
            rec.normal = (rec.p - center);
            rec.normal.noramlize();

            getUV(rec.u, rec.v, rec.normal);

            rec.mat_ptr = mat_ptr;
            return true;
        }

        // 奥.
        temp = (-voc + sqrt(discriminant)) / v2;

        if (temp < t_max && temp > t_min) {
            rec.t = temp;
            rec.p = r.org + rec.t * r.dir;
            
            rec.normal = (rec.p - center) / radius;
            rec.normal.noramlize();

            getUV(rec.u, rec.v, rec.normal);

            rec.mat_ptr = mat_ptr;
            return true;
        }
    }

    return false;
}
Example #3
0
bool yz_rect::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
	double t = (k - r.origin().x()) / r.direction().x();

	if (t<t_min || t>t_max) return false;

	double y = r.origin().y() + t*r.direction().y();
	double z = r.origin().z() + t*r.direction().z();

	if (y<y0 || y>y1 || z<z0 || z>z1) return false;

	rec.u = (y - y0) / (y1 - y0);
	rec.v = (z - z0) / (z1 - z0);
	rec.t = t;
	rec.mat_ptr = mat_ptr;
	rec.point = r.point_at_parameter(t);
	rec.normal = vec3(1.0, 0.0, 0.0);
	return true;
}
Example #4
0
vec3 color(const ray& r, surface* world, int depth) {
    hit_record rec;
    
    if (world->hit(r, 0.001, DBL_MAX, rec)) {
        ray scattered;
        vec3 attenuation;
        
        if (depth < MAXDEPTH &&
            rec.mat_ptr->scatter(r, rec, attenuation, scattered)) {
            return attenuation*color(scattered, world, depth+1);
        } else {
            return vec3(0, 0, 0);
        }
    } else {
        vec3 unit_direction = unit_vector(r.direction());
        double t = 0.5*(unit_direction.y() + 1.0);
        return (1.0 - t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);
    }
}
Example #5
0
static hdr_color
do_shade(scene const& scene, ray const& ray, shading_policy const& policy,
         unsigned depth, double importance, sampler_prng_engine& prng)
{
  if (!should_continue(depth, importance, policy))
    return policy.background;

  boost::optional<scene::intersection> i = scene.intersect_solid(ray);
  if (!i)
    return policy.background;

  hdr_color result = i->texture();
  for (light const& l : scene.lights()) {
    vector3 const light_dir{l.get_source() - i->position()};

    if (auto obstacle = scene.intersect_solid({i->position(), light_dir}))
      if ((obstacle->position() - i->position()).squaredNorm() <
          (l.get_source() - i->position()).squaredNorm())
        continue;  // Obstacle blocks direct path from light to solid

    result = blend_light(
      i->solid().material(), result, i->normal(), l.color(), light_dir
    );
  }

  unit3 const perfect_reflection_dir = reflect(ray.direction(), i->normal());
  unit3 const reflection_dir = cos_lobe_perturb(
    perfect_reflection_dir,
    i->solid().material().specular_exponent(),
    prng
  );
  oxatrace::ray const reflected{i->position(), reflection_dir};
  double const reflection_importance = i->solid().material().reflectance();
  hdr_color const reflection = do_shade(
    scene, reflected, policy, depth + 1, reflection_importance * importance,
    prng
  );
  result = blend_reflection(i->solid().material(), result, reflection);

  return result;
}
Example #6
0
vec3 color(const ray& r, hitable *world, int depth)
{
    hit_record rec;

    if (world->hit(r,0.001f, 10000, rec)) { 
        ray scattered;
        vec3 attenuation;

        if (depth < 10 && rec.mat_ptr->scatter(r, rec, attenuation, scattered)) {
             return attenuation * color(scattered, world, depth + 1);
        }
        else {
            // ‰e.
            return vec3(0,0,0);
        }
    }
    else {
        // ‹ó.
        vec3 unit_direction = unit_vector(r.direction());
        float t = 0.5 * (unit_direction.y() + 1.0);

        return (1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
    }
}
Example #7
0
			            ray(const ray<T,Dim>& r)
			            : m_src( r.source() ), m_dir( r.direction() )  {	}