Esempio n. 1
0
static t_col		shoot_ray(t_ray ray, int level_max, t_env *env)
{
	float		coef;
	float		t;

	coef = 1.0;
	while (coef > 0.0f && level_max--)
	{
		t = 20000.0f;
		get_intersections(env, ray, &t);
		if (OBJ.cur_sphere != -1)
			set_val_sphere(env, t, ray);
		else if (OBJ.cur_tri != -1)
			set_val_tri(env, t, ray);
		else if (OBJ.cur_cyl != -1)
			set_val_cyl(env, t, ray);
		else if (OBJ.cur_cone != -1)
			set_val_cone(env, t, ray);
		else
			break ;
		if (env->br == 1)
			break ;
		calc_lighting(env, coef);
		coef *= OBJ.cur_mat.reflection;
		reflect_ray(env, &ray);
	}
	return (OBJ.col);
}
Esempio n. 2
0
Vector Raytracer::shade(Ray const &ray,
                        int &rayDepth,
                        Intersection const &intersection,
                        Material const &material,
                        Scene const &scene)
{
    // - iterate over all lights, calculating ambient/diffuse/specular contribution
    // - use shadow rays to determine shadows
    // - integrate the contributions of each light
    // - include emission of the surface material
    // - call Raytracer::trace for reflection/refraction colors
    // Don't reflect/refract if maximum ray recursion depth has been reached!
    //!!! USEFUL NOTES: attenuate factor = 1.0 / (a0 + a1 * d + a2 * d * d)..., ambient light doesn't attenuate, nor does it affected by shadow
    //!!! USEFUL NOTES: don't accept shadow intersection far away than the light position
    //!!! USEFUL NOTES: for each kind of ray, i.e. shadow ray, reflected ray, and primary ray, the accepted furthest depth are different
    Vector diffuse(0);
    Vector ambient(0);
    Vector specular(0);
    
    Vector v = -ray.direction.normalized();
    Vector n = intersection.normal.normalized();
    Vector reflect = (-v + 2 * v.dot(n) * n).normalized();
    
    for (auto lightIter = scene.lights.begin(); lightIter != scene.lights.end(); lightIter++)
    {
        // @@@@@@ YOUR CODE HERE
        // calculate local illumination here, remember to add all the lights together
        // also test shadow here, if a point is in shadow, multiply its diffuse and specular color by (1 - material.shadow)
        Vector l = (lightIter->position - intersection.position).normalized();
        Vector r = (-l + 2 * n.dot(l)*n).normalized();
        Vector view = (scene.camera.position - intersection.position).normalized();
        
        double d = //(intersection.position - ray.origin).length()+
        (lightIter->position - intersection.position).length();
        double attenuation = 1.0 / (lightIter->ambient[0] + d*lightIter->attenuation[1]
                                    +d *d*lightIter->attenuation[2]);
        
        Ray shadowRay = Ray(intersection.position + (lightIter->position - intersection.position).normalized()* 1e-6,(lightIter->position - intersection.position).normalized());
        Intersection hit = intersection;
        bool isShadow = false;
        
        Vector delAmbient = material.ambient * lightIter->ambient;
        Vector delDiffuse = material.diffuse * lightIter->diffuse * max(0.0, n.dot(l))
        * attenuation;
        Vector delSpecular = material.specular * lightIter->specular *
        pow(max(0.0, r.dot(view)), material.shininess) * attenuation;
        
        
        
        for (int x = 0; x< scene.objects.size(); x++) {
            if (scene.objects[x]->intersect(shadowRay, hit)) {
                isShadow = true;
            }
        }
        
        
        if (isShadow) {
            ambient += delAmbient;
            diffuse += delDiffuse * (1 - material.shadow);
            specular += delSpecular * (1 - material.shadow);
        }
        else {
            ambient += delAmbient;
            diffuse += delDiffuse;
            specular += delSpecular;
        }
    }
    
    Vector reflectedLight(0);
    if ((!(ABS_FLOAT(material.reflect) < 1e-6)) && (rayDepth < MAX_RAY_RECURSION))
    {
        // @@@@@@ YOUR CODE HERE
        // calculate reflected color using trace() recursively
        Ray reflect_ray(intersection.position + reflect*1e-6, reflect);
        double depth = DBL_MAX;
        trace(reflect_ray, rayDepth, scene, reflectedLight, depth);
        
    }
    
    return material.emission + ambient + diffuse + specular + material.reflect * reflectedLight;
}
Esempio n. 3
0
// 屈折面
Color PathTracer::Radiance_Refraction(const Scene &scene, const Ray &ray, Random &rnd, const int depth, Scene::IntersectionInformation &intersect, const Vector3 &normal, double russian_roulette_prob) {
  bool into = intersect.hit.normal.dot(normal) > 0.0;

  Vector3 reflect_dir = ray.dir - normal*2*ray.dir.dot(normal);
  reflect_dir.normalize();
  double n_vacuum = REFRACTIVE_INDEX_VACUUM;
  double n_obj = intersect.object->material.refraction_rate;
  double n_ratio = into ? n_vacuum/n_obj : n_obj/n_vacuum;

  double dot = ray.dir.dot(normal);
  double cos2t = 1-n_ratio*n_ratio*(1-dot*dot);

  // 反射方向の直接光の評価
  Color reflect_direct;
  Ray reflect_ray(intersect.hit.position, reflect_dir);
  Scene::IntersectionInformation reflected_hit;
  if (m_performNextEventEstimation && scene.CheckIntersection(reflect_ray, reflected_hit)) {
    reflect_direct = reflected_hit.object->material.emission;
  }

  if (cos2t < 0) {
    // 全反射
    Color income = reflect_direct + Radiance(scene, Ray(intersect.hit.position, reflect_dir), rnd, depth+1);
    Color weight = intersect.object->material.color / russian_roulette_prob;
    return Vector3(weight.x*income.x, weight.y*income.y, weight.z*income.z);
  }

  // 屈折方向
  Vector3 refract_dir( ray.dir*n_ratio - intersect.hit.normal * (into ? 1.0 : -1.0) * (dot*n_ratio + sqrt(cos2t)) );
  refract_dir.normalize();
  const Ray refract_ray(intersect.hit.position, refract_dir);
  // 屈折方向の直接光の評価
  Color refract_direct;
  if (m_performNextEventEstimation && scene.CheckIntersection(refract_ray, reflected_hit)) {
    refract_direct = reflected_hit.object->material.emission;
  }

  // Fresnel の式
  double F0 = (n_obj-n_vacuum)*(n_obj-n_vacuum)/((n_obj+n_vacuum)*(n_obj+n_vacuum));
  double c = 1 - ( into ? -dot : -refract_dir.dot(normal) );  // 1-cosθ
  double Fr = F0 + (1-F0)*pow(c, 5.0);    // Fresnel (反射の割合)
  double n_ratio2 = n_ratio*n_ratio;  // 屈折前後での放射輝度の変化率
  double Tr = (1-Fr)*n_ratio2;        // 屈折直後→直前の割合

  Color income, weight;

  if (depth > 2) {
    // 反射 or 屈折のみ追跡
    const double reflect_prob = 0.1 + 0.8 * Fr;
    if (rnd.nextDouble() < reflect_prob) {
      // 反射
      income = (reflect_direct + Radiance(scene, Ray(intersect.hit.position, reflect_dir), rnd, depth+1)) * Fr;
      weight = intersect.texturedHitpointColor / (russian_roulette_prob * reflect_prob);
    } else {
      // 屈折
      income = (refract_direct + Radiance(scene, refract_ray, rnd, depth+1)) * Tr;
      weight = intersect.texturedHitpointColor / (russian_roulette_prob * (1 - reflect_prob));
    }
  } else {
    // 反射と屈折両方追跡
    m_omittedRayCount++;
    income =
      (reflect_direct + Radiance(scene, Ray(intersect.hit.position, reflect_dir), rnd, depth+1)) * Fr +
      (refract_direct + Radiance(scene, refract_ray, rnd, depth + 1)) *Tr;
    weight = intersect.texturedHitpointColor / russian_roulette_prob;
  }

  return /*intersect.object->material.emission +*/ Vector3(weight.x*income.x, weight.y*income.y, weight.z*income.z);
}