Thursday, April 9, 2015

A little history : from Phong to BRDF

In this post i will start from the well known Phong reflection model and explain why we are now (mostly) moving to physically based rendering.

Phong reflection model

This shading model was proposed by Bui Tuong Phong, who published it in his 1973 Ph.D at the University of Utah.


Where : 

Ambient = AmbiantColor * Albedo
Diffuse = clamp(N.L, 0, 1) * Albedo
Spec = clamp(V.R,0,1)^shininess



It's a very very efficient model and yet a good approximation. There is genius behind it !

Blinn-Phong

Few years latter in 1977 we get Blinn-Phong. 
It's really close to the Phong model but for the specular : 



Where:
Spec = clamp(N.H,0,1)^shininess

It is more accurate at steep angle & faster. Neat !

Furthermore it was implemented in hardware up to DX 9c. 
This model was thus very efficient and heavily used by the time :)

Diffuse VS Specular

So Phong and Blinn-Phong are both doing a clear separation between Ambient, Diffuse and Specular. Let's explain that a little :

Ambient : is the light that bounce around so much that you loss any directional information.
Diffuse :  is the light that come from the light source and get reflected in all direction.
Specular :  is the light that come from the light source and get reflected "more" in the direction of the reflection vector.


From "perfect" specular to diffuse.


That separation may seems a little bold ? However it's not a bad approximation to be better convinced let's take a look at John Hable work: 


And


Impressive isn't it ?

Morality:
  • Specular is much more present than we think
  • Specular might be colored
  • Blinn-Phong is a lie (ok it was more than expected)


Light is uber-complex


So obviously light is much more complex :) Here are some example :

Scattering

When light travel inside a solid and lit it "from the inside".
Can be seen on wax, human skin, clouds in the sky, ice etc etc ! 



Caustics

When light is reflected/refracted via a curved surface, creating cool "drawing" of concentrated light.
Can be seen on glass construct, ice, basically anything curved and semi-transparent.

Bounce

When light bounce around its color is altered (some wavelength get absorbed) based on the materials it bounce on. Here is the ultra-famous cornel-box were the effect can be seen. 

Take a look at the right face of the right box for example.


And there are a lot more ! Especially if you consider the complexity of human perception/eyes on top of the complexity of light.

So :
Do we want scattering ? Yes sometime (usually faked) !
Do we want caustics ? No. It's way too expensive!
Do we want bounces ? Yes (but that's another story)
Do we want more cool stuff ? Depend on cost.

Improving over Blinn-Phong specular model

So we cannot even hope to simulate light correctly at runtime, but we still want something cool ! At this point we need to choose were we want to spend our computation power.

Caustics and Scattering are a far fetch, post effect are of subject so for the purpose of this blog post we will answers that we want a good reflection model first. 

So what is a good reflection model ? 
It's one that work for you ! 

If you want to go cartoon shading why not ! If you want to go realistic it's good too ! However in a lot of case you will probably want to have a good specular reflection. As we have seen it's very important to define the shape and details of your objects. 

PS : Actually the raise of more complex BRDF is linked to the evolution of the hardware too : GPU are more and more and more powerfull, while memory is not following at the same speed. In other words the ratio of available math/per parameters have raised.

Fresnel

The first step to improve the specular is to take fresnel into account. What is that ? Please follow the link ! Another awesome post from John Hable !

Everything has fresnel

By now you should be convinced about the need to add some fresnel to our lighting. 

First option : Add some factor/power of N.V, for example: 

Shading += (1-(N.V)^FresnelHack) * Color
  • This have a few advantages :
    • Better than nothing it tweaked correctly
    • May be used to hack your BRDF for funky material (velvet for example)
  • This have a few draw back:
    • Specular will need to be tweaked down to compensate 
    • It scrap your lighting as crazing angle become emissive
    • This is actually not fresnel at all even if sometime it may be called so (see below)

Second option : use Fresnel-Schlick approximation 

Fresnel = F0 + (1- F0) * (1-V.H)^5
were F0 is the reflectance of the material when looking perpendicular at it.
Specular *= Fresnel
  • This have a few advantages :
    • F0 is a well known value from the real world and can be measured !
    • Will work no matter what the lighting is (no emissive stuff).
  • This have a few draw back:
    • You may end up adding a hacky N.V term anyway because of "velvet like" materials...

Second option is thus much more interresting, furthermore it's energy conservative ...

Energy conservation ?

When light bounce on a material it can be either absorbed or reflected. Right ?

Thus for a given point on a surface the amount of reflected light should be inferior or equal to the amount of received light. Right ?

To go further in that direction let's first introduce the "BRDF" 

BRDF function
For “Bidirectional Reflectance Distribution Function”

It's function taking the incoming and outgoing vectors (each described by two angles) that allow to compute the lighting on a pixel.

Its the “reflected light VS incoming light function”



For an energy conservative BRDF the sum of all reflected light on the hemisphere is thus inferior or equal to the incoming light (L).

Is Blinn-Phong energy conservative ? The short answers is no 
  • Diffuse and Specular are additive and we get no garanty that there sum is below L.
  • Diffuse and Specular are not even energy conservative individually !

Can we transform Blinn-Phong to be Energy conservative ? yes !
  • For Diffuse it's actually a matter dividing the albedo by Pi ! Easy enough !
  • For Specular what we gonna do is to normalize it. It other word no matter the specular power it will always return the amount of light defined by the specular color ! Usefull !
  • The final step is to ensure albedo and specular color dont sum to more than one !


I promised not to get into the math, but if you want them you can read this very good post by Rory Driscoll : Energy conservation in games



Some pictures: 

Top row is a Blinn-Phong specular (and diffuse)
Bottom row is a normalized Blinn-Phong specular (and diffuse)
Energy conservative Specular and Diffuse
where (albedo + specular color <=1)

Ok but what about the fresnel tweak we have done before ? 
Its fine as it can only reduce the amount of specular ! ouf :)



Physically Based Rendering

Let’s recap important concepts  :
  • Diffuse 
    • Its the light that go to the object and bounce in any direction
  • Specular
    • Its the light that go to the object and bounce "more" toward the reflection vector
  • Fresnel
    • It adjust the specular to take crazing angle into account.
  • Energy conservation
    • It ensure a material does not emit more light than it receive.
  • BRDF (bidirectional)
    • Its the actual function that is responsible for all of that.

PBR is all about finding a consistent (ie math/physically based) way of simulating light ! 

Micro-facet theory

The basis of physically based rendering is to see the surface as a lot of little face, called micro-facets.


These micro-facets are so many and so tiny that we will not defined them one by one using textures. Instead we will define them using two probability functions called D and G.

For sure these probability function will themselves being define using parameters fetched from textures.

Here is the general equation : F(Fresnel) * G * D / (4 * N.L * N.V )

  • D is the distribution term or "How the microfacet normal are distributed around a given direction” it can be seen as mirrorness.
Distribution term

  • G is the geometry/visibility term (can be name both) or “How much the microfacet is blocked by other microfacets” it can be seen as the roughness.

There are many BRDF build around the microfacet theory ! For example :

GGX, Ashikmin-Shirley, Beckman, Cook-Torrance, Blinn-Phong...


PBR Blinn-Phong


What ? Blinn-Phong ? Actually yes ! If we take the building blocks we have seen above our Blinn-Phong is really not far from being physically based and can be made to match the microfacet theory !

Let's say that :

D = (Pi+2)/2Pi * (N.H)^specularPower
G = N.L*N.V
F = fresnel term as seen before

Then you have a PBR Blinn-Phong ! There are different way to write it, here is one :

Diffuse = clamp(N.L, 0, 1) * Albedo / Pi
Specular = (Pi+2)/2Pi * (N.H)^specularPower * F * specularColor
With (Albedo+SpecularColor < 1)

Finally here is a little webgl shader to play with, feel free to experiment !


PS : You will need a welgb enabled browser (chrome for example).
PS2: When you can latest driver are a must.
PS3 : Be sure to take a look at all the awesome shaders on shadertoy !!! :)




No comments:

Post a Comment