PDA

Voir la version complète : Ombre et lumières en 3D isométrique?



Galdred
24/05/2015, 13h16
Coucou,
je développe un jeu indépendant en 3D isométrique :
http://i.imgur.com/jaOZS9O.png, (j'ai d'ailleurs ouvert un thread sur le forum, mais il a vite été enterré :http://forum.canardpc.com/threads/98005-A-venir-La-guerre-du-Zodiac-un-RPG-tactique-med-fan-avec-de-la-strat%C3%A9gie-dedans )
Comme vous pouvez le voir, cela manque cruellement d'ombres (ça donne l'impression que les personnages flottent), mais le problème des ombres en 3D iso est assez compliqué (vu qu'en fait, on est en 2D...).
Quelles techniques (ou lectures) pourriez vous me recommander?

A priori, ce que je voudrais faire :
Il y aurait une lumière diffuse + une lumière directionnelle ("soleil" en extérieur, et en intérieur, aucune justification sauf que c'est plus facile pour les ombres), et des sources de lumière ponctuelles (brasiers, chandelles...).
Je pensais faire en sorte que :
- Seuls les murs occultent toutes les sources de lumière (donc shadowmaps précalculées), et on calculera la quantité de lumière reçue partout à partir de la somme des intensités lumineuses de chaque source (qui dépendra de la distance et l'occultation). Cela nécessitera de traiter les murs comme des objets 3D à priori (base + heightmap), mais ils ont une hauteur fixe, donc c'est peu compliqué.
- Les persos et autres sprites (mobilier, arbres, ...) projetteront une ombre (sous forme de sprite obtenu par une transformation du sprite initial correspondant à sa projection sur le sol), uniquement dans la direction de la lumière directionnelle (donc la direction lumineuse est fixée pour chaque niveau, et on "colle" le sprite correspondant à cette direction).

Mais la projection des ombres de persos sur les murs poserait problème : comment faire (sans trop d'opérations GPU compliquées) pour qu'on n'ait pas l'impression que le mur est dans la même direction que le sol? ou que le mur n'est pas affecté par l'ombre des personnages ou des arbres.

Une autre méthode serait de créer des heightmaps pour les sprites également, et de faire les calculs d'occulsion complets, mais il me semble compliqué de le faire à partir de sprites 2D complexes (personnages).

Vous connaissez des livres ou articles détaillant ce genre de techniques (utilisées dans Diablo 2, et Nox il me semble, et c'est à peu près tout)?

Louck
24/05/2015, 14h20
Je ne me connais pas trop sur la gestion des ombres. Mais tu peux déjà commencer par quelque chose de très simple avec une ombre statique dans une seule direction, même dans une pièce éclairée.

De mémoire dans Diablo 2, tous les éléments ont une ombre statique. Même les torches :).

http://www.google.fr/url?source=imglanding&ct=img&q=http://classic.battle.net/images/battle/diablo2exp/images/skills/psychichammer02.jpg&sa=X&ei=dbNhVePSDomAU6v1gOgJ&ved=0CAkQ8wc&usg=AFQjCNH_nV5KKy580lYLRpMubNuySzGV9A

Une ombre statique noir avec transparence, c'est déjà pas mal.


Si tu veux gérer l'ombre d'une entité selon plusieurs sources, c'est un tout autre défi. Je ne sais pas si c'est faisable avec les shaders.

Roscopolo
24/05/2015, 16h09
Les techniques pour faire des ombres en 2D :

a) Utiliser des modèles 3D non-texturés et simplifiés pour le rendu des ombres, puis intégrer le résultat aux images 2D. C'est le seul moyen d'avoir des ombres précises et jolies, avec projections sur les murs et compagnie. Ça fait aussi ton éclairage et l'auto-ombrage.

b) Une ombre à la diablo, où tu présumes que tout le décor est à plat (et tant pis pour les murs) et où la lumière vient toujours de la même direction. Tu peux faire une variante où chaque élément de décor précise son inclinaison pour les murs droits et inclinés (et tant pis pour les coins), où alors une variante où tu supportes seulement les éléments horizontaux et verticaux (et tant pis pour les murs inclinés), ou combiner tout çà en divisant les éléments de décors en plus petits, ou supporter des rotations de la direction de la source lumineuse (en acceptant des anomalies). Mais franchement chercher à raffiner c'est beaucoup de boulot, donc autant prendre la solution (a), surtout qu'il n'y a plus de problème de performances comme c'était le cas il y a quinze ans.

c) Une ombre blob : une simple ellipse sous les pieds du perso. C'est simple mais diablement efficace pour enrichir la scène (l'essentiel pour l’œil humain ce sont les "ombres de contact" entre les pieds et le sol. Si ces ombres sont absentes nous le voyons tout de suite). Pour le décor tu peux simplement le rendre une première fois en noir et décalé de quelques pixels afin d'obtenir une ombre de contact.

d) Calculs d'illumination par pixel pour ou case, et on module la couleur de tout ce qui se trouve sur ce pixel/case. Ca ne donne pas d'ombres portées ni de contact mais ça donne des pièces sombres et des pièces lumineuses.

e) Auto-ombrage et normales : même techniques qu'en 3D, il existe des solutions clé-en-main comme Sprite Lamp pour deviner les textures appropriées à partir de l'image 2D. Mais ça ne gère pas les ombres portées ni de contact. En revanche ça donne un beau rendu pour l'illumination dynamique.



Mon conseil ? Sois tu fais simple ou très simple (c voire b rudimentaire), éventuellement enrichi par d ou e, sois tu optes carrément pour la 3D superposée à la 2D. Pas la peine de se casser la tête avec une solution 2D trop sophistiquée qui sera vite complexe mais toujours décevante.

Note que si les personnages se contentent fort bien d'ombres de contact, les décors sont mieux rendus avec des ombres portées (a ou b). Malheureusement j'ai l'impression que ta scène est générée automatiquement, donc tu ne peux pas avoir recours à des ombres faîtes à la main pour le décor ? Peut-être peux-tu créer un sprite d'ombres par sprite de décor ?

Galdred
25/05/2015, 10h09
Merci pour les éclairages :)

Le niveau a été construit en utilisant un tileset. Je pourrais donc très bien donner un sprite d'ombre à chaque tile, et ne rien changer à la construction du niveau, mais cela demanderait du travail à mes artistes (ce sont des freelances), donc je vais plutôt essayer de faire cela moi même: Je compte en effet faire des calcules d'illumination, mais les sprites "complexes" (tout ce qui ne se résume pas à un ou quelques pavés) risquent d'être un peu compliqués à gérer, si bien que je comptais ne prendre en compte que les murs pour l’occultation (c'est surtout en intérieur que ce serait important, et il n'y aura pas d'arbres, donc ce n'est pas trop grave). Du coup, je peux utiliser la solution a)/d) pour les murs (avec en gros, une "carte de niveaux" indiquant l'élévation minimale et maximale de l'obstacle en chaque point)

Pour les ombres des persos, et autre sprites, c'est plus compliqué. Comme les personnages ne sont pas générés à partir de modèles 3D, la solution a) de leur créer un squelette 3D sipmlifié me semble impraticable, donc en effet, je pourrais faire b) (on génère l'ombre par une projection du sprite qui serait passé en noir), ou c)
Je pense que b) pourrait se faire juste en trouvant les bons paramètres de transormation, donc ce serait ma solution favorite :
Si je pars du principe que la lumière est toujours dans la direction du regard, je peux peut être avoir des ombres "réalistes" avec des personnages plats.

Je verrai par la suite si je prends en compte les principales inclinaisons (2 orientations de murs), ou juste les sols.

BourrinDesBois
26/05/2015, 16h10
b ) me parait assez simple au final.

Galdred
27/05/2015, 02h51
Donc voilà le résultat du B pour les persos :
http://i.imgur.com/FTJ5fgu.png
Et animée :

http://gfycat.com/ZestyDangerousIchthyostega

BourrinDesBois
27/05/2015, 15h57
Pas mal non? Ça suffit largement pour ce genre de production je pense.

schouffy
27/05/2015, 16h02
C'est très propre oui

rotoclap
28/05/2015, 10h41
Franchement ça rend pas mal. En revanche, si on regarde les pierres autour du trou, on dirait que leur lumière vient légèrement plus de la gauche, non ?

Galdred
28/05/2015, 22h06
effectivement, les ombres devraient être plus proches de 45°. Je vais faire des tests et changer les paramètres en les inclinant un peu plus.