¿Qué hace la tarjeta gráfica con el cuarto elemento de un vector como posición final?


25

De esta pregunta parece que querría un vector de posición de cuatro elementos, ya que es más sencillo modificar su posición con la multiplicación de matrices.

Por sí solo, esto implicaría que el cuarto elemento simplemente debe ignorarse al considerarlo como una representación de un punto 3D (suponiendo que no hay transformación), pero sé que esto no es cierto, como cuando proporciono un vector4 a la GPU, si el cuarto El elemento no es uno, no se representa, ¿por qué?

¿Cuál es el significado del cuarto elemento, una vez que está en el rasterizador?

EDITAR : En la revisión, esta pregunta estaba algo mal redactada; sería más preciso que el segundo párrafo diga: "si el valor del cuarto elemento no está dentro de un cierto rango, no se representa 'correctamente' / 'como se esperaba'".


¿no un vector4 con coordenadas (x, y, z, 0.5) da los mismos resultados que el vector4 con coordenadas (2x, 2y, 2z, 1)?
FxIII

@FxIII, no pude reproducir eso exactamente, pero tienes razón, fue una declaración general incorrecta hecha en mi publicación original, después de experimentar un poco más, la actualicé.
sebf

Respuestas:


23

El cuarto componente es un truco para realizar un seguimiento de la proyección en perspectiva. Cuando realiza una proyección en perspectiva, desea dividir por z: x '= x / z, y' = y / z, pero esta no es una operación que puede implementarse mediante una matriz 3x3 que opera en un vector de x, y, z. El truco que se ha convertido en estándar para hacer esto es agregar una cuarta coordenada, w, y declarar que x, y, z siempre se dividirán por w después de aplicar todas las transformaciones y antes de la rasterización.

La proyección en perspectiva se logra al tener una matriz que mueve z hacia w, de modo que terminas dividiendo por z. Pero también te da la flexibilidad de dejar w = 1.0 si no quieres hacer una división; por ejemplo si solo quieres una proyección paralela, o una rotación o lo que sea.

La capacidad de codificar posiciones como w = 1, direcciones como w = 0 y usar la cuarta fila / columna de una matriz para la traducción es un buen beneficio adicional, pero no es la razón principal para agregar w. Se podrían usar transformaciones afines (una matriz de 3x3 más un vector de traducción de 3 componentes) para lograr la traducción sin ningún w a la vista. (Uno tendría que hacer un seguimiento de lo que es una posición y lo que es una dirección, y aplicar diferentes funciones de transformación a cada uno; eso es un poco inconveniente, pero en realidad no es un gran problema).

(Por cierto, matemáticamente, los vectores aumentados con w se conocen como coordenadas homogéneas , y viven en un lugar llamado espacio proyectivo . Sin embargo, no es necesario comprender las matemáticas más altas para hacer gráficos en 3D).


Una vez más, es ligeramente incorrecto hablar de vectores y puntos en esos términos, ya que existe un isomorfismo entre puntos y vectores (el punto y el vector que mueven el origen a ese punto son la misma entidad). Sería más correcto hablar de puntos / vectores (w! = 0) y direcciones (proyectivas) (w = 0). De todos modos, el mal uso del término "vector" es un estándar bastante consolidado en el lenguaje de bibliotecas 3d.
FxIII

@FxIII: corregido. Era confuso usar "vector" en el sentido matemático estándar y como sinónimo de "dirección" en la misma publicación.
Nicol Bolas

@FxIII y Nicol Bolas: no estoy de acuerdo. Realmente codifica vectores como w = 0, incluidos los vectores que solo representan una dirección y los vectores reales donde la longitud es importante. Por ejemplo, puede transformar el vector de velocidad angular (dirección = eje de rotación, longitud = velocidad) de un objeto entre el espacio local y el espacio mundial utilizando la matriz del objeto. No desea que la velocidad angular le agregue la traducción del objeto; solo quieres que se rote. Entonces configuras w = 0. ¿No veo el problema?
Nathan Reed

@NathanReed Espero que mi publicación ayude a aclarar el punto, de todos modos, una gran parte de mi punto se basa en las definiciones y el mal uso del término vector más la primacía del álgebra lineal sobre la terminología estándar de la biblioteca 3D. Por supuesto, ambos son debatibles, ya que cada definición y reclamo de primacía es
FxIII

@Nathan, ahora puedo ver claramente el propósito del cuarto elemento y cómo la información que contiene es utilizada por el rasterizador. ¡Muchas gracias!
sebf

10

Intentando responder al comentario apropiado de Natan, hice algunas consideraciones que pueden ser útiles para entender lo que realmente sucede cuando usas vectores en Affine Space para representar vectores 3D en el espacio euclidiano estándar.

Primero llamaré vector lo que tenga coordenadas, por lo que un punto y un vector son la misma entidad; puedes ver un vector como diferencia de dos puntos: V = B - A ; V mueve A en B porque A + V = A + B - A = B . Pon A = 0 (el origen) y obtendrás que V = B - 0 = B : el punto B y el vector que mueve 0a B son lo mismo.

Llamaré "vector" , en el sentido utilizado en la mayoría de las bibliotecas 3D, cuando un vector del espacio afín tiene w = 0.

La matriz se usa porque le permite representar una función lineal en una forma compacta / elegante / eficiente, pero las funciones lineales tienen la mayor desventaja que no puede transformar el origen: F ( 0 ) = 0 si F quiere ser lineal ( entre otras cosas como F (λ X ) = λF ( X ) y F ( A + B ) = F ( A ) + F ( B ))

Esto significa que no puede construir una matriz que haga una traducción, ya que nunca moverá el vector 0 . Aquí entra en juego el Affine Space . El espacio afín agrega una dimensión al espacio euclidiano para que se puedan realizar trasplantes con escala y rotaciones.

El espacio afín es un espacio proyectivo en el sentido de que puedes construir una relación de equivalencia entre vectores afines y euclidianos para que puedas confundirlos (como hicimos con los puntos y los vectores). Todos los vectores afines que se proyectan al origen con la misma dirección pueden verse como el mismo vector euclidiano.

Esto significa que todos los vectores que tienen las mismas proporciones en las coordenadas pueden considerarse equivalentes:

Matemáticamente:

equivalencia

es decir, cada vector afín se puede reducir a una versión canónica donde w = 1 (elegimos entre cada vector equivalente el que más nos guste).

Visualmente (2D euclidiano - 3D afín):

equivalencia visual

de ahí la media del espacio "proyectivo" ; Debes notar que aquí el espacio euclidiano es 2D (la región cian)

Hay un conjunto particular de vectores afines que no se pueden poner en su versión canónica (con facilidad) el que se encuentra en el (hiper) plano w = 0.

Podemos mostrarlo visualmente:

ingrese la descripción de la imagen aquí

lo que (debería) ver es que mientras w -> 0, el vector proyectado en el espacio euclídeo va al infinito pero al infinito en una dirección particular .

Ahora está claro que sumar dos vectores en el espacio proyectivo puede ocasionar problemas cuando considera el vector suma como un vector proyectado en el espacio euclidiano, esto se suma porque sumará los componentes W en el espacio afín y luego los proyectará en el (hiper) plano euclidiano.

Es por eso que puede sumar solo "puntos" a "vectores" porque un "vector" no cambiará la coordenada w del "punto", esto es cierto solo para "puntos" donde w = 1:

ingrese la descripción de la imagen aquí

Como puede ver, el punto verde es el que se obtiene agregando los dos vectores afines que representan el "punto" cian y el "vector" V , pero si aplica V a cada vector afín en una forma diferente al canon, obtendrá resultados incorrectos (el "" punto "rojo").

Verá que Affine Space no se puede usar de forma transparente para describir la operación en espacios euclidianos y el mal uso del término "vector" tiene sentido bajo la restricción (estricta) de sumas de cálculo solo en vectores proyectivos canónicos .

Dicho esto, es bastante razonable pensar que la GPU asume que un Vector4 debe tener w = 0 o w = 1, a menos que realmente sepa lo que está haciendo.


Fue muy difícil elegir una respuesta a esta pregunta, ya que todas han contribuido a comprender cómo se usa la relación del cuarto componente y por qué es necesaria. Su explicación del espacio euclidiano y afín es muy útil, ciertamente no lo habría entendido como lo hago ahora sin ese nivel de detalle. ¡Muchas gracias!
sebf

+1 para una buena explicación (¡y diagramas!) Del espacio proyectivo. Sin embargo, el espacio afín y el espacio proyectivo no son lo mismo (ver la definición de Wikipedia de espacio afín). Tal vez una buena manera de decir esto es: 3 espacios proyectivos y 3 espacios afines se pueden incrustar en R ^ 4, pero las incrustaciones no son completamente consonantes. Codificar vectores desde el espacio afín como w = 0 es posible y útil, pero no es significativo desde el punto de vista proyectivo. Del mismo modo, las direcciones proyectivas (puntos en el infinito) no son significativas desde el punto de vista afín.
Nathan Reed

1

Suponga un vector como (x, y, z, w). Este vector tiene 4 componentes x (coordenada x en el espacio), y (coordenada y en el espacio), z (coordenada z en el espacio) y el interesante y misterioso componente w. En realidad, la mayoría de los juegos en 3D funcionan en el espacio 4d. También se llama espacio homogéneo 4d. Hay algunos beneficios obvios de ello ->

1> Nos ayuda a combinar matrices de traslación y rotación en una sola. Pero tal vez pienses para qué sirve, podríamos simplemente multiplicar la matriz de traslación y rotación y listo, pero no hay más. Si no tenemos w componente en todos nuestros vectores, entonces cuando multiplicamos el vector 3d (xyz) a la matriz combinada de traslación y rotación de cualquier manera, estaremos escalando inconscientemente los valores con x, y o z (así es como funciona la multiplicación de matrices) y esto será probablemente corrompe la matriz de posición (parte de la traducción de la matriz combinada) debido a la escala. Para corregir este problema, se introduce el vector del cuarto componente y este componente del vector (w) tendrá el valor 1.0 en el 99% de los casos. Este cuarto componente nos permite tener valores de posición sin escala (traducción). La matriz se representa como->

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

y luego tenemos la matriz simple pero poderosa. :)

2> Copiamos el valor z en el componente w en la etapa de proyección en perspectiva y dividimos la x, y con él. De esta forma, los objetos se acortan a medida que se alejan de la pantalla.


¡Gracias! Cada vez veo más la necesidad de utilizar el cuarto componente en cualquier representación verdaderamente útil de una entidad en el espacio 3D.
sebf
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.