Après avoir écrit des shaders phong & blinn `` standard '' pendant un certain temps, j'ai récemment commencé à me familiariser avec l'ombrage à base physique. Une ressource qui m'a beaucoup aidé sont ces notes de cours , en particulier cet article - elles expliquent comment rendre le blinn plus physiquement plausible.
J'ai implémenté le modèle blinn proposé dans le document, et j'aime vraiment à quoi il ressemble. Le changement le plus important proposé (imo) est l'inclusion de la réflectance de Fresnel, et c'est aussi la partie qui me pose problème. Malheureusement, l'auteur a choisi de se concentrer uniquement sur la partie spéculaire, en omettant la réflectance diffuse. Étant donné, par exemple, une réflexion diffuse lambertienne, je ne sais tout simplement pas comment la combiner avec le blinn «amélioré» - parce que l'ajout de parties diffuses et spéculaires ne semble plus être correct.
Dans certains shaders, j'ai vu un «terme de Fresnel» à virgule flottante dans la plage 0 - 1 utilisé, basé sur les indices de réfraction des médias participants. L'approximation de Schlick est utilisée à chaque fois:
float schlick( in vec3 v0, in vec3 v1, in float n1, in float n2 )
{
float f0 = ( n1 - n2 ) / ( n1 + n2 );
f0 *= f0;
return f0 + ( 1 - f0 ) * pow( dot( v0, v1 ), 5 );
}
En procédant ainsi, on peut alors interpoler linéairement entre contribution diffuse et contribution spéculaire sur la base du terme de Fresnel, par exemple
float fresnel = schlick( L, H, 1.0002926 /*air*/, 1.5191 /*other material*/ );
vec3 color = mix( diffuseContrib, specularContrib, fresnel );
Dans l'article, l'auteur déclare que cette approche est incorrecte - car elle assombrit fondamentalement la couleur spéculaire chaque fois que L est parallèle ou presque parallèle à H - et qu'au lieu de calculer un f0 basé sur les indices de réfraction, vous devriez traiter le spéculaire se colorer comme f0 et avoir votre approximation schlick calculer un vec3, comme ceci:
vec3 schlick( in vec3 v0, in vec3 v1, in vec3 spec )
{
return spec + ( vec3( 1.0 ) - spec ) * pow( dot( v0, v1 ), 5 );
}
Il en résulte que la couleur spéculaire va vers le blanc à des angles de regard.
Maintenant ma question est, comment pourrais-je introduire un composant diffus dans ceci? À 90 °, la contribution spéculaire est entièrement blanche, ce qui signifie que toute la lumière entrante est réfléchie, il ne peut donc pas y avoir de contribution diffuse. Pour des angles d'incidence <90 °, puis-je simplement multiplier toute la partie diffuse avec (vec3 (1) - schlick), c'est-à-dire la proportion de lumière qui n'est pas réfléchie?
vec3 diffuseContrib = max( dot( N, L ), 0.0 ) * kDiffuse * ( vec3( 1.0 ) - schlick( L, H, kSpec ) );
Ou ai-je besoin d'une approche complètement différente?
Réponses:
La réponse courte:
Semble-t-il assez bon?
Oui - Gardez-le.
Non - Jouez encore avec.
Longue réponse:
L'obtention d'un ombrage physique réaliste et précis nécessite plus de puissance GPU que possible, vous devrez toujours recourir à des trucs pour la simple raison qu'un ordinateur ne peut pas simuler l'univers entier, pas même tout le spectre de la lumière visible.
C'est la "troublante vallée" de l'ombrage.
Non seulement en raison de l'éclairage ambiant et de l'occlusion, mais par exemple, les environnements externes à la fois le jour et le clair de lune ont une énorme quantité de lumière du spectre UV dont une infime partie est renvoyée au spectre visible par divers matériaux, principalement organiques. Différents types d'éclairage à tube fluorescent et HID émettent également une bonne quantité de lumière UV.
L'effet est subtil mais grâce à des années d'évolution, le cerveau le traite instinctivement car cela signifiait la différence entre un bon repas et peut-être une longue mort atroce. .
Les styles artistiques Cartoony, irréalistes et presque réalistes mais intentionnellement décalés par une bonne marge (par exemple: Halo) évitent ce problème.
Un autre problème est que deux humains n'ont pas la même présence de récepteur RYGBL ni courbe de réponse alors que les moniteurs sont strictement RVB et ne peuvent donc pas reproduire parfaitement des images pour tous les humains. (Rouge, jaune, vert, bleu et Luma, voir Tetrachromacy - http://en.wikipedia.org/wiki/Tetrachromacy )
Peu importe à quel point vous travaillez dur, il y aura «quelque chose qui ne va pas» et des améliorations, au moins pour quelqu'un quelque part.
Et c'est une des raisons pour lesquelles il existe de nombreux modèles d'ombrage.
En raison de tout cela, un bon artiste finit toujours par tromper les niveaux de lumière et de réponse lumineuse sur les environnements dans une certaine mesure pour atteindre un résultat "assez bon" (ce n'est jamais parfait), il suffit de leur donner accès à jouer avec les paramètres et tricher à leur façon à des résultats agréables.
la source