Projection d'ombres en temps réel dans un jeu isométrique 2D


15

J'écris un petit moteur isométrique 2d en C ++ et j'essaie d'implémenter le casting d'ombres en temps réel. J'ai suivi une approche simple décrite sur cette page et voici le résultat (la lumière est située à la même position que le cube jaune):

entrez la description de l'image ici

Le résultat est très agréable mais il manque des ombres sur les murs et sur le dessus des cubes. Voici un exemple de ce à quoi cela devrait ressembler (j'ai dessiné les ombres attendues en vert):

entrez la description de l'image ici

Tous les cubes dessinés sont simplement constitués de 3 quads 2D situés à une position XY et avec une profondeur Z (z = x + y). J'utilise OpenGL avec une matrice orthographique (glOrtho). Les ombres sont dessinées à l'aide du tampon de gabarit.

Je suis à la recherche de ressources ou de solutions qui pourraient m'aider à terminer cette implémentation du casting d'ombres.

Merci beaucoup!


5
Votre lien vers «cette page» pointe vers une image et non une page. De plus, je devine juste ici, mais il pourrait être plus facile de résoudre ce problème en 3D et de simplement projeter la caméra de manière isométrique.
Tetrad

Oups, vous avez raison, j'ai corrigé le lien. Ce serait certainement plus facile avec une projection 3D mais la 2D a aussi ses avantages et je suis sûr qu'il existe des solutions pour l'implémenter en 2D.
XPac27

Réponses:


6

Pour le toit et les murs, vous pouvez essayer de déterminer les intersections entre vos segments de mur et les zones d'ombres générées. Vous avez besoin d'un rendu en deux passes de vos ombres. Le premier fera ce que vous faites aujourd'hui (en mémoire). Le deuxième passage calculera les intersections du toit et du mur. La dernière étape est un vrai rendu. DeadMG a tort, vous pouvez le faire.

Remarque: pour le toit, vous devez couper la zone d'ombre et la zone du toit.


Merci pour les bons conseils! Si peut être en mesure d'optimiser ce deuxième passage en vérifiant quels murs doivent être calculés en utilisant le produit scalaire de leur segment par rapport à ceux des segments d'ombres. Je vais essayer et poster si cela fonctionne.
XPac27

Cela fait un moment mais je l'ai finalement fait fonctionner grâce à vos suggestions! Je n'avais besoin que de 2 méthodes de géométrie (une pour savoir si un point se trouve dans un polygone et une pour obtenir l'intersection de deux segments). J'ai encore besoin de manipuler des toits mais ça a l'air facile à savoir. Vous pouvez regarder le résultat sur cette vidéo et regarder le code source ici (je viens de travailler 1 jour dessus pour qu'il soit possible de l'optimiser davantage).
XPac27

@ XPac27 c'est incroyable. Merci d'avoir partagé.
ashes999

0

Fondamentalement, ce que vous recherchez ne peut pas être fait. Vous voulez prendre un tas d'objets 2D et les faire projeter des ombres comme s'il s'agissait d'objets 3D. Si vous voulez avoir des ombres 3D complètes, vous devez avoir des objets 3D.


1
Mais ce n'est pas un casting d'ombres 3D comme dans la question. Tout mur bloque complètement la ligne de vue dans cette direction, vous ne pouvez pas avoir d'objets de hauteur variable.
yuriks

0

La solution décrite n'est pas entièrement en 3D car il n'a pas besoin d'une solution complète en 3D. Cela ressemblera, mais ce n'est pas le cas. La création d'une ombre portée doit être considérée comme une intersection entre le volume. Ce dont il a besoin est moins compliqué. Rappelez-vous (si vous en avez) des châtiments et des châtiments comme le moteur de rendu. Tous les traitements ont été effectués en deux dimensions.


0

Étant donné que vous voulez que ce jeu soit petit, pourquoi ne pas simplement dire que l'implémentation actuelle de l'ombre est assez bonne?

J'avoue que je n'ai pas vu cela en action, c'est-à-dire que je n'ai pas vu à quel point les imperfections des ombres seront dérangeantes ou non dérangeantes lorsque ce jeu fonctionnera en direct avec des objets dynamiques et des sources de lumière dynamiques mais à en juger par vos images, je '' Je suis très tenté de dire "c'est assez bien, concentrez-vous maintenant sur la fin du jeu". Si l'implémentation actuelle se trouve être petite et s'exécuter rapidement et résoudre ce que vous percevez comme des problèmes rendra le code gros et lent, je pense que vous feriez mieux de ne pas vous soucier de ces ombres.

Je sais, je sais, suggérer "n'essayez pas de résoudre le problème" comme solution à un problème pourrait être une mauvaise pratique. Pourtant, je veux honnêtement dire que c'est vraiment bien comme si vous voulez une petite empreinte pour votre code.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.