PBR is a set of techniques aiming at improving realism of rendered graphics by using more physically correct formulas on how surfaces interact with light. Sometimes, especially in the realtime context it's called Physically Based Shading - PBS.
Compared to the old-school Ambient + Lambert Diffuse + Specular Blinn-Phong that you might know from OpenGL 1.0/2.0 era and first WebGL 1.0 engines, PBR brings a promise of the following benefits:
Unified shader being able to express wide range of materials from ceramics, wood and iron to sci-fi aluminum, chrome and plastic.
Predicable look under different lighting conditions.
We will cover this in more details in the future but in PBR we divide our materials into two main types:
Dielectrics / insulators (from plastic to rubber) - medium to very low reflectivity, base color due to reflected diffuse light
Metals / conductors (from silver to brushed aluminium) - highly reflective, no base color as they absorb the light, optional tint (e.g. gold)
Albedo, direct light diffuse, fresnel, diffuse reflection, specular reflection, final composition. More on this in the future as not everything here is 100% correct (e.g. I'm not completely sure about Fresnel)
Materials (Click for the realtime version)
Material mixing (Click for the realtime version)
Exposure (Click for the realtime version)
NOPE. Sorry. Please continue reading to find out why.
In the last 1.5 years I've implemented 2-3 versions of PBR in the last year with a varying success due to complexity and amount of supporting engine code they require. They are also custom, per-project built tools and therefore often no publishable online. And the code is a mess.
Learning about all that stuff is a pain. Most talks assume you just finished writing your own renderer and know all the math or you are just upgrading your engine with some new tricks and techniques. I haven't really found a A-Z description of how to put all these pieces to together in code.
So the idea is that through the series of blog posts I reimplement PBR with a better understanding of the math involved and document the process.
//this is shader code //Normal Distribution Function: GGX // a^2 //D(h) = -------------------------------- // PI * ((n.h)^2 * (a^2 - 1) + 1)^2 float aSqr = a * a; float Ddenom = dotNH * dotNH * (aSqr - 1.0) + 1.0; float Dh = aSqr / ( PI * Ddenom * Ddenom);
What's complexity you would ask? Let's try to list things that we should understand or at least know about and probably implement at some point:
In the next blog post I'll setup the code base, cover some basics like HDR, tonemapping and gamma to prepare us for Image Based Lighting.
In the meantime you might want to check out some other material covering the topic:
Open source engines implementing PBR