ce sont les mêmes paramètres, à gauche un dielectrique et à droite un métal.
et alors ?
avec ces 3 paramètres : couleur, métal et alpha, on peut écrire la brdf,
ie la fonction qui décrit une matière pour les métaux et les
dielectriques, ie les non métaux :
\[
\begin{eqnarray*}
\mbox{(métaux) } f_r( \vec{d}, \vec{l} ) &= &black + color \times \frac{8+\alpha}{8 \pi} (
\cos \theta_h )^\alpha \\
\mbox{(non-métaux) } f_r( \vec{d}, \vec{l} )&=
& \frac{color}{\pi} + white \times \frac{8+\alpha}{8 \pi} (
\cos \theta_h )^\alpha
\end{eqnarray*}
\]
chaque modèle est composé de 2 termes : la partie diffuse, qui
correspond à la diffusion de la lumière dans l'épaisseur de la matière,
comme prédit par Lambert, ainsi que la partie spéculaire, qui correspond
au reflet à la surface de la matière, comme prédit par Fresnel. Les
métaux ne diffusent pas la lumière, il n'y a qu'une réflexion colorée en
surface, alors que pour les autres matières la couleur correspond à la
diffusion colorée de la lumière et à un reflet en surface de couleur
neutre / blanc.
on peut également construire un modèle unique, utilisable avec les
métaux et les non-métaux mais paramétré avec une couleur de diffusion et
une couleur de surface :
\[
f_r( \vec{d}, \vec{l} )= \frac{diffuse}{\pi} + specular \times \frac{8+\alpha}{8 \pi} (
\cos \theta_h )^\alpha \\
\]
il suffit d'initialiser ces couleurs en fonction des paramètres de base de la matière, métal, couleur et alpha :
\[
\begin{eqnarray*}
diffuse &= & (1-metal) \times color + metal \times black \\
specular &= & (1-metal) \times white + metal \times color
\end{eqnarray*}
\]
bilan...
ce modèle est toujours très utilisé, il est assez simple à comprendre,
facile à programmer, mais c'est un modèle empirique, ie une grosse
approximation de la physique. pour faire mieux et reproduire
correctement plus de types de matières, il faut regarder un peu plus en
détail les travaux des physiciens, les formules sont moins simples mais
le résultat est quand même un peu plus subtil... les principes de
Fresnel sont dans la
doc
en ligne (cf lumière et matière), et la suite, la construction de la
nouvelle génération de modèles de matières se trouve sur cette
page (cf lumière et reflets)
comment ça se code ?
après les calculs d'intersections, on connait le point p, sa normale n,
et sa matière, c'est à dire les paramètres du modèle : métal, couleur et
alpha.
les directions vers la camera et la source de lumière sont nécessaire également.
attention !! à l'orientation des vecteurs, leur origine se trouve sur le point p...
// paramètres de la matière
Color color;
float metal;
float alpha;
Color fr( const Vector& d, const Vector& n, const Vector& l )
{
// verifie que les vecteurs sont bien orientes. d vers la camera, l vers la lumiere
assert(dot(n, d) >= 0);
assert(dot(n, l) >= 0);
// calcule h
Vector h= normalize(d+l);
// et le cosinus avec la normale
float cos_theta_h= dot( normalize(n), h );
if(metal)
// pour les metaux
return (alpha+8) / float(8*M_PI) * std::pow(cos_theta_h, alpha) * color;
else
// pour les autres
return color + (alpha+8) / float(8*M_PI) * std::pow(cos_theta_h, alpha) * White();
}
on peut aussi éviter de faire le test sur métal en séparant les 2 couleurs, celle du reflet et celle de la matière :
// paramètres de la matière
Color color;
Color specular;
float alpha;
Color fr( const Vector& d, const Vector& n, const Vector& l )
{
// verifie que les vecteurs sont bien orientes. d vers la camera, l vers la lumiere
assert(dot(n, d) >= 0);
assert(dot(n, l) >= 0);
// calcule h
Vector h= normalize(d+l);
// et le cosinus avec la normale
float cos_theta_h= dot( normalize(n), h );
return color + (alpha+8) / float(8*M_PI) * std::pow(cos_theta_h, alpha) * specular;
}
remarques : pour reproduire
les exemples de cette page, il faut programmer l'éclairage par un
soleil et par un ciel avec des directions aléatoires, cf les
tps et le
cours.