Lien de la note Hackmd
Before we start
Comment on genere une image ?
- On a vu le raytracing
- On a vu la rasterization
On va se focus sur le temps reel avec de la rasterization
Old Times
Lambert
On a tous fait un Lambert model
- Plus l’angle est eleve entre la normal et la lumiere, moins il n’y a d’energie
Il n’y a pas de modele $100\%$ diffus
En une seule operation on a notre BRDF
Il existe d’autres modeles mais la difference visuelle n’est pas assez bonne pour etre utilises
Phong
- Approximation pas tres bonne
- MAIS precurseur a son epoque ($’70s$)
Pas de conservation d’energie:
Pseudocode
Lambert
1
2
3
4
5
void main()
{
vec3 diffuse = kD * dot(normal, lightDirection) * color;
gl_FragColor.rgba = vec4(diffuse, 1.0);
}
Phong
1
2
3
4
5
6
7
void main()
{
vec3 r = reflect(- viewDirection, normal);
vec3 diffuse = kD * dot(normal, lightDirection) * color;
vec3 specular = kS * pow(max(dot(lightDirection, r)), exponent);
gl_FragColor.rgba = vec4(diffuse + specular, 1.0);
}
What and why
Introduction
Non-physical model requires a lot of tweaking
Si on a un artiste qui fait une scene en exterieur puis on lui dit qu’on doit aller dans un tunnel en voiture, l’artiste pleure Il doit tweaker les materiaux pour que ca ait l’air joli en fonction de la lumiere
C’est pour ca qu’il y a eu l’avenement du Real Time Rendering vers 2013
C’est dur de definir le PBR
Definition: PBR Modele mathematiques et approximations que nous allons tous suivre pour decrire les interactions entre la lumiere et la matiere
What is PBR ?
Pourquoi c’est populaire ?
Decrit le monde plus precisement, donne des rendus realistes Tout le monde utilise plus ou moins les memes inputs Moins de tweaking
Win-win pour les ingenieurs et artistes
Microfacets Theory
Ce modele approxime ce qu’il se passe dans la vraie vie
On dit que tous les materiaux sont composes de miroirs plus ou moins alignes
C’est quoi la difference entre un miroir et un plastique ?
Notre premier cas sera un miroir Le second est un materiaux super diffus
Dielectrics vs Conductors
Conductors
La couleur diffuse serait une approximation du sub-surface scattering
- Les conducteurs reflete $0-20\%$ de la lumiere
Les metaux n’ont pas de sub-surface scattering
- Les conducteurs refletent $60-90\%$ de la lumiere
- Certains conducteurs ont leur couleur propre due aux longueurs d’ondes absorbees
BRDF
BRDF Simplification
\[f_r(p,\omega_0,\omega_i)=f_d(p,\omega_0,\omega_i) + f_s(p,\omega_0, \omega_i)\]Notre BRDF devient pulg & play
On peut remplacer par ce qu’on veut du moment que $\int\le1$
Implementation notes
\[f_r(p,\omega_0,\omega_i)=k_df_d(p,\omega_0,\omega_i) + k_sf_s(p,\omega_0, \omega_i)\\ k_d+k_d\le1\]Diffuse Lobe
\[f_d(p,\omega_0,\omega_i) = \frac{\rho}{\pi}\]- $\rho$: reflectance spectrum
Specular Lobe
\[f_s(p,\omega_0,\omega_i)=\frac{D(\omega_0,\omega_i)F(\omega_0,\omega_i)G(\omega_0,\omega_i)}{4(\omega_0,\omega_i)(\omega_i\times n)}\]Specular BRDF
\[D_{GGX}(n,h,a)=\frac{\alpha^2}{\pi((n\times h)^2(\alpha^2-1)+1)^2}\\ \vec h=\frac{\vec v+\vec L}{\Vert\vec v+\vec L\Vert}\]- Normal distribution function $D(\omega_0, \omega_i)$
- Estimates the area of microfacets aligned to give perfect specular
- As usual, lots of different NDF equations…
- To be consistent, let’s implement the Trowbridge-Reitz equation
- Low roughness means few samples contributing a lot to specular
Shadowing term $G(\omega_0,\omega_i)$
\[G(n,v,l,k)=\underbrace{G_{SchlickGGX}(n,v,k)}_{Obstruction}\underbrace{G_{Schlik}(n,l,k)}_{Shadowing}\\ G_{SchlickGGX}(n,v,k)=\frac{n\times v}{(n\times v)(1-k)+k}\]- On va approximer $k=\alpha$
- Approximation de l’occlusion
L’orientation des facettes peut pieger la lumiere
Effet Fresnel
On a un joli coucher de soleil sur la mer (ou ocean) L’eau est un miroir modulo les vagues
Pour tout materiaux, la reflectance va etre maximale aux angles rasants
L’effet Fresnel c’est le poids du specular lobe $k_s$
- $f_0$: base reflectivity at normal incidence
- $f_{90}$: base reflectivity at grazing angle
- Almost always 1 for conductors
Fresnel reflectance for common materials
- For dialectics, $f_0$ is often approximated with $0.04$
- Some materials $f_0$ are tainted (gold, copper)
- Implementation note:
- For dielectics, pick $0.04$ $f_0$
- For conductors, store $f_0$ in albedo texture
- Use metallic input to lerp between the 2
Demo !
Direct-Lightning pseudocode
1
2
3
4
5
6
7
8
9
10
11
vec3 radiance = vec3(0.0);
for(int i = 0; i < NB_LIGHTS; ++i)
{
vec3 w_i = lights[i].direction;
vec3 kS = FresnelShlick(f0, wi, w_o);
vec3 specularBRDFEval = kS * f_s(p, w_i, w_o);
vec3 diffuseBRDFEval = (1.0 - kS) * f_d(p, w_i, w_o);
radiance += (diffuseBRDFEval + specularBRDFEval) * sampleLight(lights[i], p, w_i) * dot(normal, w_i);
}
Textures
Les artistes font plusieurs textures
To remember !
- Diffuse is an approximation of sub-surface scattering
- La plupart des moteurs connus vont avoir des metallics workflow
- Ca simplifie beaucoup la vie
Ponctual light
Point light
- Infinitely small
- Isotropic
- Describe only by a position
- Simple to code and fast to sample
- Power unit should be set using Lumens
- How to select a proper value ?
- Not as accurate as Area Light
Cette lumiere n’existe pas dans la vraie vie
Note
- On ne va pas parler de directionnal light (deja fait)
- Si on utilise une directionnal light, il faudra tweaker les parametres
- Ce n’est pas aussi fidele que les Area lights
Image Based Lightning
- 4 points lights
- Avec environnement
IBL Diffuse
\[\int_{\Omega}f_d(p,\omega_0,\omega_i)L_i(p,\omega_i)m\times\omega_i\]Mais c’est juste un flou gaussien ?
\[L_0(p,n)=\int_{\Omega}\frac{\rho}{\pi}L_i(p,\omega_i)n\times\omega_id\omega_i\\ L_0(p,n)=\frac{\rho}{\pi}\int_{\Omega}L_i(p,\omega_i)n\times\omega_id\omega_i\]C’est pas si faux que ca, c’est assez proche
Il faut faire une integration par angle solide, et c’est complique.
- Utilisation des coordonnees spheriques pour l’integration
- Discretiser l’integrale avec la somme de Riemann
- Calculer pour chaque texel, avec la direction $N$ du centre
IBL Specular
\[\int_{\Omega}f_s(p,\omega_0,\omega_i)L_i(p,\omega_i)m\times\omega_i\]\[L_0(p,\omega_0)=\int_{\Omega}L_i(p,\omega_i)d\omega_i\times\int_{\Omega}f_r(p,\omega_0,\omega_i)n\times\omega_i d\omega_i\]Ca a ete teste et ca marche: c’est ca la 3D
Changer le niveau de roughness c’est faire du downsampling, pourquoi par appliquer la roughness en faisant des images de plus en plus petites
Pre-computed BRDF
\[\begin{aligned} \int_{\Omega}f_r(p,\omega_0,\omega_i)n\times\omega_id\omega_i &= F_0\int_{\Omega}f_r(p,\omega_0,\omega_i)(1-(1-\omega_0\times h)^5)n\times\omega_id\omega_i\\ &+\int_{\Omega}f_r(p,\omega_0,\omega_i)(1-\omega_0\times h)^5n\times\omega_id\omega_i \end{aligned}\]Obtained bu substituting Fresnel Shlick Only 2 inputs left: roughness, viewing angle
At runtime:
- Fetch pre-integrated BRDF texture
- Fetch convoluted environment
- Apply the above equation to get the full specular component
Specular: compisistion
1
2
3
c2 brdf = GetIntegratedBRDF(NdotV, roughness);
vec3 prefilteredSpecular = GetPrefilteredSpecular((NdotV, roughness);
vec3 specular = prefilteredSpecular * (F * brdf.x + brdf.y);
F
: Fresnel term
To remember
- C’est juste du pre-filtering
Colorspace and color precision
- sRGB vs Linear
- Monitors apply pow function to luminance
- Toute l’industrie a du se base sur les ecran qui font ca donc ils ont cree le $sRGB$
- Sur photoshop, une image sera encodee en sRGB pour retrouver les couleurs imaginees
On va eviter de faire nos calculs en sRGB
- Soit on fait tout en sRGB
- Soit on fait tout en lineaire $\Rightarrow$ OUI
- On applique a la fin la fonction sRGB pour convertir en lineaire
HDR vs LDR
HDR: High Dynamic Range
Reinhard Tonemapping:
\[color_{final}=\frac{c}{c+1}\]- HDR has larger range of values
- Units will create radiance color outside the $0\dots1$ range
- Perform computation in HDR, tonemap to LDR is required
- HDR is required to get correct PBR result
- Especially important for IBL
Going further
Advanced materials
Examples: hair, skin, cloud, etc.