{ If $$\sin\theta_2$$ is greater than 1, then we have a case of total reflection. Indeed material do not refract light of … Figure 7: when light rays pass from one "transparent" medium to another, they change direction. { This phenomenon is illustrated in figure 7. else Note that this value can easily be computed using Snell's law: float sint = etai / etat * sqrtf(std::max(0.f, 1 - cosi * cosi)); Vec3f refract(const Vec3f &I, const Vec3f &N, const float &ior) kr = 1; ... { Shadow casting of transparent objects will be studied in a separate lesson. This phenomenon is called total internal reflection. It can create some really strange effects such as the illusion of a broken pen shown in figure 8. The issue with the fresnel check in vray is that it does not account for the face forward reflection. Figure 11: compute the refraction ray direction using geometry. In the case of reflection we need to push the point on the same side of the surface hit by the incident ray, and in the case of refraction, the points need to be pushed inward (figure 17). The shaded point $$P$$ either takes on the color of the background if the reflection ray didn't intersect any geometry or the color of the object that the reflection ray intersected otherwise. Keep in mind that the result of $$\cos(\theta_1$$) also needs to be positive. In this category you find things such as glass or plastic as well as water. break; if (kr < 1) { We will just stick for now to the equation that can be used to compute the refracted ray direction. Conductors as you may have guessed are metals. Think about the confusions and misunderstandings you face when working in a large team and using emails and Dropbox, explaining each step to each person every time you have an update, and having to upload and send download links every time someone needs a file. This is something that we find natural when we look at object from a different angle, but that we find maybe less natural when we change our position with respect to a mirror reflecting that same object, though the reason why this is happening is essentially the same. First in some cases the ray will hit the surface from outside. We then call the castRay() function recursively (the function calls itself) and assign to the primary ray color the color of the reflected ray. As stated before air has a refraction index close to 1, and for this reason, in CG, we generally ignore it. In its center though, the sphere only reflects about 6% of the incident light. float eta = etai / etat; mesh3->ior = 1.3; ... You can see that $$M$$ can be computed as follows: The first part of the equation is simple. Vec3f reflectionDirection = reflect(dir, hitNormal).normalize(); Vec3f refractionColor = 0; As you can see in figure 2, the vectors I and R can be expressed in terms of the vector A and B: The vector $$B$$ can easily be computed. While subtle, the fresnel effect on the edges of the water volume is also visible. If the object that the primary ray hit is a mirror like surface, then we compute the reflection direction using the incident view direction (the primary ray direction) and the normal of the surface at the intersection point. One final detail needs to be accounted for. When we cast a reflection ray from the primary ray, we say that the ray has a depth of 1. This is due to fresnel. float etai = 1, etat = ior; hitColor += reflectionColor * kr + refractionColor * (1 - kr); And since by the principle of the conservation of energy, the amount of reflected light plus the amount of refracted light is necessary equal to the total amount of incident light, you can deduce that the amount of reflected light increases when the angle of incidence increases, up to 100% as the angle gets closer to 90 degrees. When the angle of incident is greater than some value called the critical angle, then 100% of the light incident on the surface is reflected. Though one thing you may want to know before we close this chapter, is that metallic objects too reflect light. We look at a different part of the object. The higher the recursion the longer it will take to render a frame. { This can be done again by testing the sign of the cosine of the angle between the surface normal and the incident ray direction (the sign of $$\cos\theta_1$$). This is the case for example of metals. For example that reflections is a wavelength effect. }, switch (isect.hitObject->type) { It is the dot product between $$N$$ and $$I$$. float cosi = clamp(-1, 1, dotProduct(I, N)); // we are outside the surface, we want cos(theta) to be positive case kReflectionAndRefraction: This may not be entirely correct but I know what I mean. First, you can see that the vector $$T$$ the transmission ray that we want to build, is the sum of the vector $$A$$ and $$B$$. float Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost)); There is no refraction in this case Look through a window while standing right in front of it and notice how little or no reflections are visible. { As in the example of the real glass ball from figure 9, you can see that the image of the background geometry is inverted in the sphere. Don't worry too much if you don't know about this detail. } } Copyright © 2020 Chaos Software Ltd. All Rights Reserved. To the contrary of nature, you have a control on many different aspects of the simulation and by changing various settings (whether you similar internal reflections or not, the maximum ray depth, etc.) const std::vector<std::unique_ptr<Light>> &lights, If you fix the view direction and change the direction of the incident ray in the middle even just slightly, then the observer will stop seeing the reflection of that ray. Perpendicular – Specifies the color for the texture when viewed frontally. Note that the result we get is very similar to the same scene rendered with a commercial renderer (Mental Ray in this case). But when it travels through another medium, its speed decreases. Blend Amount–  Takes each pixel from the top layer if present. Though for most scenes using a depth much greater than 4 or 5 generally doesn't make much of visual difference. We can just set $$F_R$$ to 1. Then move aside and try looking through it from a very low angle, you’ll realize that the window has become almost purely reflective and you can’t see through it anymore. cosi = fabsf(cosi); This ratio is actually given by the Fresnel equations which we will study next. } You can see that the length of $$I + C$$ is exactly equal to $$\sin(\theta_1)$$. As mentioned before, due to conservation of energy, the ratio of refracted light can simply be computed as: Keep in mind that if light goes from a medium to another medium with a lower refraction index, it may be subject to the phenomenon of total internal reflection. Mirrors exhibit specular reflection. Although how does it work in 3D space? The difference between the two images come from the fact that in the reference image we set the max depth to 10 while in the image on right (our render), we set the max depth limit to 4. We will study these details later. std::swap(etai, etat); Dielectric are essentially non conducting materials or electric insulators for example. For this reason we need to push the reflection ray origin above the surface and the refracted ray origin below the surface by adding some artificial bias along the normal direction. Well this vector can also be easily found by construction. This is not totally wrong, as mirror like surfaces generally never reflect 100% of the incident light anyway. // we are inside the surface, cos(theta) is already positive but reverse normal direction Imagine how much time and money you will save by not always having to update everything you do on your website!