Comment créer un effet de parallaxe 2.5d?

8

J'ai une formation décente en graphisme et programmation 3D, mais je suis nouveau dans le développement de jeux. J'explore actuellement différentes possibilités et je veux vraiment créer un jeu RPG. Je pensais à la vue isométrique 2D classique, mais j'aime vraiment à quoi Diablo 2 ressemble et se sent jouer.

Ma question est - comment puis-je obtenir l' effet de parallaxe de Diablo 2 ? Tout a l'air dessiné à la main avec des lumières et des ombres cuites et a l'air génial, mais quand vous vous déplacez, vous remarquez une certaine perspective .

Par exemple, disons que j'ai dessiné une grande salle avec des colonnes dans Photoshop avec une perspective orthographique (style pixel art classique, juste des lignes parallèles). Comment pourrais-je donner un effet de parallaxe à cette scène lorsque le personnage se déplace? Si j'utilise des sprites face à la caméra pour tout, cela semblerait probablement bien au loin, mais ce serait vraiment faux quand un personnage se rapproche d'une colonne (cylindre) par exemple.

Aucune suggestion? Comment Blizzard a-t-il créé l'effet de parallaxe dans Diablo 2?

Voir cette capture d'écran: http://guidesmedia.ign.com/guides/10629/images/act2tombs.jpg

Nikolay Dyankov
la source
C'est un appareil photo de style RTS. google.com/#q=rts+game+camera
LiquidFeline
1
Je ne posais pas de question sur la caméra, c'est une caméra en perspective à un certain angle du sol, c'est évident. Ma question portait sur l'environnement et le fonctionnement de la perspective.
Nikolay Dyankov
1
Pas un doublon, AoE n'a pas d'effet de parallaxe. Veuillez prendre votre temps pour relire toute ma question.
Nikolay Dyankov
1
Veuillez cesser de coller votre nez dans cette question si vous n'avez pas de réponse. Vous ne comprenez clairement pas la question, alors arrêtez de la modifier!
Nikolay Dyankov
2
Qui est l'idiot qui a voté contre cela? Certaines personnes sur ce site n'en ont vraiment aucune idée! Seul quelqu'un qui n'a jamais joué à Diablo II aurait pu rétrograder, je suppose!
Ingénieur

Réponses:

5

C'est une longue réponse, mais en fait, la prémisse de base de la division par caméra-z est très simple: plus quelque chose est loin de vous, plus il apparaît petit. De plus, les petites distances entre deux choses apparaissent.

Positions (lecture non obligatoire si vous utilisez Unity!)

Tout d'abord, vous devez rendre les positions / points en utilisant une perspective correcte.

Les positions se situent sur un plan plat. Vous voulez quelque chose comme l'image de droite ... considérez les coins des carreaux comme des points / positions d'échantillonnage.entrez la description de l'image ici

Voici comment vous abordez la transformation des points:

  • Votre système de coordonnées est le suivant: le positif zcourt dans l'écran, tandis que xcourt de gauche à droite et ydescend. La caméra z est le monde z. C'est le raccourci qui rend cela beaucoup plus facile que d'écrire un moteur 3D complet. Inconvénient? La caméra ne peut pas changer d'orientation (bien qu'elle puisse changer de position).
  • Enregistrez la position 3D initiale de votre caméra. Remettez-le un peu (moins z) de l'origine mondiale.
  • Stockez une collection de points 3D sur le plan xz (donnez-les y=0). Essayez de les centrer sur l'origine du monde x, (0,0,0), soit de négatif nà positif n. Il s'agit de les centrer dans la fenêtre lorsque le rendu commence.
  • Considérez le point décroissant / l'origine du tracé des pixels comme le centre de l'écran.
  • Décidez d'une distance de la caméra à laquelle 1 unité spatiale mondiale = 1 pixel. Cela signifie que si vous déplacez la caméra d'une seule unité spatiale mondiale, tout objet situé à 10 unités se déplacerait de seulement 1 pixel - assez loin! Conservez cette distance en tant que constante K.
  • Maintenant, pour chaque point, effectuez le rendu à une position à l'aide de la formule suivante: screenPosition(x,y) = screenOrigin + (worldPosition(x,y) - cameraPosition(x,y)) / ((worldPosition(z) - cameraPosition(z)) * K)... comme vous pouvez le voir, nous zbasons la position de rendu sur la distance entre le point actuel et la caméra.

  • Jouez avec la position z de la caméra jusqu'à ce que les points soient rendus. Mais ce que vous verrez, c'est que les points s'afficheront tous sur la ligne médiane de l'écran. Nous devons donc y remédier. Essayez K=1vs K=10pour voir la différence.

  • Vous pouvez maintenant déplacer la caméra ypour voir comment votre caméra passe au-dessus et au-dessous du plan des points (c'est-à-dire que les points seront rendus, en perspective correcte, en dessous ou au-dessus de la ligne médiane de l'écran, respectivement, lorsque vous déplacez la caméra de haut en bas). ).

Ce sont des directives très approximatives. Il y aura plusieurs détails de mise en œuvre qui vous appartiendront. La première étape consiste simplement à afficher quelque chose, puis à modifier à partir de là. Un détail qui me vient à l'esprit est que si vous voulez que la caméra ressemble davantage à une vue vers le bas, vous devez déplacer votre origine de rendu vers le haut, plus près du haut de la fenêtre. Un autre détail est que votre distance entre la caméra et le point peut nécessiter un rapport trigonométrique ... Je pense que l'utilisation tanoffre une perspective plus réaliste. Je ne m'en souviens pas clairement, mais vous verrez rapidement si la perspective semble étrange et peut s'adapter en conséquence. Je ne peux pas être plus précis sans réécrire un échantillon.

Déformation et mise à l'échelle par panneau d'affichage (requis)

Maintenant que vous pouvez voir la perspective parmi votre ensemble de positions ponctuelles, et pouvez ajouter, supprimer ou déplacer (comme avec les personnages) des positions à volonté, vous devez également appliquer la perspective aux sprites individuels qui seront enracinés à ces positions.

En D2, cela m'a toujours semblé être une simple fonction de distorsion latérale qui s'applique plus aux panneaux d'affichage qui sont en bas de l'écran, qu'à ceux du haut, et aussi plus à mesure que vous vous éloignez de la ligne médiane en descendant. l'écran.

Il peut également y avoir une mise à l'échelle verticale appliquée aux panneaux d'affichage, par exemple. les arbres raccourcissent par rapport à leur échelle attendue, plus près du bas de l'écran (pour donner l'impression que la caméra regarde vers le bas sur les arbres - j'ai trouvé que les arbres de Tristram étaient le meilleur moyen d'explorer cela en toute sécurité, de retour dans le journée ;) ).

Ce que je ferais c'est:

  1. Tackle la fonction de mise à l'échelle de base basée sur la distance de la caméra au sol à différents points. Vous auriez donc une mise à l'échelle similaire pour chaque ligne de balayage.
  2. Ce n'est qu'après l'avoir fait, que je regarderais ensuite la déformation latérale - d'abord en fonction de la distance de la ligne médiane qui descend l'écran.
  3. Enfin, j'examinerais comment cette déformation latérale est affectée par la distance le long de l'écran (et j'ai l'impression qu'un simple rapport trigonométrique serait au cœur de cela).

Mosaïque correcte en perspective (lecture non requise si vous utilisez Unity!)

Nous espérons que ce qui précède vous donnera des sprites «debout» correctement positionnés et déformés (c'est-à-dire des objets qui sont assis perpendiculairement au plan du sol, tels que des personnages, des arbres, des maisons).

Cependant, vous devez également réfléchir à la manière de déformer correctement et de manière transparente les dalles de sol. Et je pense que vous constaterez que c'est la partie qui, en particulier, nécessitait un GPU sur D2. Je me souviens que sur les systèmes sans GPU, l'option de perspective était désactivée. La raison en serait presque certainement que le GPU peut prendre une surface de texture et lui appliquer une correction de perspective très rapidement, sans aucun problème entre les tuiles, et sans se soucier d'effectuer des transformations non affines dans le code d'application, ce qui implique des calculs matriciels. et peut être un peu coûteux:

entrez la description de l'image ici

J'ai quelques suggestions à vous faire:

  • (Unity) Utilisez une caméra Unity pour fournir le rendu du plan de sol plat et texturé, puis gérez les distorsions du panneau d'affichage séparément en fonction des positions de l'espace d'écran.
  • Faites cette logique (ou même toute la logique de rendu) dans les shaders GPU.
  • N'utilisez pas du tout de carreaux de sol. Au lieu de cela, utilisez simplement des sprites ponctuels - tout comme les personnages eux-mêmes - sur un plan de couleur uniforme (par exemple vert pour l'herbe) pour fournir des détails pour que ce plan ne soit pas terne. Cela augmentera vos coûts de rendu, mais c'est certainement le moyen le plus simple de résoudre ce problème.
Ingénieur
la source
Malheureusement, la seule chose que j'ai comprise était "l'échelle verticale". Je devrais peut-être m'en tenir à la 2D isométrique pour l'instant.
Nikolay Dyankov
Ok, permettez-moi de simplifier ma question, comment feriez-vous un cylindre dessiné 2d en 3D? Quelque chose de dessiné comme ça - media.web.britannica.com/eb-media/49/63049-004-C560D293.gif
Nikolay Dyankov
Il n'y a pas de perspective là-dessus. Vous voulez discuter dans le chat?
Ingénieur
Bien sûr, veuillez démarrer le chat, je ne sais pas comment :)
Nikolay Dyankov
^ haut de page ^
Ingénieur