Historia del graphicwhorismo III: I see the light
STOP, aquí tienes la parte 1 y parte 2 de este reportaje. Ya puedes continuar.
Con una potencia más que respetable y la posibilidad de mover millones de polígonos por frame sin despeinarse, estaba claro que el hardware estaba listo para tirar en una dirección diferente. Y esa dirección es la iluminación.
¿Y por qué recién ahora vemos cosas así? No es simplemente por potencia pura: es que no se sabía cómo hacerlo. The Last of Us se ve jodidamente bien, pero es un conjunto de hacks sobre hacks realmente. La iluminación “dinámica” se reduce a 3 elementos: sombras “suaves” en tiempo real (que son falsas, se aproximan los volúmenes como esferas y se usa blur hasta follarse bien los píxeles), pocos puntos de luces dinámicas (¿cuántas linternas o puntos de luz puedes ver al mismo tiempo en un frame realmente? Pista: no muchas), y “falso rebote de luz” (Nota: hay también sombras “duras” con la linterna, pero son de la misma calidad que las que ya tenía Doom 3 así que mejor no las comentamos).
Alguien muy inteligente decidió hace mucho tiempo, que modelar la luz en tiempo real en una computadora era imposible. Se hicieron análisis, se postularon ideas. Raytracing en tiempo real era claramente un unicornio (sigue siéndolo), calcular cómo la luz rebota sobre todas las superficies es (era) imposible. Así que había que simplificar. La forma de hacerlo fue creando una serie de ecuaciones que dividen la luz recibida/reflejada en una serie de factores: ambiental, difuso, especular. Resumiendo: hay que violar la realidad para mostrar algo que se medio “parezca”. Obviamente, no se pareció nunca en una mierda a la realidad.
Técnica “Voxel cone tracing“. Resumiendo muchísimo: es más o menos lo que usa Unreal engine 4. Resumiendo menos: se usa una versión simplificada de raytracing en la que no se dibuja cada píxel, sino que se testea contra una versión “voxelizada” del ambiente, para conseguir simular por lo menos uno o dos rebotes de luz. El resultado final se devuelve y se mezcla con la escena – más allá de los reflejos, lo interesante es cómo la luz “sangra” sobre los colores originales de la escena y “tiñe” todo según los materiales a su alrededor.
Hasta que hace no mucho, los programadores gráficos decidieron que era hora de cambiar. Tim “Pelao” Sweeney (el hombre detrás de bambalinas del unreal engine) dijo hace unos años “la realidad visual se conseguirá sólo calculando el rebote de la luz”. Y tenía razón.
Lo que hace que la vida real se vea como se vé, no es tanto por como los materiales son, sino como la luz rebota en ellos y se dispersa. El atroz “componente ambiente” de los modelos de iluminación “clásicos” es lo que realmente mataba el realismo de todo. Calcular esos rebotes es jodidamente costoso, así que todavía se “fakea“.
El primer paso fue “romper” el sistema original de iluminación directo y hacerlo “diferido”:
en lugar de renderizar en un solo paso, se rompe en muchos fragmentos para tener distintos componentes: color (albedo), normal, especular, etc. A eso se le agrega luego el componente de cada luz. Empieza así:
De arriba abajo, de izquierda a derecha: profundidad (cuanto más blanco más cerca de la cámara) – útil para niebla, SSAO y renderizado fuera de orden de superficies transparentes (en este caso: ninguna). Normales: un truco usado para que el vector normal de cada punto sea distinto al vector normal “real” de los polígonos – necesario para normal mapping. Albedo: el “color”, llamado muchas veces también “textura difusa”. Shininess: el coeficiente de “brillo” para cada punto. O de otra forma: cómo la luz se refleja. Nótese que no hay sombras ni efectos de postprocesado – esos vendrán luego.
Y termina así:
Todas las imágenes anteriores se componen, junto con la incidencia de todas las luces calculadas por separado (en esta imagen: los ojos + ilunación “ambiente”), se agregan las partículas y demás FX y por último se retoca la imagen con postprocesado (depth of field, niebla, SSAO, bloom, pase de HDR, corrección gamma, tintado de color, vignetting y lens flare).
Todavía se usa hoy en día (es la base de la mayoría de renderers modernos). Luego lo que hicieron fue llenar las escenas con “probes”: esferas flotantes que capturan la información de la luz que llega a su alrededor desde todas las direcciones (una técnica sacada directamente del cine y los efectos especiales).
Pero… tampoco es suficiente. Así que el último paso consiste en calcular directamente por lo menos una vez cómo la luz rebota en las superficies y “recolorear”.
Una forma de hacerlo es la siguiente: en el shader de cada superficie, tomar la luz incidente en cada punto, calcular las condiciones del material, y reflejar una vez ese color con un spread usando el algoritmo de monte carlo o similar (la forma más simple es poniendo una luz radial falsa en la zona con el color de la luz reflejada). The Last of Us usa esa técnica. Una forma fácil de verlo es en el metro: si apuntas con la linterna una zona amarilla o naranja en una pared, verás que la luz alrededor se colorea de forma acorde a la luz “rebotada”.
Otras formas más esotéricas se consiguen mediante la voxelización del entorno o con una iluminación híbrida con partes de raytracing (ambos métodos usados por Unreal engine 4). Unity tira por light probes, aunque Unity siempre se vio peor – per con las nuevas mejoras en su renderer a partir de Unity 5 hace que se acorte la distancia).
¿Y el futuro? ¿A dónde vamos?
En principio vamos directo hacia el “valle de lo creepy”. Los gráficos son cada vez más realistas por la potencia de las tarjetas y por los avances en el renderizado “de la luz”. PBR (physically based rendering) es el palabrejo de moda: ya no se intenta aproximar la realidad con 3 ecuaciones chorras, sino que se simula todo usando valores realistas. The order se ve bien porque los materiales son en su mayoría escaneos de objetos de la vida real (y porque en pantalla hay un pollón y medio de filtros de blur y depth of field para que se vea “cinemático” y para ocultar que en el fondo, no tiene nada especial).
Pero la luz es el camino, y con o sin Carmack, ya se puede ver al final del túnel, que la videorealidad llegará. Virtual o no.
* * *
¿Y The Order 1886? ¿Qué tiene de malo?
Pues… para empezar: resolución recortada. Tuvieron que comerse casi un 30% de buffer (o sea: renderizar muchísimo menos) para tener potencia suficiente. Para continuar: todos los materiales “base” fueron hechos con escaneos de objetos reales (piedras, metales, tapizados, etc). No es una creación hecha a mano sino un escaneo de la vida real. No digo que esté mal, pero si vamos a crear mundos virtuales necesitamos mejores herramientas para diseñadores, y no gastar en escáneres 3d de precio descomunal, ¿no?
Pero la peor ofensa es el sistema de post-procesado: la mayoría del “realismo” (si se puede llamar así) viene por una exageración en el uso de filtros (esto es: cambios en la imagen ya renderizada). El “grano” de film es grotesco, el depth of field está hecho de forma tan brutal que no se puede ver nada a 5 metros más allá del personaje; blur de movimiento gratuito a todo y todos hace que ni un solo enemigo se pueda ver medianamente claro cuando se mueve; recolorización exagerada (nada tiene un color natural – vale que sea un “toque artístico” pero se pasaron) y demasiado vignetting (oscurecer la imagen en los bordes) son de los más ofensivos que he visto en mucho tiempo. El resultado final hace que pase por “bueno” o “muy bueno”, pero en el fondo lo que hace es intentar esconder miles de defectos que por otro lado juegos como The Last Of Us solventan con mejores modelos 3d, lightmaps y más “luz”. En el futuro, es más probable que The Last of Us sea un referente visual, pero no The Order.
Y bueno amigos, hasta aquí hemos llegado. Espero que con esta introducción al apasionante mundo de los gráficos videojueguiles entiendas ahora mejor por qué tal juego o tal otro se ve mejor o peor. Para la próxima saga, te enseñaré a construir tu propia tarjeta gráfica a partir de piezas simples, un laboratorio y €48.735. ¡Buen fin de semana!