PROJET AUTOBLOG


blog.fevrierdorian.com

source: blog.fevrierdorian.com

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Lire les Light Stats dans Guerilla

mardi 14 décembre 2021 à 23:25

Depuis la version 2.3.9, Guerilla dispose d’un log de rapport de contributions des lights de vos scènes. Il n’est pas évidant d’interpréter correctement ces valeurs : Elles ne sont pas forcément simples à comprendre, et encore moins à mettre en relation avec l’image. :reflechi:

Nous allons donc commencer par expliquer ce qu’elles représentent, puis nous commenterons un petit rendu visant à pousser l’efficacité de ses statistiques dans leur retranchement.

Notez que cette version est sortie ce soir et que je n’ai pas pu m’empêcher de faire un billet… :baffed:

Activer le rapport

Pour activer le rapport de statistique des lights, il faut aller dans Preferences, Rendering, Logs & Diagnostics, mettre Verbosity à « Diagnostics » et cocher Render Statistics :

Explication détaillée

À la fin de votre rendu, vous aurez quelque chose qui ressemble à ça :

Light Stats:
  nSmp |          TL |  TL% |  OL% | Eff% | Separate Lights
 10.3M |   1065321.2 | 13.1 | 10.5 | 80.4 | Group9|SkyLight|Sky
  nSmp |          TL |  TL% |  OL% | Eff% | Shared Lights
 5.46M |    405505.3 |  5.0 |  4.0 | 80.6 | Group8|SquareLight
 5.45M |    880797.4 | 10.8 |  9.0 | 83.1 | Group9|SkyLight|Sun
 1.80M |    307087.1 |  3.8 |  3.3 | 87.2 | Group7|SquareLight2
 3.49M |    581026.5 |  7.1 |  6.3 | 87.9 | Group6|DistantSpotLight
 2.10M |    372714.8 |  4.6 |  4.0 | 88.2 | Group7|SquareLight3
 3.83M |   1379261.3 | 16.9 | 15.0 | 88.9 | Group5|DistantSpotLight1
 2.37M |    103511.3 |  1.3 |  1.1 | 89.8 | Group3|SpotLight
 2.53M |    243524.2 |  3.0 |  2.7 | 90.5 | Group2|SpotLight
 4.31M |    709680.5 |  8.7 |  8.1 | 92.8 | Group7|SquareLight1
 2.68M |    299954.9 |  3.7 |  3.4 | 92.9 | Group1|SpotLight
 4.42M |   1806236.6 | 22.1 | 21.1 | 95.4 | Group4|DistantLight
-----------------------------------------------------------------------
 48.7M |   8154621.0 |      |      |      | Total

« Pas mal, non ? C’est français. »

Pas de panique, on va commenter tout ça ! :hehe:

Comme vous vous en doutez, nSmp est le nombre de samples envoyés sur la light. Je ne m’éternise pas. :redface:

Les deux autres termes sont en revanche, plus complexes, mais ne vous inquiétez pas, je vais écrire doucement pour ne pas vous perdre… :bete:

TL est le total d’intensité lumineuse (Total Luma) agrégé par la lampe sans tenir compte de l’occlusion (c.à.d, sans prendre le test d’ombre).

Je suis obligé de m’arrêter pour expliquer un peu comment fonctionne Guerilla (et je suppose que c’est le cas pour la majorité des ray tracer du marché). Je vais volontairement être très grossier, le but est de comprendre un log, pas de vous faire un cours sur les moteurs de rendu (si ça vous intéresse c’est par ici).

Quand un rayon arrive sur une surface, le moteur calcul l’illumination de ce que nous allons appeler le shading point. Pour cela il va utiliser la normale de la surface du shading point et en extraire un hémisphère (la normal étant la direction du pôle).

Avec cet hémisphère, le moteur peu déjà éliminer les lights étant « derrière l’hémisphère » (c.à.d, derrière la normale du shading point) ainsi que celles « dos au shading point » (c.à.d, qui montrent leurs fesses au shading point) car elles ne contribueront pas à l’illumination du shading point.

Reste les autres lights, celles qui sont face au shading point : Comment déterminer la light ayant la meilleure contribution ? :petrus:

On pourrait lancer des rayons au hasard sur toutes les lights, mais en pratique, seules quelques-unes contribueraient vraiment à l’illumination du shading point. La question est donc de savoir s’il existe un moyen de déterminer quelles sont les lights qui pourraient contribuer le plus si, en effet, elles étaient visibles du shading point.

Et c’est là que c’est contre-intuitif : Pour déterminer s’il est pertinent de faire un coûteux test de visibilité de la light par le shading point, on va prendre chaque light et déterminer sa contribution théorique, c.à.d l’intensité lumineuse qu’elle « pourrait » générer sur le shading point si elle est visible par ce dernier.

Dis autrement, avant d’envoyer notre unique et coûteux rayon d’occlusion (test de visibilité) sur une light, on détermine l’illumination théorique de chaque light sur le shading point.

Mais comment on détermine la contribution théorique d’une light sans traverser la scène ? On calcule sa contribution (ou une approximation) comme s’il n’y avait rien d’autre que la light qui nous intéresse. On fait ça pour toutes les lights pouvant contribuer au shading point, et c’est seulement une fois qu’on a isolé la lampe la plus pertinente qu’on teste sa visibilité (c.à.d, qu’on lance un rayon dessus pour vérifier si un mur/objet est devant ou non). Encore une fois : On procède ainsi car calculer la contribution d’une light sans lancer de rayon est beaucoup (beaucoup) plus rapide que le coût du rayon pour déterminer si elle est visible au shading point.

Mais l’effet de bord est évident : Si vous avez une light derrière un mur, mais en direction de votre shading point, le moteur privilégiera cette lampe.

C’est ça le problème des path tracers. On peut tenter d’y répondre par du bidir, du vertex merging, etc. Mais le path tracing a des avantages que ces solutions ne gèrent pas facilement (ray differential pour le mip mapping).

Comprenez, on l’a dans l’os, lapin l’choix, et c’est pour ça que dès qu’on a du mal à garder le contrôle sur un lighting (comprenez, qu’on ne fait pas un lighting aux petits oignons par plan), on crée forcément des situations où le path tracer se fait avoir. :IFuckTheWorld:

Une fois que vous avez compris ça, vous êtes en mesure d’expliquer la relation entre TL% et OL%.

Première chose : TL% est le pourcentage d’intensité lumineuse sans tenir compte de l’occlusion (comprenez, la contribution « théorique ») de la light par rapport à toutes les lights de la scène. Total de TL% de toutes les lights est 100 %.

Et enfin : OL% est le pourcentage d’intensité lumineuse en prenant en compte l’occlusion (comprenez, après un test de visibilité réussi) de la light par rapport à toutes les lights de la scène.

Vous l’aurez deviné : TL% - OL% = Pourcentage de perte de cette light par rapport à tous les autres lights.

Et le ratio OL% / TL% = ratio d’efficacité de cette light dans la scène. Exemple dans notre cas sur la light la moins efficace :

>>> 4.0/5.0
0.8  # 80 %

Et cela correspond bien à notre valeur de Eff% (moins les imprécisions). :youplaBoum:

En pratique, la valeur TL n’est pas d’une grande aide, ce sont les valeurs TL%, OL% et Eff% qui sont importantes.

Le test du mur

Comme je suis taquin, je vais tenter de piéger Guerilla et surtout de voir si les statistiques des lights me remonte cette information. :reflexionIntense:

Voici la scène :

Un plan, une sphère, deux lights positionnées à 180 l’une de l’autre et un mur sur celle de droite :

Le rendu :

Clairement la light derrière le mur ne contribue pas au rendu, et les statistiques le confirme :

Light Stats:
  nSmp |          TL |  TL% |  OL% | Eff% | Separate Lights
  nSmp |          TL |  TL% |  OL% | Eff% | Shared Lights
 15.8M |   4436347.0 | 42.2 |  0.0 |  0.0 | derriere_mur|SquareLight
 23.2M |   6064878.0 | 57.8 | 48.7 | 84.4 | devant_mur|SquareLight
-----------------------------------------------------------------------
 39.0M |  10501225.0 |      |      |      | Total

On remarque immédiatement l’Eff% de la light derrière le mur à 0. Cette light est inefficace et peut être retirée du rendu sans risque. :bravo:

La raison pour laquelle le TL% de la light derrière le mur n’est que de 42 % et non de 50 % comme on pourrait s’y attendre (la scène étant très symétrique d’un point de vue lighting) c’est parce que les shading points de la caméra vers le mur excluent de facto la light derrière le mur (rappelez-vous, l’hémisphère). Le mur représentant une partie non négligeable de l’image, il est logique que le moteur estime, à juste titre, que la light de gauche (devant le mur) contribue plus à l’image.

Regardons les temps de rendu. Ma RenderPass est à 256 samples, threshold à 0.03 et min samples à 16. Le rendu original se fait en 26 secondes sur mon modeste PC. Si je prune la light derrière le mur, je tombe à 19 secondes.

Allons encore plus loin et regardons les light stats de ce « lighting parfait » :

Light Stats:
  nSmp |          TL |  TL% |  OL% | Eff% | Separate Lights
  nSmp |          TL |  TL% |  OL% | Eff% | Shared Lights
 22.8M |   3876291.8 | 100.0 | 77.4 | 77.4 | devant_mur|SquareLight
-----------------------------------------------------------------------
 22.8M |   3876291.8 |      |      |      | Total

Notez le 77.4 % de l’efficacité de la light. Elle semble diminuer par rapport au 84.4 % du rendu précédent. Rien d’anormal pour autant : Sur le premier rendu, le moteur avait le choix entre deux lights. Si, par exemple il tombait sur un shading point de la partie droite de la sphère (pointant vers la droite de la scène), il choisissait la light derrière le mur et c’est elle qui ratait son test de visibilité. L’efficacité de la light de droite était donc conservée.

Je soupçonne que quand il n’y a aucune light à choisir, Guerilla considère automatiquement le test de visibilité comme ayant échoué. C’est donc les ombres de la partie de droite de l’image qui entraînent un échec du test de visibilité.

Notez aussi le nombre total de samples lancé avant de converger : Un tiers de moins. Une information confirmée par l’AOV de heat.

Rendu avec les deux lights :

Rendu avec une seule light, à droite :

On remarque que Guerilla n’arrive pas à sampler une partie de l’image. Et pour cause, aucune light n’illumine ses zones. :cayMal:

Conclusion

J’espère que cette brève présentation vous a plu et que cette nouvelle feature vous permettra d’identifier les lights parasites de vos rendus, avec, pourquoi pas, un parsing automatique des logs… :siffle:

À très bientôt !

:marioCours: