Un objet deux fois plus proche apparaît deux fois plus gros?

16

Je pensais donc à créer un jeu 2D où vous pouvez également vous déplacer le long de l'axe Z, en changeant dans quelle couche vous vous trouvez. En fonction de la profondeur, je souhaite mettre à l'échelle mes sprites 2D.

Une fois, quelqu'un m'avait montré une démo dans laquelle il avait beaucoup de sprites 2D, et en faisant défiler, il pouvait changer la profondeur de la caméra. Ainsi, lors d'un zoom avant, les objets se rapprochent du joueur et apparaissent plus gros. Ensuite, je me suis demandé combien un objet devrait être plus gros lorsqu'il se rapproche d'une unité. Comment calculeriez-vous cela? Alors le gars m'a dit: Il y a une règle de base que j'utilise: "les objets deux fois plus proches, apparaissent deux fois plus gros."

Maintenant, en le testant moi-même, je sais que la règle ne s'applique pas dans le monde réel;) Mais y a-t-il une constante qui est utilisée dans les calculs du monde réel pour la perspective ou quelque chose? Ou une formule?

Je sais que ce n'est peut-être pas le meilleur endroit pour poser une telle question, mais comme c'est le seul site que j'utilise pour les questions liées au jeu, et que mon contexte est un jeu, j'ai pensé essayer. De plus, je m'attends à ce qu'il y ait cette personne ici qui sait tout sur les perspectives et les matrices 3D ou quelque chose, car cela pourrait être lié aux jeux 3D;)

tl; dr:

"un objet deux fois plus proche, apparaît deux fois plus grand" Ce n'est pas vrai dans le monde réel. Mais quelle constante ou formule est correcte?

Baie
la source
3
Je n'ai aucune idée de la réponse, mais je sais comment je pourrais le découvrir. Prenez des photos de quelque chose. Peut-être un morceau de papier. Prenez-les à différentes distances connues, puis faites des calculs pour calculer la quantité d'image occupée par le morceau de papier et déterminer le rapport par cela. Cela pourrait être une expérience amusante!
SpartanDonut
Je me demande pourquoi personne n'a rien dit sur les logarithmes naturels ...
Chad Harrison
4
Pourquoi n'est-ce pas vrai? je pense que c'est vrai.
Ivan Kuckir
@hydroparadise Qu'est-ce que les logarithmes naturels ont à voir avec cette question?
Nathan Reed
Je suis juste pédant ici, je sais, mais "deux fois plus près" est une expression étrange. Ne devrait-il pas être "à moitié aussi loin"? «Deux fois» est plus grand, mais si quelque chose se rapproche, la distance devient plus petite.
MrVimes

Réponses:

19

En général, cela est vrai, en fonction de votre point de vue et de la direction dans laquelle il s'est déplacé, ainsi que de l'angle de vue.

Exemple de perspectives pour les objets

Notez comment dans la première vue de la caméra, comme le bloc rouge est perpendiculaire à la vue de la caméra, l'objet semble être deux fois plus grand dans un rapport parfait de 1: 2 (notez la flèche pointant qu'il touche le bord de la vue après avoir été déplacé deux fois plus près)

Le second est le bloc de même taille tourné à 45 degrés. Au fur et à mesure de sa rotation, le bord inférieur n'est plus à la même distance de l'appareil photo que le bord supérieur, il ne semble donc PAS être mis à l'échelle correctement à un rapport 1: 2 mais en réalité il est deux fois plus grand (comme il l'est à le même angle sur le bloc bleu le plus éloigné que dans le bloc bleu proche.)

En conclusion, cela signifie en fait que votre ami avait raison et un rapport de 1: 1 ("les objets deux fois plus proches, apparaissent deux fois plus gros.") Pour vos objets est un bon choix.

Tom 'Blue' Piddock
la source
Très bonne réponse! Les images le rendent certainement plus clair. En fait, je me sens vraiment stupide maintenant, puisque j'ai essayé cela avant de poster la question en tenant ma main devant mon visage et en la rapprochant. Et puis j'ai pensé: non, ça ne fait pas deux fois plus gros ... J'aurais dû le mesurer avec plus de précision;) La perspective est drôle! De plus, Ifeel comme j'aurais dû être capable de trouver les photos moi-même;) Mais bonne réponse! Merci!
Berry
@Mason Wheeler - Sorted: P
Tom 'Blue' Piddock
8

Un objet deux fois plus proche apparaît deux fois plus gros. C'est une conséquence du théorème de Thales et c'est vrai dans le monde réel.

On pourrait soutenir que le théorème de Thales est l'outil mathématique de base derrière la projection en perspective et ce qui est connu dans le pipeline graphique (OpenGL ou DirectX) sous le nom de division en perspective . C'est un théorème que vous devez absolument connaître et apprendre à reconnaître quand il peut être utilisé.

sam hocevar
la source
Bonnes références! Je vais certainement vérifier Thales Theorem et essayer de mieux comprendre le pipeline graphique.
Berry
7

En fait, c'est à peu près vrai (si vous déplacez un objet deux fois plus loin, il semble moitié moins grand), mais cela obscurcit la façon dont la taille visuelle des objets devrait changer lorsque les spectateurs se déplacent. Plus précisément, les objets semblent grossir plus rapidement lorsqu'ils sont proches. En effet, le spectateur parcourt la moitié de la distance beaucoup plus rapidement lorsque l'objet est proche, par rapport à lorsque l'objet est plus éloigné. Ou pour le dire autrement, alors que la vitesse du spectateur est constante, la valeur de "la moitié de la distance" change à mesure que la distance à l'objet change.

jhocking
la source
2

Étant donné que vous ne travaillez pas réellement dans l'espace 3D, nous pouvons supposer que les sprites ne tournent jamais (la rotation peut être simulée avec une inclinaison, etc.) de la caméra.

Tout d'abord, vous devez comprendre comment les objets 3D sont rendus. Même si une caméra converge vers un seul point, il existe un plan invisible qui agit comme un écran sur lequel dessiner les objets. La seule chose que vous devez savoir sur l'écran est sa distance par rapport à l'appareil photo.

Voici un diagramme de la façon dont un objet est rendu à un appareil photo à deux distances différentes.

Comme vous vous en doutez, la hauteur de l'objet dépend de la distance de la caméra. MAIS puisque le rendu se produit sur le plan de réforme proche, nous devons calculer la hauteur du sprite à ce point.

Certains calculs de trig de base vous mèneront à la formule suivante:

f(d, v) = v/(v+d)
* Where f is the size ratio to the original sprite aka size factor
    and v is the distance to the near clipping plane (trial and error value)
    and d is the distance from the near clipping plane to the object

EXEMPLE:

Assuming you have a sprite that is 2.5x1.8 units in size and 10 units away 
   from the camera, and that the near clipping plane is 5 units from the camera.

sizeFactor = 5/(5+10) = 0.3

renderHeight = actualHeight * sizeFactor = 1.8 * 0.3 = 0.54
renderWidth  = actualWidth * sizeFactor = 2.5 * 0.3 = 0.75

Je suggérerais de commencer par v=5, puis d'ajuster à partir de là en fonction de son apparence. Je peux lancer un violon ensemble qui vous permet de voir les changements en temps réel.

TL; DR

The change in height or width should be multiplied by the following factor:

sizeFactor = v/(v+d)

Where v = Some number greater than 0 that never changes (try 1 thru 5)
  and d = the distance from the camera

So an object that is 2.5 units tall would be rendered at 2.5*sizeFactor units tall.

EDIT: Lorsque vous dites se déplacer le long de l'axe z, je suppose que vous voudrez une vue en perspective (comme la plupart des jeux 3D; tireurs, etc.) Le calcul pour calculer la taille de l'objet en fonction de la distance dépendra également de l'emplacement dans le cadre, semblable à la vision périphérique. Au lieu de cela, je l'essayerais avec mes mathématiques qui sont une vue orthographique (pensez à Mario, Angry Birds, Super Smash Bros, etc.). Je ne connais pas l'apparence que vous essayez d'atteindre, mais tant que cela semble réel, les joueurs ne le sauront jamais!

DEMO!

Jim Buck
la source
Oui, je vise en fait une vue orthographique. Le jeu auquel j'emprunte mon inspiration actuelle est Rayman Origins. Dans certaines sections du jeu, vous pouvez sauter sur des fleurs, puis rebondir sur une autre couche avec une profondeur différente. La caméra effectue ensuite un zoom avant ou arrière sur cette profondeur. Axamples peut être vu dans cette vidéo , à 4:50 et 5:00.
Berry
De plus, bonne réponse! Mais comme une simple confirmation que la règle "deux fois plus proche, deux fois plus grande" s'applique aurait été suffisant, j'ai choisi la réponse de Blue comme la meilleure.
Berry
Merci et bonne chance avec votre jeu! Mais je tiens à préciser aux autres que "deux fois plus près, deux fois plus gros" fonctionnera très bien si tout est très proche de la caméra. À mesure que les choses s'éloignent, le changement de taille perçu diminue. Par exemple, regardez de près votre pouce, puis étendez votre bras et regardez-le. La taille de votre pouce semble considérablement plus petite. Après cela, regardez quelque chose de loin. Faites un pas en arrière (à peu près la même que votre longueur de bras). Remarquez comment la taille a à peine changé? Si un jeu a un long champ de vision, utiliser un peu de maths ira très loin.
Jim Buck
EDIT: J'ai fait une erreur dans mon commentaire précédent. "Deux fois plus près, deux fois plus gros" est correct lorsque les éléments restent assez proches les uns des autres par rapport à leur distance par rapport à la caméra.
Jim Buck
Voici une démo rapide que j'ai mise en place, utilisez la souris pour vous déplacer et la molette pour changer la profondeur.
Jim Buck
0

Cela n'a pas été couvert et j'ai pensé que cela pourrait être bénéfique: il convient de noter que lorsque vous divisez la moitié de la distance, doubler la taille dans les dimensions X et Y quadruplera la surface totale du sprite. Ceci est dû au fait:

Area = X * Y

Après avoir zoomé:

NewArea = (x*2) * (y*2)

Cela peut vous donner l'impression que l'effet de zoom se produit rapidement ou est trop intense. Vous pouvez ajuster le facteur en remplaçant 2 dans la formule ci-dessus par une valeur flottante comme 1,5 ou 1,33 à la place.

Alternativement, ce que j'ai fait est de stocker la profondeur de la caméra (distance) à vos tuiles dans une valeur d'octet avec la traduction de la caméra (X et Y) puis de calculer la taille de tuile projetée ainsi:

XTileSize = (255 / CameraZ) * DefaultTileWidth
YTileSize = (255 / CameraZ) * DefaultTileHeight

Notez que cela CameraZdoit être strictement compris entre 1 et 255 et que cette restriction peut être un avantage ou un fléau pour vous à l'avenir.

Mark H.
la source