Les ombres en temps réel

Oh cool, les ombres en temps réel. J'ai attendu si longtemps pour elles, et maintenant je vais les utiliser pour absolument tout dans mon jeu. Chaque feuille d'un arbre va jeter son ombre sur le terrain. Cela va rendre tellement bien! Absolument tout aura sa propre ombre, comme dans la réalité!

Si c'est ce que vous êtes en train de penser, je vais vous décevoir. C'est tout simplement irrealisable. Aucun PC ne sera à même de faire tourner cela de façon fluide. Quoi qu'il en soit, les stencils d'ombres en temps-réel d'Ultimate 3D sont une fonctionnalité vraiment cool. Des scènes sans ombres n'ont pas l'air authentiques. Les choses doivent être ombrées pour avoir l'air réaliste. Les ombres aident l'oeil humain à comprendre la structure tridimensionnelle des images bidimensionnelles vues à l'écran. Dans les jeux choquants, les ombres peuvent contribuer grandement à l'effet dramatique des évènements. Ils peuvent vous donner une idée des choses que l'on ne voit pas directement. De cette façon, une ombre peut effrayer les gens qui jouent au jeu, du moins... si c'est bien fait.

Ce n'est pas tout à fait faux de voir la projection des ombres en temps réel comme une méthode pour améliorer le potentiel dramatique de votre jeu, mais cela nécessite d'être utilisé avec prudence pour obtenir une bonne performance. Dans ce contexte la leçon la plus importante est que les ombres en temps réel doivent être utilisées uniquement pour les objets et les sources de lumières non statiques. Pour des ombres statiques vous pouvez utiliser des techniques telles que le light mapping, qui peut être réalisée à l'aide des fonctions de multi texturage, qui sont beaucoup plus économiques.

Ultimate 3D utilise l'accélération matérielle des stencils d'ombre. Vous n'avez pas besoin de savoir comment ces ombres fonctionnent, mais vous devriez connaître les différents avantages et désavantages de cette technique. Les avantages sont principalement l'extrême qualité des ombres résultantes, qui sont très précises pour chaque pixel, une capacité matérielle faible requise (pas de support des pixel shader n'est requise), la fiabilité, la combination sans soucis avec les effets de shaders tels que le per pixel lighting et étant donné que les ombres en temps réel sont complètement accélérées matériellement, elles ne stressent pas le CPU plus que ça. Les désavantages sont que vos modèles doivent respecter certaines conditions, pour être des moules d'ombres valides, elles stressent vraiment le GPU; des ombres douces ne sont pas réalisables.

Utilisation des ombres en temps réel

L'utilisation d'ombres en temps réel dans Ultimate 3D est très facile. La première chose que vous devez faire est de vérifier qu'elles sont prises en charge. Si c'est le cas, vous pouvez activer le moulage d'ombre (shadow casting) pour des sources de lumière particulières, définir un objet de modèle particulier en tant que moule d'ombre et définir des objets de modèles, des objets de terrain ou des objets primitifs en tant que receveurs d'ombre. La première chose que vous avez à faire pour pouvoir utiliser les ombres, est de définir global.u3d_z_buffer_format à 32 dans le script Ultimate3DOptions(). Pour plus d'informations sur la signification de cette variable, référez vous au chapitre sur les options d'Ultimate 3D. La raison pour laquelle il ne peut y avoir d'ombres sans un buffer z de 32 bits est que 8 bits du buffer z est utilisé en tant que buffer de stencil, qui est requis pour calculer les ombres. Si le PC que vous êtes en train d'utiliser est assez récent et si le buffer z a le bon format, la fonction GetShadowSupport() retournera true, cela signifie que vous pouvez utiliser les ombres en temps réel. Autrement vous ne pourrez pas, toutes les fonctions relatives aux ombres ne feront rien dans ce cas.

Maintenant que vous êtes sûr que les ombres sont supportées, vous pouvez appeller la fonction suivante pour activer les ombres pour une source de lumière particulière.

Cette fonction active ou désactive les ombres pour l'objet de source de lumière par lequel elle est appellée. Cela doit être appellé après LightDirectional(), LightPoint() ou LightSpot().

SwitchShadows(
Enable
)

Enable
Si vous passez true pour ce paramètre, Ultimate 3D activera les ombres pour cette source de lumière, autrement il les désactivera.

Ensuite vous pouvez définir quel objet de modèle projette des ombres pour quelles sources de lumière.

Cette fonction active ou désactive la projection d'ombre pour l'objet de modèle par lequel il est appellé. Si le modèle utilise le vertex skinning, il ne doit pas utiliser plus de 28 os, étant donné que tout os supplémentaire serait transformé incorrectement. Ce qui explique ce comportement est le nombre limité de constantes de vertex shader disponible dans la version de Direct3D utilisée.

SwitchShadowCasting(
LightSourceID,
Enable
)

LightSourceID
L'id Game Maker de l'objet de source de lumière pour lequel ce modèle doit projeter des ombres.

Enable
Si la projection d'ombre doit être activée ou désactivée.

Finalement vous devriez être en mesure de définir quels objets peuvent recevoir les ombres. C'est tout aussi facile.

Cette fonction active ou désactive la réception d'ombres projetées par une source de lumière particulière. Cela l'applique à l'objet de terrain, à l'objet de modèle ou à l'objet primitif par lequel elle est appellée.

SwitchShadowReceiving(
LightSourceID,
Enable
)

LightSourceID
La source de lumière que vous voulez activer ou désactiver pour la réception des ombres.

Enable
Si vous passez true, l'objet recevra des ombres de la source de lumière donnée, sinon non. Notez que les terrains ne recevront aucune ombre tant qu'ils n'auront pas appellé CalculateTerrainLightMap(...) au moins une fois après avoir appellé cette fonction.

Maintenant vous pouvez activer les ombres pour les sources de lumières, la projection d'ombre pour les modèles, et la réception d'ombres pour différents types d'objets. C'est tout ce dont vous avez besoin pour utiliser les ombres avec Ultimate 3D. Cependant, le résultat que vous obtiendrez avec ces connaissances sera souvent pauvre dans la majorité des cas. Cela s'explique par le fait que les stencils d'ombres requièrent une géométrie spécifique pour fonctionner correctement. La géométrie ne doit avoir aucun trou et devrait avoir des triangles pour représenter les bords, à moins qu'elle ne dispose d'un nombre élevé de triangles. Cela aura l'air réaliste uniquement si cette géométrie est disponible. Par chance, Ultimate 3D possède une fonction permettant d'altérer la géométrie des modèles de sorte qu'ils respectent ces conditions. Comme d'habitude vous n'avez pas beaucoup de travail à faire, parce qu'Ultimate 3D fait tout automatiquement. Vous avez juste à lui demander ce service.

Cette fonction crée la géométrie optimisée pour la projection d'ombres de l'objet de modèle qui l'appelle. Elle doit être appellée après LoadMesh() (et après l'appel à CreateLODChain(...) si un appel y est fait). 

CreateShadowOptimizedGeometry(
LODIndex,
CreateConnectionPatches
)

LODIndex
Grâce à ce paramètre, vous pouvez définir pour quel niveau de détail vous souhaitez créer la géométrie optimisée pour les ombres. Souvent il est logique d'utiliser des niveaux de détail faibles pour la projection d'ombre puisque les ombres n'ont pas besoin d'être très précises. Le plus haut niveau de détail avec une géométrie optimisée sera utilisée pour la projection d'ombre. Pour ce paramètre, 0 se réfère au plus haut niveau de détail (le modèle inchangé), 1 équivaut au niveau de détail plus bas suivant, et ainsi de suite.

CreateConnectionPatches
Si vous passez true pour ce paramètre, cette fonction créera la géométrie qui donnera une ombre extrêmement précise, mais le prix à payer est cher. Cela nécessite la création de deux triangles pour chaque bord du modèle. Si vous passez false ces patchs de connexion ne seront pas créés, cela correspond à une meilleure performance mais à des ombres moins détaillées.

Malheureusement, même cette fonction ne parvient pas à optimiser correctement la géométrie dans certains cas. Si cela arrive, vous obtiendrez des résultats extrêmement laids. L'ombre ne s'arrêtera pas derrière le modèle. Au contraire, elle ira à l'infini en longues bandes noires. Donc, quelles sont les conditions que le modèle doit respecter pour éviter cet effet? C'est très simple à faire, mais un peu difficile à comprendre. Tous les bords du modèle ne doivent être partagés par pas plus de deux triangles. Voici une petite illustration pour clarifier cela.

ShadowThreeSidedEdge.png

La géométrie sur la gauche pourrait être optimisée parfaitement, parce qu'elle est faite de bords simples (bleu) et de bords doubles (vert) uniquement. Mais le morceau de géométrie sur la droite a deux bords qui sont partagés par trois triangles (rouge). Pour cette raison le mécanisme utilisé par Ultimate 3D pour remplir les trous dans la géométrie des modèles ne peut trouver de meilleure solution et de fait, la fonction ne retournera pas une géométrie optimisée pour l'ombre valide dans ce cas. C'est pourquoi aucun des modèles projetants de l'ombre dans votre scène ne peut avoir des triangles configurés ainsi. C'est à vous de vérifier cela. Ultimate 3D ne peut le faire pour vous, parce qu'un procédé mathématique qui donne une solution unique ne peut être trouvé dans cette situation. Mais c'est peu coûteux pour des ombres en temps réel extrêmement réalistes, n'est-ce pas ;) ?

Shadow checklist

Récemment des problèmes avec le système de projection d'ombre ont été rapportés assez souvent sur la Communauté Ultimate 3D. Dans la majorité des cas, c'était le résultat d'une mauvaise utilisation. Il reste cependant qu'il est difficile de déboguer les problèmes liés aux ombres, parce que si un seul élément est faux le système d'ombres ne fonctionnera pas complètement et il n'y a aucun moyen de trouver si c'est la source de lumière, le projeteur d'ombre ou celui qui la reçoit qui ne fonctionne pas. Pour cette raison, voici une checklist avec laquelle vous pouvez travailler si vos ombres ne fonctionne pas. Elle explique toutes les erreurs communes et précise comment les corriger. Lisez ceci avant de poster n'importe quelle question liée au non fonctionnement des stencils d'ombre.

L'erreur la plus commune est que SwitchShadowCasting(...) et SwitchShadowReceiving(...) sont appellés avant que les sources de lumière n'aient étés créés et initialisées. Dans ce cas, le paramètre LightSourceID sera invalide et cela fera que la projection d'ombre ou la réception d'ombre ne fonctionnera pas. La manière la plus sûre d'éviter ce problème est de placer ces appels dans le step event des objets. Elles ne font aucun calcul intensif, donc cela ne sera pas mauvais pour les performances.

Une autre erreur qui a été faite à plusieurs reprises est que CreateShadowOptimizedGeometry(...) n'a pas été appellé pour l'objet de modèle projetant les ombres. Vous devriez toujours appeller cette fonction pour la projection d'ombre. Sans elle, vous obtiendrez des ombres fausses, imprecises ou carrément pas d'ombres du tout dans la plupart des cas. La seule exception ici est les modèles avec un très haut nombre de triangles. Pour eux, cela devrait fonctionner sans appel à cette fonction, mais si les ombres ne fonctionnent pas et que vous n'utilisez pas CreateShadowOptimizedGeometry(...), vous savez ce qu'il vous reste à faire immédiatement.  

Si vous avez des problèmes avec l'utilisation les objets de terrain comme receveurs d'ombres, vous devriez vérifier la valeur de retour de GetSimultaneousTextureCount(...). Si c'est inférieur à trois, votre système ne supporte pas le light mapping des terrains en combinaison avec le texture splatting. Et sans light mapping, vous ne pouvez pas obtenir d'ombres. Une autre chose que vous devriez noter: les terrains avec une light map personnalisée ne peuvent recevoir d'ombres.

Si les ombres fonctionnent, mais que vous obtenez d'étranges bandes d'ombres, qui vont jusqu'à l'infini, lisez l'explication des bords avec trois faces accollés ci-cessus. C'est souvent la cause de ce problème. Une autre cause possible de ce problème est que vous n'appellez pas CreateShadowOptimizedGeometry(...) correctement.

Une dernière cause possible de non-fonctionnement des ombres est une proportion inappropriée entre camera.min_range et camera.max_range. Si le résultat de camera.max_range/camera.min_range est très élevé, il peut arriver que les erreurs d'arrondis font aller le champ de vision à l'infini. Etant donné que le champ de vision joue un role important pour les projeteurs d'ombres, la projection d'ombres ne fonctionnera pas. Pour régler ce problème, vous devez simplement augmenter camera.min_range et/ou diminuer camera.max_range. 



© Christoph Peters. Certains droits réservés. (Traduction FR 04/2008, Franck Vernel / Damien Buhl).

Creative Commons License XHTML 1.0 Transitional