Image principale : une longue colonnade éclairée par le soleil, avec des ombres nettes et stables sur l’allée

Les ombres font partie des détails qui ancrent une scène 3D et la rendent crédible, mais aussi de ceux qu’il est le plus facile de rater de façon visible. Cette mise à jour rend les ombres du soleil plus stables, plus propres et bien plus faciles à régler, et apporte les mêmes améliorations aux spot lights, point lights et area lights.

En bref :

Dans cet article

Pourquoi les ombres sont importantes

Retirez les ombres d’une scène et tout semble flotter. Les objets perdent leur lien avec le sol, la profondeur devient plus difficile à percevoir et l’éclairage paraît plat. Une bonne ombre vous indique où se trouvent les objets, quelle est leur taille et d’où vient la lumière.

Une mauvaise ombre se remarque tout autant. Des contours qui fourmillent lorsque la caméra bouge, des rayures sur une surface ou une ombre qui se détache de l’objet qui la projette brisent immédiatement l’illusion. C’est précisément ce à quoi s’attaque cette release.

Comment fonctionne une ombre en temps réel ?

Dans la réalité, les ombres naissent d’une lumière bloquée, mais un moteur de rendu temps réel ne suit pas le trajet de la lumière. Il utilise une astuce moins coûteuse et très efficace appelée shadow map :

  1. Regarder depuis la lumière. Nous rendons la scène du point de vue de la lumière, mais nous ne conservons que la distance à la surface la plus proche pour chaque pixel. Le résultat est la shadow map.
  2. Regarder depuis la caméra. Pour chaque pixel à l’écran, nous déterminons sa position du point de vue de la lumière et comparons sa distance avec celle enregistrée dans la shadow map.
  3. Décider. Si un élément plus proche de la lumière a été enregistré, le pixel est dans l’ombre. Sinon, il est éclairé.

Schéma : une shadow map en trois étapes

Le problème, c’est qu’une shadow map est une texture de résolution fixe. Voyez-la comme une photo basse résolution de la scène prise depuis la lumière. Presque toutes les techniques d’ombrage sont des moyens de tirer le meilleur parti de cette résolution limitée.

Et les ombres en ray tracing et en path tracing ?

Les shadow maps sont une approximation : il est donc légitime de se demander pourquoi ne pas simplement suivre la lumière. Sur les GPU dotés de ray tracing matériel, c’est possible : on lance un rayon depuis chaque point visible vers la lumière, et si quelque chose fait obstacle, le point est dans l’ombre. Il n’y a pas de résolution de texture à épuiser, donc pas d’effet de pixellisation, pas d’acné et pas de peter-panning, et les ombres douces sont rendues avec précision. Le path tracing va plus loin et suit de nombreux trajets lumineux aléatoires qui rebondissent dans la scène : les ombres, les réflexions et l’éclairage indirect proviennent tous du même processus. L’exemple de path tracer d’Evergine montre à quoi cela ressemble.

Schéma : comparaison entre shadow maps et ombres en ray tracing

Le prix à payer, ce sont les performances. Une image propre nécessite plusieurs rayons par pixel à chaque frame, généralement suivis d’un denoiser. La scène a besoin d’une structure d’accélération qui doit être reconstruite lorsque les objets bougent. Et les rayons partent dans toutes les directions, ce qui sollicite bien davantage la mémoire GPU que la rastérisation de triangles dans une texture. Même les GPU desktop haut de gamme comptent soigneusement leurs rayons, et la plupart des téléphones, tablettes et appareils d’entrée de gamme ne disposent d’aucun ray tracing matériel.

C’est pourquoi les shadow maps restent la solution de référence pour les ombres en temps réel : elles sont peu coûteuses, prévisibles et fonctionnent sur pratiquement tous les appareils. Le ray tracing est une excellente option lorsque le matériel le permet, mais ce sont les shadow maps qui permettent à une scène de fonctionner partout ailleurs, et c’est pourquoi nous continuons à investir dans cette technique.

Le problème du soleil, et les cascades

Une lumière directionnelle représente le soleil, et le soleil éclaire tout. Une seule shadow map devrait couvrir tout le monde visible : une texture étirée sur des centaines de mètres produirait des ombres pixellisées juste devant le joueur, là où le détail compte le plus.

La solution classique consiste à utiliser des cascaded shadow maps. Nous découpons la vue en tranches selon la distance à la caméra : une petite tranche près de vous, une plus grande derrière, et ainsi de suite. Chaque tranche dispose de sa propre shadow map : les ombres proches sont nettes et les ombres lointaines plus grossières. Les objets éloignés étant petits à l’écran, on le remarque rarement.

Schéma : le frustum de la caméra découpé en quatre cascades, chacune rendue dans une shadow map de même résolution

Evergine utilisait déjà des cascades. La nouvelle release vise à améliorer leur comportement.

Les limites de l’ancienne approche

Trois problèmes revenaient sans cesse :

Quoi de neuf

Des cascades qui ne scintillent plus

L’espace des ombres dépend désormais uniquement de l’orientation de la lumière, et non de la direction vers laquelle regarde la caméra. Chaque cascade est également alignée sur la grille de texels de la shadow map, et sa taille ne change que par petits paliers d’environ 2 %. Ainsi, déplacer ou faire pivoter la caméra ne modifie plus quel texel couvre quelle partie du monde, et le scintillement disparaît.

Schéma : le contour d’une ombre sur trois frames, avant et après l’alignement des cascades sur la grille de texels

Un bias qui comprend votre scène

Le bias est désormais appliqué dans l’espace monde et exprimé en texels de shadow map. Deux nouvelles propriétés, ShadowDepthBias et ShadowNormalBias, s’adaptent automatiquement à la taille des texels de chaque cascade et à la douceur du filtre d’ombre. Un seul réglage se comporte désormais de façon cohérente de la cascade la plus proche à la plus éloignée, ce qui élimine les bandes d’acné aux angles rasants et les ombres flottantes au loin.

Schéma : bias trop faible, bias équilibré et bias trop fort

Spot lights, point lights et area lights

Le modèle de bias basé sur les texels ne se limite pas au soleil. Les spot lights, point lights et area lights l’utilisent désormais aussi : ShadowDepthBias et ShadowNormalBias ont donc la même signification pour tous les types de lumière. Au passage, nous avons corrigé deux problèmes :

Schéma : la bande de garde qui fait se chevaucher les faces du cube autour d’une point light

Des cascades réglables

Les lumières directionnelles exposent désormais les compromis entre qualité et performances :

Schéma : les modes d’ajustement de cascade Stable et Tight

Remarque : l’intervalle de mise à jour n’a aucun effet lorsqu’une lumière est rendue par plusieurs caméras.

Un meilleur débogage

Le Debug Mode des lumières affiche désormais la couleur de chaque cascade (et de chaque face du cube pour les point lights), ainsi qu’un damier de texels de shadow map de 8x8, pour que vous puissiez voir exactement la densité de vos ombres à l’écran. Les spot lights disposent également de leur propre DebugMode.

Nous avons également corrigé des problèmes connexes : les distances de découpage des cascades utilisent désormais la bonne formule, les caméras orthographiques dont le plan proche est à zéro ne produisent plus de découpages invalides, et le rendu de plusieurs caméras avec plusieurs lumières directionnelles projetant des ombres ne conduit plus les lumières à écraser mutuellement leurs shadow maps. Les backends gèrent le depth clamping de manière cohérente, si bien que les objets situés devant une cascade ne sont plus tronqués.

Voyez la différence

Faites glisser le curseur pour comparer l’ancien système d’ombres au nouveau, dans la même scène et avec la même position de caméra.

Avant : colonnade vue depuis l’allée, avec l’ancien système d’ombres Après : colonnade vue depuis l’allée, avec le nouveau système d’ombres
Comparaison 1
Avant : scène de test, vue 2, avec l’ancien système d’ombres Après : scène de test, vue 2, avec le nouveau système d’ombres
Comparaison 2
Avant : clôture et base de colonne, avec l’ancien système d’ombres Après : clôture et base de colonne, avec le nouveau système d’ombres
Comparaison 3
Avant : scène de test, vue 4, avec l’ancien système d’ombres Après : scène de test, vue 4, avec le nouveau système d’ombres
Comparaison 4
Avant : scène de test, vue 5, avec l’ancien système d’ombres Après : scène de test, vue 5, avec le nouveau système d’ombres
Comparaison 5
Avant : colonnade et obélisques au loin, avec l’ancien système d’ombres Après : colonnade et obélisques au loin, avec le nouveau système d’ombres
Comparaison 6

Prise en main

Vous pouvez tout régler depuis l’éditeur ou depuis le code. Les valeurs ci-dessous sont des points de départ indicatifs : ajustez-les à votre scène.

// Get the directional light of your sun entity
var sun = sunEntity.FindComponent<DirectionalLight>();

sun.IsShadowEnabled = true;
sun.ShadowDistance = 100;                   // How far from the camera shadows are rendered
sun.ShadowCascadeCount = 3;                 // Between 1 and 4

// Keep cascades stable, and fade shadows out smoothly
sun.CascadeFitMode = DirectionalLight.CascadeFitModes.Stable;
sun.ShadowFadeFraction = 0.1f;
sun.CascadeBlendFraction = 0.1f;

// Bias is measured in shadow map texels
sun.ShadowDepthBias = 1;
sun.ShadowNormalBias = 1;

Cela active un soleil projetant des ombres avec trois cascades stables, un fondu progressif entre elles et un léger estompage à la distance d’ombre. Si vous voyez de l’acné, augmentez légèrement les bias. Si les ombres semblent détachées des objets qui les projettent, diminuez-les.

Migration depuis la version précédente

Quelques changements concernent les projets existants :

Essayez-le et donnez-nous votre avis

Prêt à doter vos scènes d’ombres plus stables et plus propres ? Mettez à jour Evergine, ouvrez une scène avec une lumière directionnelle et essayez les nouvelles options.

Nous serions ravis d’avoir votre avis.

José Antonio Collado Araque
Auteur
José Antonio Collado Araque
Ingénieur graphique - Chercheur