Así es como la CPU y la GPU afectan al rendimiento en Ray Tracing

No hay ninguna duda que los fabricantes de tarjetas gráficas han empezado la transición hacia el uso generalizado del Ray Tracing en los juegos, periodo que va a suponer varias generaciones de tarjetas gráficas y es que el trazado de rayos requiere de una alta potencia para funcionar. Pero, ¿Qué factores afectan al rendimiento en el Ray Tracing? Os lo explicamos.

Tener la CPU o la GPU más potente no vale a día de hoy para que los juegos que utilizan trazado de rayos vayan como la seda. Incluso a día de hoy con esta técnica siendo utilizada de forma tan primitiva, el rendimiento en el Ray Tracing no es el esperado. ¿Qué fenómenos son los que lo afectan?

¿Cómo afecta la CPU al rendimiento en el Ray Tracing?

CPU Render

Ya os hemos hablado de los volúmenes delimitados o BVH más de una vez en diversos artículos, pero a día de hoy estos no son generados por la GPU, sino que los juegos utilizan un BVH general para el nivel, el cual le permite a esta posicionar los diferentes elementos de la escena según la posición del jugador. ¿El uso más común? Pese a que es la GPU la que renderiza la escena, en cada fotograma la CPU ha de calcular el estado de cada uno de los elementos.

Es por ello que en los juegos se suelen utilizar estructuras de datos espaciales como mapa del nivel, las cuales sirven para localizar la posición de cada elemento en pantalla respecto al jugador y la estructura del nivel. De esta manera se localizan todos los esfuerzos de cálculo en lo que ocurre cercano a donde se encuentra su avatar y que el jugador puede ver en ese momento.

No-Clip Quake

Hay trucos en varios juegos que nos permiten salir de los extremos de un mapa o incluso ver todo lo que ocurre en el escenario al mismo tiempo. Cuando lo hacemos entonces el rendimiento del juego baja en picado. Pues bien las estructuras de datos espaciales son generadas por la CPU, ya que son la herramienta que utiliza para descartar de la escena todo aquello que no es visto por el jugador y que por tanto sería una pérdida de recursos tener que calcularlos al mismo tiempo.

La CPU por tanto cuando crea la lista de pantalla para que sea calculada por la GPU lo que va a hacer es crear una lista de pantalla en dicho fotograma con todos los objetos a la vista del jugador y le será completamente igual que sea matemáticamente correcto que más allá del espacio de visionado hayan elementos que también afectan a la escena.

Al mismo tiempo también se encarga de actualizar el BVH en cada fotograma y entregarlo renovado a la GPU. Dado que en el BVH los elementos estáticos del nivel no se mueven, pero los móviles cómo NPCs, personajes o el mismo jugador sí que lo hacen en cada nivel y es la CPU la encargada de actualizar el estado de cada uno.

GPUs y rendimiento en el Ray Tracing

GPU AMD VRAM

Las GPU son los procesadores para el procesamiento en paralelo por antonomasia, tanto es así que llevamos años en los que en la computación de alto rendimiento, o HPC, estas se utilizan para acelerar las partes en paralelo de los diferentes programas. Siendo el Ray Tracing una de las aplicaciones que más se benefician de la paralelización y por tanto más se benefician en apariencia de la potencia de las GPUs, no obstante, aún estamos muy alejados del paradigma ideal en que las GPUs tal y como las conocemos ahora sean el hardware ideal para el Ray Tracing.

En el Ray Tracing al igual que en el otro algoritmo para generar gráficos en 3D, la rasterización, lo que hacemos es coger una colección de objetos en un espacio en tres dimensiones y lo representamos en un espacio de dos dimensiones compuesto por una matriz de píxeles que es la pantalla. No obstante, nunca se ha conseguido que una GPU renderiza a tiempo real una escena basada en el Ray Tracing a la misma velocidad y con el mismo rendimiento que con la rasterización.

El Ray Tracing no depende de la resolución

ray tracing amd

Decir esto puede parecer atrevido para muchos, al fin y al cabo el rendimiento a renderizar a FHD no es lo mismo que a QHD o 4K. Las variaciones en el rendimiento son dispares, pero una vez entendáis a qué nos referimos vais a entender el porqué hablamos de que no depende de la resolución.

El algoritmo original del Ray Tracing habla de hacer impactar los rayos primarios y secundarios de la escena contra cada uno de los píxeles de la escena. Esto requiere mucha potencia, por lo que en vez de utilizar el algoritmo original, lo que se hace es utilizar estructuras de datos espaciales como el BVH con tal de acelerar el algoritmo. Ya que sin la estructura de datos espacial, el Ray Tracing necesitaría una enorme potencia de cálculo. Data center

De ahí el uso de estructuras de datos espaciales en forma de árbol para acelerar el rendimiento de las GPU en Ray Tracing. No obstante, los juegos a día de hoy tienen escenas extremadamente complejas cuya estructura de datos utilizada para la intersección no se puede almacenar en las cachés de la GPU debido a su tamaño. Por lo que se hace es copiar fragmentos de la estructura en la caché de la GPU desde la VRAM a medida que son necesarios.

El otro truco es cómo ya sabréis a estas alturas es el uso de hardware encargado de realizar el cálculo de la intersección de cada rayo con la estructura de datos. Se trata de un cálculo que se realiza de manera continua y recursiva y acabaría consumiendo recursos en gran cantidad a la GPU, por eso con estas unidades vemos aumentos de rendimiento de entre cinco veces y una orden de magnitud.

El problema de la localización de los datos

BVH recorrido

En realidad no estamos representando el trazado de la luz, debido a que en la vida real la luz no tiene tiempo y por su velocidad se encuentra en todos los lugares a la vez. Por lo que la estructura de datos no representa o lo que es la trayectoria de un rayo de luz en la escena, sino que partes de la escena que se ven afectadas por el mismo.

Lo que hacemos es organizar los objetos de la escena en conjuntos que llamamos volúmenes delimitados, de tal manera que se interpreta que si el rayo no pasa por un volumen delimitado entonces no afectará a los objetos, otros volúmenes delimitados, que se encuentren dentro de su conjunto.

NVIDIA BVH

Lo primero que podemos pensar es que sería buena idea dividir el espacio de la escena de manera regular. De tal manera que de una parte de la escena se encargue una parte de la GPU y de otra parte de la escena otra parte de la misma. Dicho de otra manera, sería como coger un mapa y delimitarlo por cuadrantes, haciendo que la información de cada cuadrante o incluso subcuadrante sea almacenado por los diferentes niveles de la caché. Se trata de un método que funciona muy bien con el rasterizado.

En el trazado de rayos en cambio, nos podemos encontrar que si dividimos una escena en varios subespacios que un solo rayo de luz pase por diversos subespacios, los cuales pueden estar asignados a diferentes elementos de proceso en la GPU. Es por ello que lo que se hace es tomar un camino totalmente distinto, no se divide la escena según los píxeles que se ven afectados por cada rayo, sino que se cataloga cada rayo según las áreas de la escena que atraviesa.

El ejemplo del vehículo y el mapa

Mapa Vehiculo

Para entender mejor la situación, supongamos que tenemos que marcar el trazado de un vehículo encargado de realizar entregas en un mapa. ¿De qué forma lo podemos hacer? La primera de ellas consiste en crear el mapa y dibujar el recorrido. La segunda no es otra que hacer una lista de las áreas del mapa por las que ha pasado el vehículo para luego construir su recorrido más fácilmente.

En el segundo caso podemos reconstruir por completo el recorrido convirtiendo este en un recorrido lineal. Al fin y al cabo solo nos interesa por donde ha pasado el vehículo y no por donde no ha pasado, por lo que en el caso de utilizar un mapa buena parte de la información sería superflua y la podríamos descartar al no aportarnos nada.

Pero el hecho de crear una lista ordenada no quita que quien conduce el vehículo tenga que recorrer una gran cantidad de kilómetros para sus entregas. Esa información no se tiene en cuenta y lo mismo ocurre con el rendimiento en el Ray Tracing, cada uno de los rayos tiene un coste computacional distinto, no solo por tener un recorrido diferente, sino por el hecho que no sabemos los saltos a memoria que tendremos que hacer.