Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Programación Gráfica: Práctica de Proyección en Perspectiva

–Los Engines 3D no fueron hechos por los Extraterrestres–

Mientras mas gente relacionada con el desarrollo de videojuegos conozco. Mas me convenzo de que la mayoría de ellos creen que la tecnología que hace posible los juegos 3D fue inventada por los extraterrestres. O por lo menos una inteligencia superior a la de la raza humana. Solo así se explicarían muchas actitudes raras que involucran a gobiernos, universidades, empresas privadas y controvertidos grupos en internet dedicados a la desinformación. Hay mucho secretismo alrededor del tema. Por mi parte, considero que puedo ayudar mucho mas al desarrollo de estas tecnologías explicando como funcionan del modo mas amistoso y entendible que he podido hasta ahora en lugar de pasarme el tiempo diciéndole a todos lo genial que soy como la gente de cierta comunidad de desarrollo de videojuegos que por cierto ya muestra signos de rigidez cadavérica. En esta entrada les voy a mostrar un ejemplo muy simplificado pero funcional de como se genera una vista en primera persona de un objeto 3D.

En la entrada anterior vimos como el campo visual de una persona tiene forma de pirámide y como los objetos que quedan dentro de este volumen se proyectan sobre un plano imaginario que se encuentra frente al ojo del observador. En esta entrada vamos a dividir la tarea en dos partes. En la primera vamos a crear un objeto 3D sencillo en coordenadas de modelado y lo posicionaremos en el sistema de coordenadas mundiales. En la segunda parte vamos a colocar a un observador y generaremos una vista 3D del objeto. Recuerden que lo único que estamos usando ahora son lapiz, papel cuadriculado y una calculadora de bolsillo. Aunque si no tienen la suficiente paciencia pueden hacer uso de una hoja de cálculo por si quieren experimentar.

La figura mas elemental y conocida por el gran público que se me ocurre es un cubo que mide una sola unidad por lado. El cubo de la primera imagen tiene 8 vértices y 12 aristas. De momento no quise definir las caras porque no las vamos a necesitar. Pero si ustedes quieren hacerlo no olviden subdividir cada una de las caras cuadradas por al menos 2 caras triangulares para asegurar que cada una quede siempre definida como un plano en el espacio. Otra razón por la que quise usar un cubo unidad es que es mucho mas sencillo cambiar sus proporciones y posición de manera manual usando las matrices de rotación, traslación y escala que ya conocemos. En este ejemplo como lo queremos dejar lo mas sencillo posible vamos a usar una matriz identidad que como ya saben deja todos los vértices sin cambios. En este caso particular el cubo tiene una de sus esquinas justo en el origen y la esquina opuesta queda en la coordenada (1, 1, 1).

Ahora coloquemos al observador. Para agilizar los cálculos vamos a colocar la cámara en la coordenada (0,0,4) y el plano de proyección exactamente dos unidades por delante de modo que la linea de vista que es también la normal al plano de proyección coincida con el eje Z. La escena final se muestra en la segunda imagen junto con todos los parámetros básicos de vista.

Antes de generar la vista final repasemos las ecuaciones de proyección en perspectiva. Como ya saben de la entrada anterior la fórmula de proyección en perspectiva toma como entrada las coordenadas mundiales de un vértice y los datos de la cámara y da como salida las coordenadas bidimensionales en el plano de proyección. Este ejemplo ha sido reducido a tal nivel que los únicos parámetros que necesitamos son las coordenadas mundiales XYZ del vértice que queremos proyectar y la distancia del ojo al plano de proyección. La distancia del ojo al plano de proyección la llamaremos D_Plano y en este caso siempre va a ser 2. Para calcular la distancia total del ojo del observador al vértice vamos a tener que tomar la coordenada Z del punto de observación y restarle la coordenada Z del vértice que queremos poyectar. Hay una razón por la cual tomamos Z como negativa, y es que la distancia de vista se incrementa en dirección a la Z negativa. Si la coordenada Z del punto que queremos proyectar y la coordenada de vista fueran iguales (en este caso igual a 4), el denominador de la ecuación de proyección en perspectiva se anularía y tendríamos la temible división entre cero. En fin, luego de sustituir la distancia al plano por 2 y la coordenada Z de la cámara por 4, la vieja ecuación de proyección en perspectiva para esta vista nos queda así:
X_proyectada = (2 * X)/(4 – Z)
Y_proyectada = (2 * Y)/(4 – Z)

Lo siguiente es tomar los 8 vértices que componen nuestro cubo ya trasladado a coordenadas mundiales y aplicarle a cada uno las ecuaciones de proyección en perspectiva. En total se necesitan una multiplicación, una división y una resta para cada componente de la coordenada. Aunque mas adelante verán que todo esto puede reducirse a un solo producto de matriz por vector cuando se mecanizan los c\alculos con matrices. Al final de esta serie de operaciones tendremos las coordenadas proyectadas de todos los vértices del cubo. Ahora lo único que tenemos que hacer es dibujar los puntos en una hoja cuadriculada y unirlos siguiendo el orden de nuestra lista de aristas. Esto no es tan sencillo como parece y veremos el porqué a continuación.


Generación de la Vista en Primera Persona

Los parámetros que usamos para generar esta vista fueron simplificados en extremo para poder hacer estos cálculos a mano. Si tan solo dibujamos las coordenadas anteriores la imagen que vamos a obtener va a ser demasiado pequeña. Pues con los parámetros dados el plano de proyección que queda dentro del volumen de vista apenas mide 4 por 4 unidades. Así que para que puede dibujarse en una hoja de libreta a escala razonable vamos a escalar por un factor de 4 para poder dibujar la escena en una cuadrícula de 16 por 16. Para hacer este escalamiento basta con multiplicar las coordenadas ya proyectadas por 4. Una vez hecho esto dibujamos los vértices ya proyectados recordando que las coordenadas del plano de proyección (0,0) se encuentran al centro de ese cuadro, para recordar esto he dibujado una mira en ese punto no solo para que se parezca mas a un First Person Shooter sino para recordarles hacia donde está mirando el jugador. Es importante recordar que cuando queremos representar una imagen solo por sus aristas (lo que también se llama estructura de alambre primero dibujamos los vértices proyectados y luego los unimos por lineas rectas como lo indica la lista de aristas. En este caso vamos a dibujar 12 lineas rectas que unen los puntos en la secuencia que indica la lista de aristas que define el cubo. No importa donde queden los vértices después de las transformaciones, las aristas siempre los van a unir. Es importante tener bien identificado cual vértice es cual para evitar no confundirnos. Si hicimos todo correctamente al final obtenemos la vista en primera persona de la siguiente imagen (click para ampliar):


La verdad es que la imagen no me salió tan detallada como me hubiera gustado por hacerla tan simple. La escena está tomada de una toma al mismo nivel del piso en el que se encuentra posado el cubo. Piensen en una escena de un juego de guerra en la que el jugador se encuentra pecho tierra apuntando hacia la esquina izquierda de un edificio alejado. Para disminuir la ilusión óptica conocida como el Cubo de Necker repinté las aristas que quedan de frente al jugador y dejé con lineas de grosor normal las que quedarían ocultas si el cubo fuera opaco. Como la linea de vista está alineada con la esquina del cubo, lo que puede verse es la pared opuesta, el techo y la pared orientada en dirección al eje X. Espero en notas posteriores cuando veamos como eliminar partes ocultas y añadir detalle de superficie no necesitar de tanta imaginación para entender este tipo de tomas.

Pues bien, como pueden ver acabamos de crear una escena en 3D y la hemos proyectado. Y lo mas impresionante de todos es que no nos hizo falta mas equipo que papel, lapiz, calculadora y puede que una regla para dibujar rectas las aristas. Lo mas interesante de todo este proceso es que podemos aplicar cualquier transformación geométrica al cubo original y vamos a obtener una vista completamente diferente dependiendo de los datos que le demos. Si movemos el punto del observador hacia atras o adelante veremos como los cubos se alejan o se acercan. Todo estará bien por ahora mientras los vértices no salgan de la pirámide de visión ni entren en contacto con el punto que representa el ojo del observador. Inclusive podemos colocar el cubo entre el observador y el plano de proyección. Lo que bien hecho puede dar la impresión de que se encuentre por delante del monitor de la computadora.

Antes de terminar esta entrada quiero comentar un poco mas sobre el modelado wireframe o de estructura de alambre. En este ejemplo solo proyectamos los vértices y los unimos con aristas. Lo que da la impresión de que los objetos son transparentes o que están formados por alambres finos. Existen algoritmos para determinar si una arista es visible o no desde el punto de vista en que la vemos e incluso hay avanzados (aunque no por ello imposibles) algoritmos de iluminación y detalle de superficies. Cuando trabajamos con superficies opacas determinamos primero si un polígono es visible y si así es lo dibujamos. Para los casos en los que solo una parte es visible es posible recortar las aristas y redefinir la estructura de datos del sólido para desplegarla correctamente. Por ahora, con lo visto, podemos dibujar los cubos que queramos a partir del mismo cubo que definimos en coordenadas de modelado.

Ya para irme quiero advertirles algo sobre lo que acabamos de hacer aquí. Esta vista está exageradamente simplificada para ser facil de entender y generar a mano en tiempo razonable. La verdad es que es posible implementar una enorme cantidad de mejoras a la vista en primera persona para convertirla en una auténtica cámara. Por ejemplo, es posible obtener una vista de cualquier parte del espacio de coordenadas mundiales y no solo desde un punto constante dentro del eje Z. El plano de vista puede ampliarse para obtener visiones panorámicas o estrecharse para simular una mira telescópica. Puede rotarse sobre la linea de vista para hacer una vista ladeada. Maniobra conocida como Bank o Roll. También es posible definir una cámara con tan solo 3 puntos en el espacio o crear secuencias de animación donde la cámara tenga siempre enfocado un objetivo. En pocas palabras, existen algoritmos de vista capaces de implementar una auténtica cámara con la cual poder capturar cualquier escena de nuestro mundo 3D. Y eso lo vamos a estudiar en las siguientes entradas.

Anuncios

diciembre 16, 2011 - Posted by | Uncategorized | , , ,

2 comentarios »

  1. Mmm mi duda en esta entrada es cómo hacen los PCs para dibujar las aristas. Es decir, dibujar puntos parece sencillo, pero como dibujan las líneas ? Recorren la recta con la ecuación que vio anteriormente (con el parámetro t entre 0 y 1) y van dibujando un numero determinado de puntos a lo largo de la recta para representarla o va con otro sistema o … ? xD

    Comentario por JuDelCo | julio 22, 2012 | Responder

    • Existen viejos algoritmos para dibujar lineas rectas. Todos se basan en la ecuación lineal y = mx + B y aplican diferentes optimizaciones. Se parte de uno de los 2 puntos extremos y luego se sigue un algoritmo que decide cuales de los puntos intermedios se deben pintar.

      Algunos algoritmos de dibujo de lineas rectas son el de Bresenham que solo usa sumas y rotaciones binarias, Nichol-Lee-Nichol que aprovecha la simetria y el de Análisis de Diferencia Digital que es el mas sencillo de entender pero también es el menos eficiente. A ver si un dia escribo sobre estos porque no son tan fáciles

      Comentario por asm86 | julio 22, 2012 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: