¿Por qué necesitamos una cuarta coordenada para dividir por z?

12

Leí la respuesta aquí:

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

"El cuarto componente es un truco para realizar un seguimiento de la proyección en perspectiva. Cuando haces una proyección en perspectiva, quieres dividir por z: x '= x / z, y' = y / z, pero esta no es una operación que puede implementarse mediante una matriz de 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 ".

pero no entendí por qué no podríamos dividir por z usando una matriz 3x3?

¿No podemos simplemente multiplicar por

1/z 0 0
0 1/z 0
0 0 1/z

Llegar [x/z y/z 1]

?

Comunidad
fuente
Intente expresar una transformación (o composición de transformaciones) que incluya la traducción en algún lugar de la cadena. Sin un valor aw, no puede expresarlo en una sola matriz.
DMGregory
Entiendo la parte de la traducción, pero no entendí cómo agregar una cuarta coordenada ayudará o es un truco para dividir por z
Por lo que vale, puedes hacer lo que dijiste. Dividir x e y por z es un método válido para convertir desde coordenadas 3d a un espacio de pantalla 2D con proyección donde los objetos distantes se hacen más pequeños. La w es una coordenada homogénea para llevarla a la cuarta dimensión para poder hacer la traducción.
Alan Wolfe

Respuestas:

14

Porque si solo divide [x, y, z]entre zobtiene [x/z, y/z, 1]y pierde el valor real de z, lo cual es realmente útil si desea hacer un recorte de plano cercano / lejano o llenar un búfer Z.

Por lo tanto, la mejor manera de mantener información sobre z, al menos en la GPU, es usar 4 componentes en lugar de 3. En la práctica, lo que está realmente en los dos últimos componentes del vector antes de la división en perspectiva depende de qué tipo de proyección y efectos desear.

Por ejemplo, en el caso de una proyección en perspectiva, este es el vector resultante de 4 componentes:

| a 0 0 0 |   | x |   |   ax   |
| 0 b 0 0 |   | y |   |   by   |
| 0 0 c d | × | z | = | cz + d |
| 0 0 1 0 |   | 1 |   |    z   |

Después de la perspectiva, dividir el vector se convierte en:

|  ax/z   |
|  by/z   |
| c + d/z |
|    1    |

Y la c + d/zparte nos deja con suficiente información para llenar el búfer Z.

sam hocevar
fuente
Podrías dividir solo X e Y por Z, produciendo [x / z, y / z, z]. La GPU no tiene que hacer división de vectores, podría haber sido diseñada para hacer cualquier cálculo.
user253751
3

Técnicamente, podrías hacer eso. ¿Pero por qué molestarse? Para cuando tengas esa final z, podrías:

  • construya una matriz de 3x3 como lo describió, desperdiciando 9 * sizeof(float)bytes de espacio, gastando ciclos para calcular 1/z(una división) y luego haciendo nueve multiplicaciones y seis sumas para obtener su vértice final, o
  • puede hacer tres divisiones, como lo hace actualmente la tubería moderna

Uno de estos me parece mucho más óptimo, y no es el primero. Incluso si existe hardware optimizado para la multiplicación de la matriz, como ciertamente lo hace, sigue siendo conceptualmente más complejo que una simple división.

Además, una matriz 3x3 no puede codificar una traducción, por lo que una matriz 4x4 (y, por lo tanto, la cuarta wcoordenada) se usa antes en la tubería de todos modos . Esto significa que ya tiene ese cuarto componente sentado, por lo que también puede usarlo para transportar un valor útil y hacer su división con él.


fuente