Sunday, September 6, 2015

An Intuitive Guide to Fresnel



Let me preface this with a couple of things, this is not aimed at physicists or mathmaticians, but rather at graphics software developers looking to get an intuitive understanding of the Fresnel effect. I'm not an expert on the Fresnel equations and so most of this is just my own findings and hunt to understand what Fresnel shaders are really trying to model, so don't take any of what I say below as expert opinion in anyway.

 I'm assuming that most developers reading this are already aware of the Fresnel effect and have likely implemented it in the form of Schlick's approximation or have heard of it, and are just trying to understand what the formula represents. If you're not as familiar on the Fresnel shading, here's some really great sources to get you started:
http://kylehalladay.com/blog/tutorial/2014/02/18/Fresnel-Shaders-From-The-Ground-Up.html
http://filmicgames.com/archives/557


However even after digging through those, I still couldn't get an intuitive understanding of what the hell Schlick's approximation was actually trying to represent. Why does index of refraction determine the reflectiveness of a surface? Why in the world do grazing angles make surfaces more reflective??

Lets see if we can break down Schlick's approximation and understand what he was trying to model. Note that Schlick's Approximation is an approximation, if I wanted to really break it down I would look at the Fresnel equations but Schlick's approximation is much simpler and will be sufficient for what I want to talk about. Don't worry, we will try to avoid jumping into too much math in favor of a more intuitive understanding.


So here is Schlicks approximation:

R₀ = ((n₁ - n₂) / (n₁ + n₂))²

R(θ) = R₀ + (1 - R₀)(1 - cos(N•V))⁵


First lets talk about R₀. We can think of R₀ as the base value of how reflective a material is. What you'll find is regardless of N, L, or θ is, R(θ) will always return a value >= R₀. What you'll find is that for most values, R(θ) will return a value close to R₀.


I'm going to make a few assumptions to simplify things, first let always assume that n₁ is air, and n₁=1 (actually it's 1.00029 but that's okay). Also lets assume n₂ is going to be materials we generally see in real life and so generally n₂ >= 1 (for those interested in some example indexes of refractions check here: http://hyperphysics.phy-astr.gsu.edu/hbase/tables/indrf.html). So our simplified R₀ calculation is:

R₀ = ((1 - n₂) / (1 + n₂))²

When graphing this you get something like:





So a couple of interesting observations we can make:



  • At IOR = 1, there is no reflectivity. That makes sense as you a ray traversing from one section of air to another section of air shouldn't cause any kind of reflection. 
  • At IOR >= 1 (the range we are considering), the amount of reflection goes up with the IOR. We need to break down the definition of IOR to get to the bottom of this one, lets take a look at the wiki definition: https://en.wikipedia.org/wiki/Refractive_index#Definition. So the index of refraction = c / v, where c is the speed of light and v is the speed at which light can travel through the given material. This tells us that materials with a high IOR are materials where light moves more slowly through and material with a low IOR are materials where light moves quickly through. It is helpful to think of IOR as a kind of density, physics folks will get upset by this because you can have a high IOR for low density materials due to polarity/magnetism/etc., but for the sake of imagining IOR, I like to think of it as "the amount of resistance light deals with going through a surface". This makes it much easier to rationalize why reflectivity is based on IOR, surfaces with a low IOR or low "resistance to light" are much more likely to absorb light where as high IOR surface or high "resistance to light" are much more likely to "reject" or reflect light. 
Now lets talk about the interesting part:

R(θ) = R₀ + (1 - R₀)(1 - cos(N•V))⁵

And actually the first part R₀ + (1 - R₀) is just a lerp based on R₀. The ⁵ is Schlick playing with the curve to get it close to what the Fresnel equations, this is interesting as well but out of the scope of what I want to talk about. What's really interesting about this is the remaining:

(1 - cos(N•V))

What this says is that when N and V are close (you are facing the surface dead on), the value is 0. When N and V are perpendicular (glancing angle), the value is 1. I thought about it and I simply couldn't accept why this made any sense, so I did some digging. There's a whole lot of justification about how this all makes sense due to the Maxwell equations but the only thing that spoke to me on an intuitive level was this: http://physics.stackexchange.com/questions/12035/why-does-light-reflect-more-intensely-when-it-hits-a-surface-at-a-large-angle. The easiest way to imagine it is that at glancing angles, it takes much less energy to redirect the light than it does to redirect light when hitting a surface dead on.






The analogy given on the stack exchange link mentions the idea of a bullet, you can imagine that the bullets momentum will be slowed down quite a bit when hitting a wall straight on, but may still keep a lot of the momentum when grazing off a wall. In the case of light, it's not really momentum but more related to electromagnetism, but I find that even this analogy is enough for me to be able to swallow what's going on due to Schlick's approximation.

If you have any feedback, please let me feel free to comment (particularly you light/physics experts, I'd love to hear your details and especially corrections on whether my explanations are really true to the physics of what's going on).


















No comments:

Post a Comment