Que fait la carte graphique avec le quatrième élément d'un vecteur comme position finale?

25

De cette question, il semble que vous souhaitiez un vecteur de position à quatre éléments, car il est plus simple de modifier sa position avec une multiplication matricielle.

À lui seul, cela impliquerait que le quatrième élément devrait simplement être ignoré lorsque l'on le considère comme une représentation d'un point 3D (en supposant qu'aucune transformation), mais je sais que ce n'est pas vrai, comme lorsque je fournis un vecteur4 au GPU, si le quatrième l'élément n'est pas un, il n'est pas rendu - pourquoi?

Quelle est la signification du quatrième élément, une fois qu'il est dans le rasterizer?

EDIT : Lors de l'examen, cette question était quelque peu mal formulée; il serait plus exact que le deuxième paragraphe dise: "si la valeur du quatrième élément n'est pas dans une certaine plage, elle n'est pas rendue" correctement "/" comme prévu "".

sebf
la source
un vecteur4 avec des coordonnées (x, y, z, 0,5) ne donne-t-il pas les mêmes résultats que le vecteur4 avec des coordonnées (2x, 2y, 2z, 1)?
FxIII
@FxIII, je n'ai pas pu reproduire cela exactement mais vous avez raison, c'était une déclaration de couverture incorrecte faite dans mon message d'origine, après quelques essais, je l'ai mis à jour.
sebf

Réponses:

23

Le quatrième composant est une astuce pour suivre la projection en perspective. Lorsque vous faites une projection en perspective, vous voulez diviser par z: x '= x / z, y' = y / z, mais ce n'est pas une opération qui peut être implémentée par une matrice 3x3 fonctionnant sur un vecteur de x, y, z. L'astuce qui est devenue standard pour ce faire consiste à ajouter une quatrième coordonnée, w, et à déclarer que x, y, z seront toujours divisés par w après l'application de toutes les transformations et avant la pixellisation.

La projection en perspective est alors accomplie en ayant une matrice qui déplace z en w, de sorte que vous finissez par diviser par z. Mais cela vous donne également la possibilité de laisser w = 1.0 si vous ne voulez pas faire de division; par exemple, si vous voulez juste une projection parallèle, ou une rotation ou autre.

La possibilité de coder des positions comme w = 1, des directions comme w = 0 et d'utiliser la quatrième ligne / colonne d'une matrice pour la traduction est un avantage secondaire intéressant, mais ce n'est pas la principale raison de l'ajout de w. On pourrait utiliser des transformations affines (une matrice 3x3 plus un vecteur de traduction à 3 composants) pour accomplir la traduction sans aucun w en vue. (Il faudrait garder une trace de ce qu'est une position et quelle est une direction, et appliquer différentes fonctions de transformation à chacune; c'est un peu gênant, mais pas vraiment un gros problème.)

(BTW, mathématiquement, les vecteurs augmentés de w sont connus comme des coordonnées homogènes , et ils vivent dans un endroit appelé espace projectif . Cependant, vous n'avez pas besoin de comprendre les mathématiques supérieures pour faire des graphiques 3D.)

Nathan Reed
la source
Encore une fois, il est légèrement incorrect de parler de vecteurs et de points en ces termes car il y a un isomorphisme entre les points et les vecteurs (le point et le vecteur qui déplacent l'origine vers ce point sont la même entité). Il serait plus correct de parler de points / vecteurs (w! = 0) et de directions (projectives) (w = 0). Quoi qu'il en soit, l'utilisation abusive du terme "vecteur" est une norme assez consolidée dans le langage des bibliothèques 3D.
FxIII
@FxIII: corrigé. Il était déroutant d'utiliser "vecteur" dans le sens mathématique standard et comme synonyme de "direction" dans le même article.
Nicol Bolas
@FxIII et Nicol Bolas: Je ne suis pas d'accord. Vous encodez vraiment des vecteurs avec w = 0 - y compris les vecteurs qui représentent juste une direction et les vecteurs réels où la longueur est importante. Par exemple, vous pouvez transformer le vecteur de vitesse angulaire (direction = axe de rotation, longueur = vitesse) d'un objet entre l'espace local et l'espace mondial à l'aide de la matrice de l'objet. Vous ne voulez pas que la vitesse angulaire y ajoute la traduction de l'objet; vous voulez seulement qu'il soit tourné. Vous définissez donc w = 0. Je ne vois pas le problème?
Nathan Reed,
@NathanReed J'espère que mon article aide à clarifier le point, de toute façon une grande partie de mon point concerne les définitions et l'utilisation abusive du terme vecteur plus la primauté de l'algèbre linéaire sur la terminologie standard de la bibliothèque 3D. Bien sûr, les deux sont discutables, car chaque définition et revendication de primauté l'est
FxIII
@Nathan, je peux maintenant voir clairement le but du quatrième élément, et comment les informations qu'il contient sont utilisées par le rasterizer. Merci beaucoup!
sebf
10

Pour répondre au commentaire approprié de Natan, j'ai fait quelques réflexions qui peuvent être utiles pour comprendre ce qui se passe réellement lorsque vous utilisez des vecteurs dans l'espace affine pour représenter des vecteurs 3D dans l'espace euclidien standard.

D'abord, j'appellerai vecteur ce qui a des coordonnées, donc un point et un vecteur sont la même entité; vous pouvez voir un vecteur comme une différence de deux points: V = B - A ; V déplace A dans B car A + V = A + B - A = B . Mettez A = 0 (l'origine) et vous obtiendrez que V = B - 0 = B : le point B et le vecteur qui se déplace 0à B sont la même chose.

J'appellerai "vecteur" - dans le sens utilisé dans la majorité des bibliothèques 3D - lorsqu'un vecteur de l'espace affine a w = 0.

Les matrices sont utilisées car elles vous permettent de représenter une fonction linéaire sous une forme compacte / élégante / efficace, mais les fonctions linéaires ont l'inconvénient majeur de ne pas pouvoir transformer l'origine: F ( 0 ) = 0 si F veut être linéaire ( entre autres choses telles que F (λ X ) = λF ( X ) et F ( A + B ) = F ( A ) + F ( B ))

Cela signifie que vous ne pouvez pas construire une matrice qui effectue une traduction car vous ne déplacerez jamais le vecteur 0 . Ici entre en jeu l' Espace Affine . L'espace affine ajoute une dimension à l'espace euclidien pour que les traslantions puissent être effectuées avec des échelles et des rotations.

L'Espace Affine est un espace projectif dans le sens où vous pouvez construire une relation d'équivalence entre les vecteurs Affine et Euclidienne afin de pouvoir les confondre (comme nous l'avons fait avec les poins et les vecteurs). Tous les vecteurs affines qui se projettent à l'origine avec la même direction peuvent être vus comme le même vecteur euclidien.

Cela signifie que tous les vecteurs qui ont les mêmes proportions dans les coordonnées peuvent être considérés comme équivalents:

Mathématiquement:

équivalence

c'est-à-dire que chaque vecteur affine peut être réduit à une version canon où w = 1 (nous choisissons parmi chaque vecteur équivalent celui que nous aimons le mieux).

Visuellement (euclidienne 2D - affine 3D):

équivalence visuelle

d'où la moyenne de l' espace "projectif" ; Vous remarquerez qu'ici l'espace euclidien est 2D (la région cyan)

Il existe un ensemble particulier de vecteurs affines qui ne peuvent pas être mis dans leur version canonique (avec facilité) celui qui se trouve sur le (hyper) plan w = 0.

On peut le montrer visuellement:

entrez la description de l'image ici

ce que vous (devriez) voir, c'est que tandis que w -> 0, le vecteur projeté dans l'espace euclidien va à l'infini mais à l'infini dans une direction particulière .

Il est maintenant clair que l'addition de deux vecteurs dans l'espace projectif peut entraîner des problèmes lorsque vous considérez le vecteur de somme comme un vecteur projeté dans l'espace euclidien, cela s'ajoute car vous additionnez les composants W dans l'espace affine, puis les projetez dans le (hyper) plan euclidien.

C'est pourquoi vous ne pouvez additionner que les "points" aux "vecteurs" car un "vecteur" ne changera pas la coordonnée w du "point" ceci n'est vrai que pour les "points" où w = 1:

entrez la description de l'image ici

Comme vous le voyez, le point vert est celui obtenu en ajoutant les deux vecteurs affines qui représentent le "point" cyan et le "vecteur" V , mais si vous appliquez V à chaque vecteur affine sous une forme différente de celle du canon, vous obtiendrez un mauvais résultat (le "" point "" rouge).

Vous voyez que Affine Space ne peut pas être utilisé de manière transparente pour décrire le fonctionnement sur les espaces euclidiens et l' utilisation abusive du terme "vecteur" a du sens sous la contrainte (stricte) des sommes de calcul uniquement sur des vecteurs projectifs canon .

Cela dit, il est tout à fait raisonnable de penser que le GPU suppose qu'un Vector4 doit avoir w = 0 ou w = 1, sauf si vous savez vraiment ce que vous faites.

FxIII
la source
Il a été très difficile de choisir une réponse à cette question, car tous ont contribué à comprendre comment la relation du quatrième composant est utilisée et pourquoi elle est nécessaire. Votre explication de l'espace euclidien et affine est très utile, je ne l'aurais certainement pas compris comme je le fais maintenant sans ce niveau de détail. Merci beaucoup!
sebf
+1 pour une bonne explication (et schémas!) De l'espace projectif. Cependant, l'espace affine et l'espace projectif ne sont pas la même chose (voir la définition Wikipedia de l'espace affine). Une bonne façon de le dire est peut-être: 3 espaces projectifs et 3 espaces affins peuvent tous deux être intégrés dans R ^ 4, mais les plongements ne sont pas entièrement conformes. L'encodage de vecteurs à partir de l'espace affine avec w = 0 est possible et utile, mais n'est pas significatif du point de vue projectif. De même, les directions projectives (points à l'infini) ne sont pas significatives du point de vue affine.
Nathan Reed
1

Supposons un vecteur comme (x, y, z, w). Ce vecteur a 4 composantes x (coordonnée x dans l'espace), y (coordonnée y dans l'espace), z (coordonnée z dans l'espace) et la composante w intéressante et mystérieuse. En fait, la plupart des jeux 3D fonctionnent dans un espace 4d, également appelé espace homogène 4d. Il y a des avantages évidents ->

1> Cela nous aide à combiner des matrices de traduction et de rotation en une seule. Mais vous pensez peut-être à quoi cela sert, nous pourrions simplement multiplier la matrice de traduction et de rotation et c'est tout, mais non, il n'y a rien de plus.Si nous n'avons pas le composant w dans tous nos vecteurs, puis lorsque nous multiplions le vecteur 3d (xyz) à la matrice combinée de translation et de rotation de quelque manière que ce soit, nous allons inconsciemment mettre à l'échelle les valeurs avec x, y ou z (c'est ainsi que la multiplication matricielle fonctionne) et cela probablement corrompre la matrice de position (partie de traduction de la matrice combinée) en raison de la mise à l'échelle.Pour corriger ce problème, le 4ème composant est introduit et ce composant du vecteur (w) tiendra la valeur 1.0 dans 99% des cas.Ce 4ème composant nous permet d'avoir des valeurs de position non mises à l'échelle (translation). La matrice est représentée comme->

 [x y z w] [rx1 rx2 rx3 1]
           [ry1 ry2 ry3 1]
           [rz1 rz2 rz3 1]
           [px  py  pz  1]

puis nous avons la matrice simple mais puissante. :)

2> Nous copions la valeur z dans le composant w dans la scène de projection en perspective et divisons le x, y avec. Les objets deviennent ainsi plus courts lorsqu'ils s'éloignent de l'écran.

gamePro
la source
Merci! Je vois de plus en plus la nécessité d'utiliser le quatrième composant dans toute représentation vraiment utile d'une entité dans l'espace 3D.
sebf