Implement transparency effects by sending rays recursively in the refracted direction. If the material is transparent (getTransparentColor() > (0,0,0)), trace a new ray in the transmitted direction. We suggest you implement a function transmittedDirection that given an incident vector, a normal and the indices of refraction, returns the transmitted direction.
bool transmittedDirection(const Vec3f &normal, const Vec3f &incoming, float index_i, float index_t, Vec3f &transmitted);
We make the simplifying assumption that our transparent objects exist in a vacuum, with no intersecting or nested refracting materials. This allows us to determine the incident and transmitted index of refraction simply by looking at the dot product between the normal and the incoming ray. You may assume that the camera is always placed outside of transparent objects.
However, be careful about the direction of the vectors and the ratio of refraction indices. Because we now consider transparent objects, we might hit the surface of a primitive from either side, depending on whether we were inside or outside the object. The -shade_back command line option should be used when there are transparent objects in the scene.
The dot product of the normal and ray direction is negative when we are outside the object, and positive when we are inside. You will use this to detect whether the new index of refraction is 1 or the index of the hit object. Also, the index of refraction for the material surrounding the ray origin is passed as an argument to traceRay.
For the Fresnel term, we advise that you use Schlick's approximation (see lecture slides).