XNA Demos (III): Simulación de geometría con impostores

descargar_codigo

Aunque hoy en día las GPUs ganan rendimiento a pasos agigantados, la evolución de los gráficos por computador (no olvidemos que muchos de los efectos y técnicas que ahora se usan en tiempo real estaban limitados a un uso precalculado hasta no hace mucho) se adapta a estos cambios y los explota al máximo, y más aún desde el abandono de la FFP y el advenimiento de los shaders.

Una de las limitaciones que más rápidamente se alcanza es la complejidad poligonal de la escena. Teniendo en cuenta que la GPU tiene que transformar la posición de cada vértice a coordenadas de pantalla, interpolar los valores (posición, normal, coordenadas de textura) al resto del triángulo, y por último rasterizar los fragmentos visibles (aplicando los efectos de shader correspondientes), tener una escena de un millón de polígonos y querer moverla con un refresco decente (60+ Hz) sigue siendo un suicidio. Por ello, hay que recurrir a técnicas de simplificación, como puede ser el frustrum culling, para eliminar objetos fuera del campo de visión de la cámara, o, como se muestra en el ejemplo, simplificar el dibujado de los mismos.

Uno de los métodos más empleados es el Level-Of-Detail, o LOD. Ésta técnica consiste en disponer de varias copias de un mismo modelo, en las que se ha ido reduciendo el nivel de polígonos (mediante un programa de modelado) progresivamente. Dependiendo de la distancia del objeto a la cámara, se dibuja una versión con mayor o menor detalle, procurando que el tamaño final del objeto en pantalla compense los posibles errores del modelo (partes deformadas, texturas mal alineadas, etc.).

comparacion_lod

Izquierda: ~10000 polígonos. Derecha: ~4000 polígonos.

Pero cuando el LOD no es suficiente (cientos o miles de instancias de objetos al mismo tiempo) y el mesh instancing tampoco da buenos resultados, se recurre a un “truco”: los impostores. Un impostor es un sprite orientado siempre hacia la cámara (algunas veces con un eje de rotación restringido, para evitar resultados poco realistas debido a deformaciones), y que contiene una imagen del modelo visto desde un ángulo determinado.

tira
Los sprites usados para los impostores del ejemplo.

Dependiendo de la forma y uso de los impostores, podremos generar más o menos proyecciones del model, dependiendo del grado de realismo que queramos alcanzar. En el ejemplo se han generado 8 vistas de 128×128 píxeles, con una diferencia de 45º de rotación entre ellas; dependiendo de la orientación de la cámara, se dibujará una u otra para simular la existencia de un objeto tridimensional en la escena, como muestra el esquema siguiente:

diagrama
Sprite empleado dependiendo de la orientación de la cámara y el objeto.

Por último, queda aclarar que los impostores no siempre son la solución; si la diferencia de altura entre el objeto y la cámara es muy grande, se puede producir (debido a la restricción de ejes en el impostor) una distorsión que arruinaría todo el realismo de la escena:

image
Distorsión de los impostores al verlos desde un ángulo muy inclinado.

XNA Demos (II): Reflexiones en tiempo real con cubemaps

descargar_codigoUno de los efectos más buscados en los videojuegos desde la transición del género a las 3D ha sido la posibilidad de generar reflexiones (como espejos o superficies metálicas) de una manera realista y convincente. Debido a la poca flexibilidad del renderizado por raster (sólo se dibujan los píxeles visibles por el volumen generado a partir de las matrices de vista y proyección), siempre se ha recurrido a “trucos” para simular el efecto. Por ejemplo, los motores con geometría basada en CSG aprovechan el uso de los portales para, creando una máscara mediante el uso del stencil buffer, redibujar los objetos visibles tal y como se verían reflejados.

Con el aumento de la potencia de las GPUs y el abaratamiento de la VRAM, se ha optado por utilizar un tipo especial de textura llamado “cubemap”, que como el nombre indica, almacena las 6 caras de un cubo. De esta manera, se puede representar todo el entorno que rodea a un punto determinado, y se pueden crear offline (con un editor gráfico, para dibujar por ejemplo un skybox que dé profundidad a la escena) o en tiempo de ejecución.

cubemapCubemap estático de la demo, reescalado

Uno de los motores que más emplean el uso de cubemaps es Source, si bien los utiliza sólo en su versión estática; al compilar un mapa, y mediante un comando especial, se ordena que se generen los cubemaps en determinados puntos designados por el diseñador. El problema de este método es que las reflexiones sólo mostrarán los objetos estáticos del mapa, así que si creamos una superficie totalmente reflectante y situamos al jugador delante suyo, no habrá cambio alguno.

Un método más realista es actualizar los cubemaps dinámicamente, para que reflejen todos los cambios de la escena. Sin embargo, éste método también tiene sus desventajas: hay que dibujar la escena 7 veces (una por cada cara del cubemap y otra para el resultado final), así que hay que pensar en métodos para rebajar la carga: usar sólo un cubemap dinámico al tiempo, actualizar únicamente 2 caras a cada frame…

Por último, la demo también incluye un efecto de refracción, con una constante de transmisión del medio de 0.66, para simular vidrio. La única diferencia entre los dos shaders es la instrucción usada para calcular el vector que se empleará para obtener el téxel del cubemap, que en un caso es reflect y en el otro refract.

reflex_refract Vectores de reflexión y refracción.

01/01/2010: actualizado el código para mejorar el rendimiento del Cubemap dinámico.

SetCronJob, cron jobs gratuitos para cualquier host

Una de las cosas que eché de menos al migrar la web desde Hostinet (empresa que elegí para el programa Jóvenes en Red) a 1&1 fue la posibilidad de programar cron jobs en el servidor (1&1 sólo ofrece el servicio en su modalidad Business Plus).

Ahora, casi un año después, he necesitado volver a programar una tarea periódica para un script de la web. Y buscando en internet me he topado con SetCronJob, un servicio gratuito (también con modalidad de pago) que te permite planificar cron jobs de cualquier host externo.

¿Las pegas de usarlo sin pagar? Muy pocas; un intervalo de 5 minutos entre ejecuciones y la caducidad de la tarea a los 3 meses (aunque renovarla es tan sencillo como volver a logear y hacer click en el botón correspondiente).

Para más información consultar el FAQ, y si la suscripción gratuita te parece poco, a contratarlo por unos precios muy reducidos.