Skip to main content

Malentendu sur la multidiffusion

juillet

13, 2020

by coberst


Technologie

Construisons notre propre GGX FDRB (fonction de distribution de réflectivité bidirectionnelle) de pointe, à multidiffusion, pour un rendu basé sur la physique.

Bien sûr, tout cela a été construit auparavant – par des personnes très intelligentes qui ont utilisé leurs connaissances en mathématiques et en physique pour créer des solutions sophistiquées. Si tu souhaites vraiment lire beaucoup pour obtenir un résultat similaire, n’hésite pas à essayer ces excellents articles :

Nous allons oublier toute cette lecture et faire les choses de la manière la plus simple. Prêt ?

Commençons par ton GGX contemporain conventionnel avec toutes les corrections Smith correspondantes. La séquence d’images suivante est générée avec le mode d’éclairage de l’environnement de l’explorateur FDRB de Disney. Il montre un GGX métallique avec une rugosité variable de 0,3 à 0,9 en utilisant la paramétrisation commune dealpha = rugosité au carré.

Remarque à quel point le matériau semble trop sombre lorsque la rugosité est dense. Une fois de plus, des personnes intelligentes ont travaillé dur pour trouver et régler ce problème.

Comparons l’image ci-dessus avec Kulla/Conty’s Multiscattering GGX BRDF.

Résolu !

Maintenant, nous pouvons essayer de savoir comment cette solution peut marcher. Le calcul est déjà fait et tu devrais probablement le faire aussi. Il est à la fois intéressant et utile pour comprendre d’autres problèmes connexes. Mais n’oublie pas que nous allons éviter tout cela.

Commençons par le haut. Pourquoi préférons-nous le PBR (physical based restituer) ? Ce n’est pas parce que nous aimons la physique (du moins, pas moi). Et si nous étions extrêmement préoccupés par la physique, ce serait une petite erreur de se concentrer sur le fait que nous commettons certainement des péchés plus graves dans notre pipeline d’images de bout en bout

L’infographie n’est pas un rendu prédictif. Nous ne simulons pas la physique pour le réalisme, ce n’est pas le but. Nous essayons de faire de belles images.

Nous avons remarqué que la simulation de la physique pour faire de jolies images permettait de faciliter les flux de travail : découplage des matériaux de l’éclairage, réduction du nombre de hacks et de paramètres, possibilité d’utiliser des bibliothèques de matériaux réels, etc.

Ainsi, lorsque nous prenons des décisions sur la manière de procéder, nous devons considérer les préoccupations artistiques avant les préoccupations techniques. S’il y a un problème artistique que nous pouvons identifier, alors nous pouvons nous tourner vers la physique pour voir s’il y a une solution technique. Dans notre FDRB actuel, le problème est qu’il serait bien que nos paramètres des matériaux soient orthogonaux, et le fait que les choses deviennent plus sombres à mesure que nous modifions la rugosité n’est pas idéal.

Est-ce que la physique peut nous aider ? Cet assombrissement est-il physiquement correct ou non ? Comment faire le test ? Saute dans la fournaise ! Mettons notre objet métallique recouvert de GGX dans un environnement uniformément éclairé et voyons ce qui se passe :

La lumière éclaire notre surface et atteint nos microfacettes. Les microfacettes renvoient une partie de la lumière et en réfractent une autre, selon Fresnel. Si nous supposons que cette surface est en métal, la physique nous dit que la lumière réfractée, celle qui va « à l’intérieur » de la surface, est absorbée et ne sort jamais (car elle est convertie en chaleur).

Il est raisonnable que même dans une fournaise, notre objet métallique ait une couleur car une partie de l’énergie sera absorbée. Qu’en est-il si nous prenons nos microfacettes et les faisons toujours refléter toute la lumière, sans absorption ?

Cela signifie que nous devons régler notre f0 sur 1 (souviens-toi, Fresnel est ce qui contrôle la quantité de lumière que les microfacettes diffusent). Essayons et voyons ce qui arrive :

Cet objet n’est toujours pas blanc. Quelque chose ne va pas ! Maintenant, un lecteur curieux pourrait dire : « Comment sais-tu que c’est mal ? Peut-être que certaines directions diffusent plus de lumière et d’autres moins ? Il n’est pas toujours facile de deviner la bonne solution.

Considérons plutôt à quoi ressemble un rayon lumineux, partant de la caméra. Il touchera une ou plusieurs des microfacettes, rebondira, puis finira par s’échapper et se connectera à l’environnement de la fournaise – qui émettra toujours une énergie constante donnée.

Quelle quantité de cette énergie devrait donc atteindre la caméra ? Tout ! Parce qu’en fonction de notre réglage, toute l’énergie doit être réfléchie, quel que soit le nombre de microfacettes qu’elle touche. Tous les rayons lumineux mènent à la caméra, en définitive.

C’est pourquoi l’image ci-dessus doit être complètement blanche. Comme ce n’est pas le cas, nous devons avoir un problème dans nos calculs.

Si tu as étudié les FDBR, tu sais que dans le modèle des microfacettes, il existe une fonction de visibilité masquante-obscurcissante qui modélise les microfacettes qui sont occultées par d’autres. Ce que nous ne modélisons pas généralement, cependant, c’est le fait que ces occlusions sont elles-mêmes des microfacettes, de sorte que la lumière devrait rebondir et éventuellement sortir, et non être rejetée.

C’est ce que modélisent et fixent les modèles de multidiffusion. Si nous placions le GGX de Kulla et Conty dans une fournaise, il produirait une image blanche totalement ennuyeuse et totalement correcte pour un matériau entièrement réfléchissant quelle que soit sa rugosité

Le modèle de Kulla n’est cependant pas simple et dans de nombreux cas, ne vaut pas la peine d’être utilisé pour un problème aussi mineur. Alors est-ce que notre solution peut-elle être plus simple ? Et si nous savions quelle quantité de lumière notre FDRB émet dans une fournaise pour une rugosité et un angle de vue donnés (en fixant alors à nouveau f0=1) ? Pourrions-nous simplement prendre cette valeur et normaliser le FDRB avec elle ?

Alerte au spoiler : on peut facilement. Nous avons déjà cette valeur « fournaise » dans la plupart des moteurs modernes dans les tables de recherche utilisées pour l’approximation de l’éclairage basée sur l’image à somme fractionnée très populaire.

Le tableau à somme fractionnée réduit la « FDRB dans une fournaise » (également appelée albédo directionnel ou réflectivité hémisphérique directionnelle) à une échelle et un facteur de biais (addition) à appliquer à la valeur f0 de Fresnel.

Dans notre cas, nous voulons normaliser en considérant f0=1, donc tout ce que nous faisons est d’échelonner notre lobe FDRB de un sur biais (rugosité,ndotv) + échelle (rugosité,ndotv). C’est le résultat :

Nous récupérons un peu d’énergie à haute rugosité, et si nous testions cela dans un four, cela donnerait un résultat blanc, correctement, à f0=1. Mais il est aussi différent de celui de Kulla. En particulier, la couleur n’est pas aussi saturée dans les matériaux bruts. Comment cela se fait-il ? Encore une fois, si tu as déjà étudié ce problème (tricheur !), tu connais la réponse.

Une bonne multidiffusion ajoute de la saturation parce que lorsque la lumière frappe plus de microfacettes avant de s’échapper de la surface, nous captons plus de couleur (augmenter une couleur d’une puissance donnée donne une couleur plus saturée). Alors comment cela peut-il être physiquement mauvais, mais néanmoins correct dans notre test ?

En ne simulant pas cette saturation supplémentaire, nous continuons à économiser l’énergie, mais nous avons changé la signification de nos paramètres FDRB. La « signification » de f0 dans notre FDRB multidiffusant « ignorant » n’est pas la même que celle de Kulla. Il en résulte un changement d’albédo, mais le FDRB lui-même est toujours économe en énergie. Il s’agit juste d’un paramétrage différent.

Et surtout, je dirais que c’est un meilleur paramétrage ! Il faut se souvenir de nos objectifs. Nous ne faisons pas de la physique pour la physique, nous le faisons pour aider notre production.

Nous préférons rendre nos paramètres plus orthogonaux afin que les artistes n’aient pas besoin d' »éclaircir » artificiellement notre FDRB à haute luminosité. Si nous optons pour la solution « plus correcte » (à ce propos, ce récent article de Narkowicz est très intéressant à lire), nous ajouterons une dépendance différente, de sorte que la rugosité, au lieu d’assombrir nos matériaux, les rend plus saturés (ce qui irait en quelque sorte à l’encontre du but recherché). Tu peux imaginer certains scénarios où cela pourrait être souhaitable, mais je dirais que c’est presque toujours mauvais pour nos cas d’utilisation.

Si nous voulions simuler la saturation supplémentaire, il existe quelques moyens faciles. Une fois de plus, en optant pour les plus « ignorants » (simples), nous pouvons simplement mettre le FDRB à l’échelle 1+f0*(1/(biais(rugosité,ndotv) + échelle(rugosité,ndotv)) – 1), ce qui donne le résultat suivant :

Maintenant, nous nous rapprochons de la solution de Kulla. Si tu te demandes pourquoi l’approximation de Kulla est meilleure, comme elle pourrait ne pas se voir sur les images, c’est parce que la nôtre ne respecte pas la réciprocité.

Cela pourrait être important pour Sony Imageworks (car certains algorithmes de transport de rayons lumineux hors ligne l’exigent), mais ce n’est pas pertinent pour nous.

Maintenant que nous avons trouvé une approximation dont nous sommes satisfaits, nous pouvons (et devrions) aller plus loin et voir ce que nous faisons réellement. Oui, nous avons une formule, mais elle dépend de certains tableaux de référence.

Ce n’est pas un gros problème (nous avons besoin de ces tables pour l’éclairage basé sur l’image de toute façon), mais ce serait une recherche de texture supplémentaire et il est toujours important de revérifier nos calculs. Visualisons donc la fonction 1/[biais(rugosité,ndotv) + échelle(rugosité,ndotv)] que nous utilisons :

Cela paraît vraiement simple ! En fait, c’est si simple qu’il n’est pas nécessaire d’avoir un outil sophistiqué pour le trouver – alors je vais simplement le montrer : 1 + 2*alpha*alpha * ndotv Très bien.

Approximation par rapport au facteur de normalisation correct (surface grise).

Tu peux voir qu’il y a une petite erreur dans le test de la fournaise. Nous pourrions l’améliorer en effectuant un ajustement polynomial correct (il apparaît que « 2 » et « 1 » dans la formule ci-dessus ne sont pas les meilleures constantes), mais définir ce qui est « meilleur » serait un problème en soi, parce que faire une simple minimisation de la moyenne quadratique sur la fonction de normalisation n’a pas vraiment beaucoup de sens (nous devrions nous préoccuper des visuels finaux, des mesures perceptives, des angles qui importent le plus, etc.) Nous avons déjà passé trop de temps pour une si petite correction. De plus, les images effectivement restituées sont très difficiles à distinguer de la solution basée sur les tableaux.

Voyons maintenant ce que nous pourrions faire si nous voulions aller encore plus loin en supprimant la dépendance de l’ndotv. Il apparaît que, dans ce cas, 1+alpha*alpha fait aussi bien l’affaire.

Nous appliquons un facteur multiplicatif à notre FDRB pour l’éclaircir à une rugosité élevée, ce qui est tout à fait logique.

Bien sûr, cela ajoute encore des erreurs, et cela commence à se voir au fur et à mesure que la forme du FDRB change. Nous obtenons plus d’énergie aux angles d’attaque sur les surfaces rugueuses, mais cela peut être suffisant selon les besoins :

Sous-exposé pour souligner qu’avec l’approximation plus simple, parfois nous perdons de la lumière, parfois nous en ajoutons.

J’espère que tu as compris la grande leçon. Bien sûr, tu peux te consacrer à la chasse aux graphiques qui simulent parfaitement la physique du monde réel. Tu peux aussi tricher. Et que ce soit pour la performance, la simplicité ou par pure paresse, parfois la tricherie est la bonne réponse.


Ni Roblox Corporation ni ce blog ne cautionnent ni ne soutiennent aucune entreprise ou service. En outre, aucune garantie ou promesse n’est faite quant à l’exactitude, la fiabilité ou l’exhaustivité des informations contenues dans ce blog.

Cet article de blog a été publié à l’origine sur Roblox Tech Blog.