Voy a responder en esta entrada un par de preguntas que me llegaron via Curious Cat.

¿Qué tal Urian?

Psche… Bien.

Ya que estamos con el tema del raytracing y el ultra realismo en videojuegos me encantaría hacerte 2 preguntas.

Veré que puedo hacer

¿Se puede actualmente simular humo ultra realista o un chorro de agua los cuales interactúen con la física del entorno en un videojuego, o falta tiempo para que podamos verlo?
Yo pregunto porque sigo viendo falso humo compuesto de texturas semitransparentes que siempre atraviesan las paredes.

Esto es interesante porque has tocado uno de los temás más delicados de la rasterización contemporanea, el de la casa de cristal.

casa-cristal1-a.jpg

El miramos el algoritmo Z-Buffer veremos que en su naturaleza tiene un problema enorme que es el overdraw que no es otro que cuando dos o más pixeles se encuentran en una misma posición el que esta más cercano a la cámara debería ser por lógica el que se dibujará.

Por cada fragmento 

{ Por cada pixel del objeto proyectado a la pantalla. 

{ Sí Z del Pixel es más cercano que el valor existente en el Z-Buffer 

{ Actualiza el Color Buffer con el color resultante del shader resultante del objeto sobre el pixel. 

Actualiza el Z-Buffer } } }

Al hecho de tener que procesar por posición de pantalla pixeles de más se le llama overdraw. Pero en el pipeline de rasterizacion pese a que conocemos la Z (profundidad) del pixel asignado una vez se han rasterizado los polígonos en fragmentos, aún no hemos texturizado el objeto, desconocemos por completo el canal alfa que es el nivel de transparencia del objeto que nos debería permitir ver o no el objeto que hay detrás. Es por ello que cuando tenemos una escena con un objeto transparente los algoritmos de eliminación de pixeles «no visibles» no se pueden aplicar por el hecho eliminariamos buena parte de los pixeles de la imagen.

Tampoco podemos aplicar las técnicas de Culling durante el pre-renderizado, por el mismo motivo. Cuando un objeto transparente o semi-transparente aparece en la escena rompe por completo todos los algoritmos de eliminación de geometría no visible (Culling) y de pixeles no visibles, en el último caso es crucial como bien sabréis porque la mayor carga computacional se encuentra en la etapa del texturizado y si podemos reducir al máximo posible los pixeles en forma de fragmentos que se procesan en esa étapa sin reducir la calidad de imagen mejor que mejor.

DiamondStructure

Luego tenemos el tema de las particulas, desde que Direct3D 10/OpenGL 3 aparecieron en el mercado se añadio un Shader adicional a la etapa de la geometría previo a la rasterización llamado Geometry Shader. Los Geometry Shaders trabajan con la geometría de la escena una vez que esta ha sido procesada, pero antes de la transformación de la geometría en fragmentos y por tanto antes de la rasterización.

shader_full

En Direct3D 11 se añadieron el Hull Shader, Teselador y Domain Shader a la ecuación pero en Direct3D 10 y equivalente se comunicaba el Vertex Shader directamente con el Geometry Shader. ¿Que puede hacer el Geometry Shader? Pues crear o eliminar geometría principalmente sobre la ya existente.

b3d31b3d32b3d33

Mucha gente lo confunde con el teselador que simplemente realiza sub-división de superficies pero el teselador no puede crear geometría nueva. ¿Aplicaciones visuales del Geometry Shader? La primera de ellas,  si os fijáis tiene un contacto directo con la memoria, esto es debido a que lo que antes se llama Vertex Texture Fetch que era el darle acceso al Vertex Shaders  a la información de las texturas fue colocado como estándar en el Geometry Shader permitiendo la aplicación del Displacement Mapping.

displacement_vs_bump

Dado que también se puede utilizar para generar geometría es ideal para la creación de particulas para crear nubes volumétricas de todo tipo …

cloud-matthias

Pero nos encontramos con que dichas nubes no suelen llevar particulas semi-transparentes, el motivo de ello son los problemas con las transparencias que he comentado antes.

Pero hay un problema, el hecho de tener una particula de este tipo es un problema en cuanto a rendimiento. Para empezar el rasterizador tiene un limite en la cantidad de gemetría que puede rasterizar, para que la gente lo entienda, por ejemplo en las GPUs de AMD es posible transformar un triangulo/polígono en un fragmento que puede ir de los 1×1 pixeles a los 8×8 pixeles. ¿Cual es el problema? Pues que los Pixel/Fragment Shaders trabajan en grupos de 2×2 por lo que si tienes partículas unitarias, es decir de 1 pixel, te vas a encontrar con que el trabajo de «texturizado» aumenta considerablemente. Sumadlo al problema del overdraw y tendréis un enorme cuello de botella en cuanto al rendimiento a la hora de renderizar la escena que los desarrolladores prefieren evitarlo.

¿Que es lo que hacen hoy en día la mayoría de desarrolladores? Pues basicamente lo que hacen es calcular las particulas aparte… ¿Como? Pues como efecto de post-procesado a través de los Compute Shaders, pero esto no sustituye a la forma de ejecutarlos en el pipeline gráfico sino que depende de como este planteado cada juego a nivel gráfico.

¿Puede solventar el problema el Raytracing? El problema es que lo que vamos a ver es un mecanismo híbrido donde la primera parte del pipeline gráficos será la rasterizacion por lo que seguiremos teniendo ese problema, es más, en las demos presentadas estos días en la GDC han procurado eliminar las transparencias de dichas demos  y los motivos después de lo que os he explicado deberían ser más que claros.

Si a partir de GTA 4 se implemento el motor Euphoria ¿Por qué las desarrolladoras no investigan en la simulación de movimiento o licencian Euphoria como lo hizo Rockstar Games? Pregunto porque pienso que se ahorrarían mucho dinero en animar manualmente los personajes.
Un saludo.

Este es otro tema, personalmente la aplicación de las neural networks/tensor cores creo que va a revolucionar enormemente el mercado de la animación. Motores como el Euphoria tiran de CPU en su animación y nos encontramos que cuando la cantidad de personajes en pantalla aumenta considerablemente entonces la carga sobre la CPU y esto ha sido el talón de aquiles de la actual generación porque la mayoría de desarrolladores pese a que saben que pueden realizar esto via GPU no quieren sacrificar el nivel visual y solamente tirán del cálculo de la animacion via GPU cuando existe la suficiente potencia disponible… Para la CPU tener que animar cientos de miles o millones de partículas en pantalla es una sobrecarga enorme para la misma.

¿El ejemplo más claro? Lo vimos a principios de esta generacion con Assassin’s Creed Unity.

ubisoft-cloth-simulation-ps4-vs-ps3

Lo que hacemos en el pipeline gráfico es renderizar un instante concreto y fijo, no renderizamos un intervalo de tiempo por lo que la animacion no es procesada durante el pipeline gráfico por lo que se tiene que ejecutar via CPU o via GPU… Sacrificando en el último caso parte de la potencia gráfica.

2918553-old_xdk_ubisoft_benchmark

¿Que es la animación de una escena en 3D a tiempo real? No deja de ser el desplazamiento de los vertices y obviamente cuantas más vertices tengamos en escena necesitaremos más y más potencia de la CPU o de la GPU (en el caso de utilizar esta para la animacion). ¿La solucion para la siguiente generación? Nos están hablando del uso de los Tensor Cores para la generación de animacion de manera directa a través del Motion Capture pero no os dejéis engañar por eso, porque en ese aspecto no existe el nivel de interactividad que tenemos en los videojuegos. ¿Es posible acelerar la animación a través de los Tensor Cores o que estos la generen a través de su proceso de aprendizaje? Posible es.

La idea de utilizar las Neural Networks/Tensor Cores para la animación de una escena es algo que ya lo podéis ver en cosas como los Emojis en 3D del iPhone X y teléfonos similares donde la animación de la caricatura no esta pre-establecida sino que es calculada y procesada por un procesador de este tipo. Obviamente la potencia en los Tensor Cores de una GPU dedicada es enorme en comparación. Es decir, utilizar la IA para que la escena se anime completamente sola y de una manera mucho más rápida que la de los Compute Shaders.

Con estos métodos el coste de la animación en la producción bajara enormemente en los juegos pero hemos de tener en cuenta que la potencia de los sistemas seguira teniendo un limite. El hecho de tener que procesar la animación por cada uno de los personajes es algo que será muy tedioso… ¿Entonces? Simple y llanamente no creo que veamos la predicción de la animación via Deep Learning pero si que vamos a ver el uso del hardware especializada para la misma para acelerar la ejecución de la misma y reducir el tiempo para procesarla.

En todo caso, paciencia… En ese elemento la cosa esta muy verde y el uso de este tipo de unidades aún no se ha estandarizado en los videojuegos.