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; }