Vec4d Raytracer::shade(const RayIntersection& intersection, size_t depth) const { // This offset must be added to intersection points for further // traced rays to avoid noise in the image const Vec3d offset(intersection.normal() * Math::safetyEps()); Vec4d color(0,0,0,1); std::shared_ptr<const Renderable> renderable = intersection.renderable(); std::shared_ptr<const Material> material = renderable->material(); for(size_t i=0;i <mScene->lights().size();++i) { const Light &light = *(mScene->lights()[i].get()); //Shadow ray from light to hit point. const Vec3d L = (intersection.position() + offset) - light.position(); const Ray shadowRay(light.position(), L); //Shade only if light in visible from intersection point. if (!mScene->anyIntersection(shadowRay,L.length())) color += material->shade(intersection,light); } // limit recursion depth if (depth >= mMaxDepth) return color; Vec3d dir = reflect(intersection.ray().direction(), intersection.normal()); Ray reflectedRay(intersection.position() + offset, dir); double reflectance = material->reflectance(); color = color * (1 - reflectance) + reflectance * trace(reflectedRay, depth - 1) + Vec4d(0.0,0.0,0.0,1.0); return color; }
// use phong shading model Vec4d PhongMaterial::shade( const RayIntersection& intersection, const Light& light) const { // calculate diffuse part of the equation Vec3d lightDirection = (light.position() - intersection.position()).normalize(); Vec3d diffuse = this->color() * std::max(dot(intersection.normal(), lightDirection), 0.d); // calculate specular part Vec3d viewDirection = intersection.ray().direction(); Vec3d reflection = reflect(lightDirection, intersection.normal()); Vec3d lightcolor = light.spectralIntensity() / 255; Vec3d specular = ((mShininess + 2) / (2 * M_PI)) * SPECULAR_REFLECTION_DEGREE * pow(std::max(dot(reflection, viewDirection), 0.d), mShininess) * lightcolor; // calculcate sum -> result return Vec4d(diffuse + specular, 1); }