Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Programación Gráfica: Proyección en Perspectiva

–Como Funciona la Vista en Primera Persona–

Uno de los mejores recuerdos que tengo de cuando comenzaba a programar fue el haber implementado las ecuaciones de proyección en perspectiva en un modesto programa de 16 bits de MS-DOS. Cálculos que aunque humildes eran capaces de desplegar imágenes tridimensionales de estructura de alambre que a principios de los noventa sorprendian a mas de uno. Se trataba tan solo de lineas claras sobre fondo negro pero al menos a mi me dieron la suficiente inspiración para dedicarme a programar estas cosas. De eso han pasado casi veinte años y aunque las gráficas por computadora son algo cotidiano siguen provocando el mismo complejo de inferioridad de aquellos dias de los monitores CRT. Sigo escuchando como programadores jóvenes que han jugado juegos 3D toda su vida les da miedo este tipo de programación. De momento no me voy a poner a insultar y voy mejor a intentar compartir con los programadores mas principiantes esa misma emoción que experimenté aquellos dias.

La proyección en perspectiva es como el ojo humano percibe su entorno tridimensional. Cualquiera puede salir a la calle y ver como las cosas parecen hacerse mas pequeñas cuanto mas lejos están, o como las orillas de la carretera parecen juntarse en la distancia a pesar de tratarse de lineas paralelas. Los movimientos de los objetos cercanos parecen ser mas rápidos que los que están lejos de nosotros e incluso podemos cubrir la circunferencia completa de la luna llena con tan solo uno de nuestros dedos. En el primero de los dibujos se muestra el porqué de esto. El campo visual de una persona tiene forma de una pirámide cuya punta termina en el ojo y se abre hasta el infinito. Todo lo que podemos ver se encuentra en los límites de esa figura. Sin embargo, como no estamos trabajando con proyecciones intraoculares sino con pantallas de computadora existe un concepto llamado Plano de Proyección.

El plano de proyección es como una ventana de vidrio por la que vemos nuestro mundo en 3D. La parte de ese plano que queda dentro del volumen de visión piramidal representa la pantalla de la computadora. Existe una distancia entre el ojo del observador y esa ventana que representa el plano de proyección. Si leyeron la entrada anterior ya saben que hay lineas llamadas proyectores que van desde el ojo del observador hasta cada uno de los vértices de las figuras tridimensionales. Las ecuaciones de perspectiva nos indican como se proyectan los vértices en el espacio en ese plano dados únicamente sus coordenadas x,y,z y la distancia entre el observador y el plano de proyección.

De manera muy esquematizada, lo que se muestra en el dibujo es la vista lateral de una proyección en perspectiva. Aunque los mísmos cálculos se pueden aplicar para una vista superior. Representa a un observador que dispara contra una pared (el rectángulo) frente a él. La linea vertical entre ambos es el plano de proyección y la linea punteada horizontal indica la linea de vista que es la dirección en la que el jugador está apuntando. Las diagonales que van del ojo del observador a las esquinas de la pared son los proyectores y las equis donde estos se cruzan son los puntos que vamos a desplegar en pantalla. Tenemos que obtener las coordenadas BIDIMENSIONALES que corresponden a esas equis en nuestro plano de proyección.

Recuerden por un momento como representábamos un plano cartesiano en dos dimensiones. Era esa cosa con dos lineas cruzadas que recordaba a las miras de los francotiradores (snipers) de los juegos First Person Shooters. Pues al igual que estas miras, la linea punteada que indica la dirección en la que el jugador está viendo pasa por el centro de esa mira como lo haría una bala disparada por el rifle. Si un vértice quedara en esa linea de fuego se proyectaría justo en el centro de nuestro plano de proyección. Y conforme cambiara de lugar se alejaría cada vez mas del centro. Ahora veamos de forma matemática como obtener las coordenadas x,y de este plano de proyección a partir de las cordenadas x,y,z que son mundiales.

En el segundo dibujo se muestra una parte de la primera imagen. La linea horizontal representa la linea de vista (la punteada) que coincide con el centro del plano de proyección y es igual a la distancia entre el observador y el objetivo. El eje vertical puede representar tanto X como Y suponiendo que la linea de vista coincida con el eje Z. La linea vertical mas grande, o en este caso el lado vertical del triángulo que se forma es la distancia del centro de la linea de vista al punto en el espacio que queremos proyectar, la linea vertical que parte el triángulo representa nuestro plano de proyección.

Matemáticas de la Proyección en Perspectiva

Antes de continuar revisemos que tenemos 4 parámetros:
Distancia Total: La distancia horizontal del observador a la coordenada mundial. Se acostumbra que coincida con el eje Z.
Coordenada Mundial:Puede ser X o Y suponiendo que la distancia total coincida con el eje Z.
Distancia al Plano:La distancia del observador al plano de proyección.
Coordenada Proyectada: Se trata de la proyección de la coordenada mundial en el plano de proyección y es el valor que queremos obtener

Lo que debemos hacer es calcluar la longitud del segmento de linea pintado de rojo (la coordenada proyectada) y ese será el valor proyectado de la coordenada mundial en nuestro plano de proyección. Lo primero que vemos es que la Distancia Total se divide en dos partes. La parte entre el punto de observación y el plano de vista es la distancia al plano de visión. Y la distancia del observador al objetivo es la Distancia Total. Lo segundo es que existe una proporción entre estos 4 números: Si dividimos la Coordenada Mundial entre la Distancia Total obtenemos el mismo número que si dividimos la Coordenada Proyectada entre la Distancia de Proyección. No importa que no conozcamos el valor de la Coordenada Proyectada porque se trata de triángulos similares. Entonces con un poco de álgebra podemos despejar el valor de la Coordenada Proyectada como sigue:

(Coordenada_Mundial)/(Distancia_Total) = (Coordenada_Proyectada)/(Distancia_al_Plano)

(Coordenada_Proyectada) = (Distancia_al_Plano)*(Coordenada_Mundial)/(Distancia_Total)

En resumen, para proyectar una coordenada mundial en un plano de proyección basta con multiplicarla por la Distancia al plano de proyección y luego dividirla por la distancia horizontal. Ahora juguemos con estos valores. La distancia al plano de proyección debe de elegirse cuidadosamente, si es demasiado pequeña el volumen de vista será demasiado amplio y las figuras parecerán mas pequeñas de lo que son. Si es demasiado grande no podremos ver mas que una parte muy pequeña del mundo, es mas, conforme este valor se acerca al infinito los proyectores comienzan a volverse paralelos y obtenemos una proyección paralela. Dato que veremos en alguna nota posterior de manera mas matemática. Nota aparte, en la época en la que se hacía 3D sin valores de punto flotante se acostumbraba usar una potencia de dos como 128 o 256 para optimizar los cálculos y cambiar una multiplicación por un simple desplazamiento binario.

La distancia horizontal entre el observador y el objetivo a proyectar controla no solo el tamaño de la proyección. Sino que cuando se convierte en un valor negativo. Es decir que el objeto queda por detras del observador la imagen proyectada se invierte y parece estar por delante del jugador. Es importante mantener los valores siempre dentro de la pirámide de volumen de vista o recortarla si es posible. Si la distancia es muy larga el objeto comenzará a parecer un simple punto cerca del centro de la pantalla.

Cuando la coordenada mundial que queremos proyectar tiene un valor cercano a cero va a aparecer en el centro del plano de proyección y conforme crece en valor absoluto se va alejando del centro hasta que queda fuera de los límites de lo que podemos mostrar en pantalla.

El algoritmo de proyección funciona como una cámara fotográfica. Ponemos la cámara en un lugar del espacio y tomamos la foto. Mas adelante veremos como poner la cámara en cualquier parte del mundo definido por el sistema de Coordenadas Mundiales. De momento vamos a suponer que la cámara está alineada con el eje Z y que mira en dirección al origen. De modo que el plano de proyección sea perpendicular al eje Z del sistema de coordenadas mundiales y que el observador se encuentre frente a este. En la siguiente entrada veremos todo esto de una manera mucho mas programable. De momento solo tienen que estar enterados de que se usan matrices de transformación geométrica para simplificar los cálculos de las vistas de cámara.

Ya para despedirme, espero que estas notas les abran los ojos y vean que todos este asunto del 3D no es tan impresionante como lo pintan algunos “profesionales de la industria”. Desarrollar un Engine Gráfico no es mas dificil que desarrollar cualquier sistema de computación dedicado a cualquier otra cosa, la única diferencia es que necesitan saber matemáticas y ensamblador para que funcione de manera eficiente. No pierdan las esperanzas si es que han decidido intentar este tipo de proyectos. O por lo menos mantengan siempre presente que hacerlo es cuestión de conocimiento y dedicación y no de tener dinero o cumplir con el perfil como muchos por ahi les van a querer hacer creer.

Anuncios

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

1 comentario »

  1. Buenisimo asm86, si estos ejemplos me hubiera puesto el profesor de matematicas seguro los hubiera entendido mejor.

    Saludos.

    Comentario por StrongCod3r | diciembre 6, 2011 | 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: