Cosa fa la scheda grafica con il quarto elemento di un vettore come posizione finale?


25

Da questa domanda sembra che vorresti un vettore di posizione a quattro elementi, poiché è più semplice modificarne la posizione con la moltiplicazione della matrice.

Di per sé ciò implicherebbe che il quarto elemento dovrebbe essere semplicemente ignorato quando lo si considera come una rappresentazione di un punto 3D (supponendo che non ci sia trasformazione), ma so che questo non è vero, come quando fornisco un vettore4 alla GPU, se il quarto l'elemento non è uno, non è reso - perché?

Qual è il significato del quarto elemento, una volta che è nel rasterizzatore?

EDIT : Sulla revisione questa domanda era in qualche modo mal formulata; sarebbe più preciso per il secondo paragrafo dire: "se il valore del quarto elemento non rientra in un certo intervallo, non viene reso" correttamente "/" come previsto "".


un vettore4 con coordinate (x, y, z, 0,5) non fornisce gli stessi risultati del vettore4 con coordinate (2x, 2y, 2z, 1)?
FxIII

@FxIII, non sono stato in grado di riprodurlo esattamente, ma hai ragione, è stata un'affermazione coperta errata fatta nel mio post originale, dopo qualche ulteriore sperimentazione l'ho aggiornato.
sebf,

Risposte:


23

Il quarto componente è un trucco per tenere traccia della proiezione prospettica. Quando esegui una proiezione prospettica, vuoi dividere per z: x '= x / z, y' = y / z, ma questa non è un'operazione che può essere implementata da una matrice 3x3 operante su un vettore di x, y, z. Il trucco che è diventato standard per fare ciò è aggiungere una quarta coordinata, w, e dichiarare che x, y, z saranno sempre divisi per w dopo che tutte le trasformazioni sono state applicate e prima della rasterizzazione.

La proiezione prospettica viene quindi realizzata avendo una matrice che sposta z in w, in modo da finire per dividere per z. Ma ti dà anche la flessibilità di lasciare w = 1.0 se non vuoi fare una divisione; per esempio se vuoi solo una proiezione parallela, una rotazione o altro.

La possibilità di codificare posizioni come w = 1, indicazioni come w = 0 e utilizzare la quarta riga / colonna di una matrice per la traduzione è un bel vantaggio collaterale, ma non è il motivo principale per l'aggiunta di w. Si potrebbero usare trasformazioni affine (una matrice 3x3 più un vettore di traduzione a 3 componenti) per realizzare la traduzione senza alcun w in vista. (Uno dovrebbe tenere traccia di ciò che è una posizione e che cosa è una direzione e applicare diverse funzioni di trasformazione a ciascuna; questo è un po 'scomodo, ma non è un grosso problema.)

(A proposito, matematicamente, i vettori aumentati con w sono noti come coordinate omogenee e vivono in un luogo chiamato spazio proiettivo . Tuttavia, non è necessario comprendere la matematica superiore per realizzare grafica 3D.)


Ancora una volta è leggermente errato parlare di vettori e punti in quei termini poiché esiste un isomorfismo tra punti e vettori (il punto e il vettore che spostano l'origine in quel punto sono la stessa entità). Sarebbe più corretto parlare di punti / vettori (w! = 0) e direzioni (proiettive) (w = 0). Comunque l'uso improprio del termine "vettore" è uno standard abbastanza consolidato nel linguaggio delle biblioteche 3d.
FxIII

@FxIII: corretto. Era confuso usare "vettore" nel senso matematico standard e come sinonimo di "direzione" nello stesso post.
Nicol Bolas,

@FxIII e Nicol Bolas: non sono d'accordo. Codifichi davvero i vettori come w = 0, inclusi sia i vettori che rappresentano solo una direzione, sia i vettori effettivi in ​​cui la lunghezza è importante. Ad esempio, è possibile trasformare il vettore di velocità angolare (direzione = asse di rotazione, lunghezza = velocità) di un oggetto tra lo spazio locale e lo spazio del mondo usando la matrice dell'oggetto. Non vuoi che la velocità angolare venga aggiunta alla traduzione dell'oggetto; vuoi solo che sia ruotato. Quindi hai impostato w = 0. Non vedo il problema?
Nathan Reed,

@NathanReed Spero che il mio post aiuti a chiarire il punto, comunque gran parte del mio punto riguarda le definizioni e l'uso improprio del termine vettore più il primato dell'algebra lineare sulla terminologia standard della biblioteca 3D. Naturalmente entrambi sono discutibili come ogni affermazione di definizione e primato è
FxIII

@Nathan, ora riesco a vedere chiaramente lo scopo del quarto elemento e come le informazioni in esso contenute vengono utilizzate dal rasterizzatore. Molte grazie!
sebf,

10

Cercando di rispondere al commento appropriato di Natan, ho fatto alcune considerazioni che possono essere utili per capire cosa succede realmente quando usi i vettori nello Spazio Affine per rappresentare i vettori 3D nello Spazio Euclideo standard.

Per prima cosa chiamerò vector qualunque cosa abbia coordinate, quindi un punto e un vettore sono la stessa entità; puoi vedere un vettore come differenza di due punti: V = B - A ; V muove A in B perché A + V = A + B - A = B . Inserisci A = 0 (l'origine) e otterrai quel V = B - 0 = B : il punto B e il vettore che si muove 0a B sono la stessa cosa.

Chiamerò "vettore" - nel senso usato nella maggior parte delle librerie 3D - quando un vettore dello spazio affine ha w = 0.

La matrice viene utilizzata perché consente di rappresentare una funzione lineare in una forma compatta / elegante / efficiente, ma le funzioni lineari presentano il principale svantaggio che non può trasformare l'origine: F ( 0 ) = 0 se F vuole essere lineare ( amog altra cosa come F (λ X ) = λF ( X ) e F ( A + B ) = F ( A ) + F ( B ))

Ciò significa che non è possibile costruire una matrice che esegua una traduzione poiché non si sposta mai il vettore 0 . Qui entra in gioco lo spazio affine . Lo spazio affine aggiunge una dimensione allo spazio euclideo in modo che le traslanzioni possano essere fatte con ridimensionamento e rotazioni.

Lo spazio affine è uno spazio proiettivo, nel senso che puoi costruire una relazione di equivalenza tra vettori affini ed euclidei in modo da poterli confondere (come abbiamo fatto con poins e vettori). Tutti i vettori affini che proiettano all'origine con la stessa direzione possono essere visti come lo stesso vettore euclideo.

Ciò significa che tutti i vettori che hanno le stesse proporzioni nelle coordinate possono essere considerati equivalenti:

Matematicamente:

equivalenza

cioè ogni vettore affine può essere ridotto a una versione canonica dove w = 1 (scegliamo tra ogni vettore equivalente quello che ci piace di più).

Visivamente (euclidee 2D - 3D affine):

equivalenza visiva

da qui la media dello spazio "proiettivo" ; Dovresti notare che qui lo spazio euclideo è 2D (la regione ciano)

C'è un particolare insieme di vettori affini che non possono essere messi nella loro versione canonica (con facilità) quello che giace sul (iper) piano w = 0.

Possiamo mostrarlo visivamente:

inserisci qui la descrizione dell'immagine

quello che (dovresti) vedere è che mentre w -> 0 il vettore proiettato nello spazio euclideo va all'infinito ma all'infinito in una direzione particolare .

Ora è chiaro che sommare due vettori nello spazio proiettivo può portare a problemi quando si considera il vettore di somma come vettore proiettato nello spazio euclideo, ciò si aggiunge perché si sommano i componenti W nello spazio affine e quindi li si proietta sul piano euclideo (iper).

Questo è il motivo per cui puoi sommare solo "punti" a "vettori" perché un "vettore" non cambierà la coordinata w del "punto", ciò vale solo per "punti" dove w = 1:

inserisci qui la descrizione dell'immagine

Come vedi il punto verde è quello ottenuto aggiungendo i due vettori affini che rappresentano il "punto" ciano e il "vettore" V , ma se applichi V a ogni vettore affine in una forma diversa da quella canonica, otterrai risultati errati (il "" punto "" rosso).

Vedete che Affine Space non può essere usato in modo trasparente per descrivere l'operazione su Spazi euclidei e l' uso improprio del termine "vettore" ha senso sotto il vincolo (rigoroso) di somme di calcolo solo su vettori proiettivi canonici .

Detto questo, è abbastanza ragionevole pensare che la GPU presuma che un Vector4 debba avere w = 0 o w = 1, a meno che tu non sappia veramente cosa stai facendo.


È stato molto difficile scegliere una risposta a questa domanda, poiché tutti hanno contribuito a comprendere come viene utilizzata la relazione del quarto componente e perché è necessaria. La tua spiegazione dello spazio euclideo e affine è molto utile, non avrei certamente capito come faccio ora senza quel livello di dettaglio. Grazie mille!
sebf,

+1 per una buona spiegazione (e diagrammi!) Dello spazio proiettivo. Tuttavia, lo spazio affine e lo spazio proiettivo non sono la stessa cosa (vedere la definizione di spazio affine di Wikipedia ). Forse un buon modo per dirlo è: il 3-spazio proiettivo e il 3-spazio affine possono essere entrambi incorporati in R ^ 4, ma gli incorporamenti non sono del tutto consonanti. La codifica di vettori dallo spazio affine come w = 0 è possibile e utile, ma non è significativa dal punto di vista proiettivo. Allo stesso modo, le direzioni proiettive (punti all'infinito) non sono significative dal punto di vista affine.
Nathan Reed,

1

Assumi un vettore come (x, y, z, w). Questo vettore ha 4 componenti x (coordinata x nello spazio), y (coordinata y nello spazio), z (coordinata z nello spazio) e l'interessante e misteriosa componente w. In realtà la maggior parte dei giochi 3d opera in uno spazio 4d, chiamato anche spazio omogeneo 4d. Ci sono alcuni ovvi benefici di esso ->

1> Ci aiuta a combinare le matrici di traduzione e rotazione in una sola. Ma potresti pensare a cosa serve, potremmo semplicemente moltiplicare la matrice di traduzione e rotazione e basta, ma non c'è altro. Se non abbiamo w componente in tutti i nostri vettori quindi quando moltiplichiamo il vettore 3d (xyz) alla matrice combinata di traslazione e rotazione in qualunque modo scaleremo inconsciamente i valori con x, yo z (è così che funziona la moltiplicazione della matrice) e questo funzionerà probabilmente corrompe la matrice di posizione (parte di traduzione della matrice combinata) a causa del ridimensionamento. Per correggere questo problema viene introdotto il vettore del 4 ° componente e questo componente del vettore (w) manterrà il valore 1,0 nel 99% dei casi. Questo 4 ° componente ci consente per avere valori di posizione non scalati (traduzione). La matrice è rappresentata come->

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

e quindi abbiamo la matrice semplice ma potente. :)

2> Copiamo il valore z nel componente w nella fase di proiezione prospettica e dividiamo x, y con esso. In questo modo gli oggetti si accorciano man mano che si allontanano dallo schermo.


Grazie! Sto vedendo sempre più la necessità di usare il quarto componente in qualsiasi rappresentazione veramente utile di un'entità nello spazio 3D.
sebf,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.