Example #1
0
Vector3D Ray::LightTrace(Vector3D position, Vector3D normal, Environment &env, int recursion) {
	if(recursion > MAX_RECURSION) return BACKGROUND_COLOR;
	std::vector<Light*>::iterator it;

	Vector3D color;
	for(it = env.lights.begin(); it != env.lights.end(); ++it) {
		Ray light_ray(position, ((*it)->Position() - position).Normalize());
		float shade = normal * light_ray.direction;
		if(shade < 0) continue;

		Intersection inter = light_ray.FindClosestIntersection(env);
		if(inter.obj == NULL) {
			color = color + shade * (*it)->GetColorAt(position);
		} else {
			continue; // shade = 0
		}
	}
	return color;
}
    Color LambertianShader::shade(const geometry::DifferentialGeometry &dg, int bounce) {
      // initialize the return color for the shader to black
      Color shadeColor(0,0,0,1);

      /************************************************************************/

      // no light falloff based on distance (defaulted to no falloff)
      float distanceVal_no_falloff = 1.0f;

      // linear light falloff based on distance
//     float distanceVal_linear = (light_vec.length());

      // quadratic light falloff based on distance
//      float distanceVal_quadratic = (light_vec.length() * light_vec.length());

      // ambient lighting - faking global illumination with constant
      // low color value
      shadeColor.red = mImpl->color.red * 0.1f;
      shadeColor.green = mImpl->color.green * 0.1f;
      shadeColor.blue = mImpl->color.blue * 0.1f;

      std::vector<std::shared_ptr<Light > > lights;
      lights = Scene::getInstance().lights();
      /************************************************************************/
      for (int i=0; i<lights.size(); i++) {
	      float intensity = lights[i]->intensity();
	      math::Vector light_vec = lights[i]->getLightVector(dg);
	      Ray light_ray(dg.p, light_vec.normalized());

	      // This implementation uses the singleton of the scene to see if we
	      // hit any objects.  Note that we do not need to pass in the Scene as
	      // an argument since a singleton is in the global namespace,
	      // essentially, a global class where there is only one instance)
	      if (!Scene::getInstance().hit(light_ray)) { // if no objects in the way, do lighting
		// this computes the cosine of the angle between the light vector
		// and the geometry normal

      		float shadeAngle = light_vec.normalized().dot(dg.nn);
		  // if the angle is greater than 0, do the lambertian shading
		      if (shadeAngle > 0) {
		    // add the diffuse (matte) lighting to the ambient lighting based on
		    // the intensity and the falloff factor based on the distance
		        float factor = shadeAngle*intensity/distanceVal_no_falloff;
		        shadeColor.red += mImpl->color.red*factor;
	          shadeColor.green += mImpl->color.green*factor;
            shadeColor.blue += mImpl->color.blue*factor;
		      }
         }
    }

    if (dg.shape->reflectivity() > 0 && bounce < mImpl->max_num_reflects) {
      math::Vector normal = math::Vector(dg.nn.x(), dg.nn.y(), dg.nn.z());
      float cl = -dg.V.dir().dot(normal);
      Ray reflect_ray = Ray(dg.p, dg.V.dir()+(2*normal* cl));
      std::shared_ptr<DifferentialGeometry> dg1;
      std::shared_ptr<Primitive> prim;
      float rHit;
      if (Scene::getInstance().hit(reflect_ray, rHit, dg1, prim)) {
        Color temp = prim->shade(dg1, bounce+1);
        shadeColor.red+=(temp.red*dg.shape->reflectivity());
        shadeColor.green+=(temp.green*dg.shape->reflectivity());
        shadeColor.blue+=(temp.blue*dg.shape->reflectivity());
      }
    }
    return shadeColor;
  }