Durante la GTC, que es el evento de Nvidia y no se debe confundir con la GDC, Nvidia hablo de la historia de su implementación del Raytracing a tiempo real y concretamente del RT Core.

La motivación detrás de ello como ya he comentado varias veces estaba en solucionar el problema de la intersección de rayos, la cual requiere recorrer una estructura de datos espacial ordenada en forma de árbol, el llamado Bounding Volume Hierarchy.

Las GPU no son muy buenas atravesando estructuras de datos en comparación con las CPUs, es por ello que Nvidia decidió crear una unidad a la que llamaron Tree Traversal Unit o TTU, la cual con el tiempo se convirtio en el RT Core por motivos de marketing. La idea no es otra que la de ordenar la geometria en un arbol pero Nvidia no no dice que tipo de arbol para ordenar la geometria utilizan.

Viendo la diapositiva uno puede deducir que la forma de ordenar la geometría es a través de una estructura de datos en Octree, pero por otro lado sabemos que no es un Octree por el hecho que estos son altamente contraproducentes por el coste que supone reconstruirlos en cada fotograma.

La geometría de bajo detalle permite unas intersecciones de rayos más rápidas que pueden ser útiles para efectos que no requieren la precisión geometrica al completo, por ejemplo en casos como Motion Blur, Reflejos Gloss (borrosos), ambient occluson e iluminación global con luz rebotada difusa. Especialmennte cuando la geometría no es visible o en reflejo especulares (tipo espejo), utilizando proxies de geometría que pueden proveer un significante aumento de velocidad con una casi imperceptible y negligible perdida en calidad.

Las ventajas de utilizar el BVH en si mismo como una representación geométrica con nivel de detalle son:

  • No es necesario el paso adicional de voxelización (el proptio BVH provee el nivel de detalle)
  • No consume tanta memoria
  • Evita la cara intersección de trianglulos cuando es posible.
  • Realiza las intersecciones de caja/rayo, en vez de tener una mezcla de intersección caja/rayo y caja/triangulo, lo cual es más eficiente en la GPU ya que evita la divergencia de hilos.
  • El BVH es almacenado en la memoria cache de la GPU, la cual es más rápida que memoria global
  • Los nodos del BVH pueden almacenar información adicional
The renderer determines the appropriate level of detail based on the distance from the camera for primary rays or on the distance from the ray origin and the ray type for secondary rays (glossy/reflection, shadow, AO or GI rays). The following screenshots show the bounding boxes of the BVH nodes from depth 1 (depth 0 is the rootnode) up to depth 12: El renderizador determina el nivel de detalle apropiado basado en la distancia desde la cámara para los rayos primarios o en la distancia desde el origen del rayo y el tipo de rayo para los rayos secundarios (glossy/reflejos, sombra, AO o rayo de ilumininación global). Las siguientes imágenes nos muestran las “bounding box” de los nodos BVH desde la profundidad 1 (del arbol) hasta la 12 (el nivel 0 es la raiz).

Una de las cosas que las GPUs más contemporaneas tienen, y que he explicado multitud de veces, es el Tile Caching o Rasterizado por Tiles donde la geometría es rasterizada por tiles según su posición en la pantalla y por tanto ordenada a priori. pero Volta/Turing tiene una enorme diferencia respecto a Maxwell/Pascal en el caso de Nvidia, no ordena la geometría en la cache de nivel 2 sino que ordena la geometría en la cache de datos de Nivel 1 a donde puede acceder la unidad TTU/RT Core.

Para ello ha sido necesario un cambio en la organización de la cache L1 de Datos:

En el caso del SM de Pascal/Maxwell la memoria compartida y la Cache L1 de datos están separadas, en el caso de Turing/Volta ya no es así. la Shared Memory/Memoria Compartida es lo que en las GPUs de AMD es llamado Local Data Share (LDS). En realidad ambos tipos de unidades tienen elementos comunes pero la LDS/Shared Memory es una memoria que en la jerarquía de Maxwell/Pascal en el caso de Nvidia y en las GCN de AMD esta a un nivel diferente respecto a la Cache L1 de datos.

Desde la Cache L1 de datos podemos exportar a:

  • A la LDS.
  • A la cache L2
  • A lo ROPS (RBE)

Pero claro, 16KB son muy pocos para almacenar el BVH correspondiente a esa parte de la pantalla, porque recordemos que tenemos la geometría ordenada en un bvh correspondiente a cada tile de la pantalla, esto ha llevado que la cache L1 aumente de tamaño y desaparezca por completo la Shared Memory/LDS como una memoria aparte, cambio que hemos visto ya en Turing/Volta en el caso de Nvidia y podríamos ver en el caso de Navi con AMD, lo cual requiere cambios internos en la organización de la Compute Unit, quizas es por eso que hay rumores confusos acerca de si Navi es una nueva arquitectura o no. En todo caso no lo sabemos y es posible que AMD tome un camino distinto pero teniendo en cuenta la estandarización de este de Raytracing para los juegos en tiempo real no creo que la solución de AMD sea muy diferente a la de Nvidia.

Ahora bien… ¿No se puede utilizar también la división por tiles de cara a estructuras de datos como por ejemplo los Octree en vez de cargarlo desde la memoria principal? La diferencia es que los Octree hacen referencia al espacio de la escena ya que es una subdivisión del mismo.

Esto provoca que dado que la organización del espacio cambie en cada fotograma y sea necesario voxelizar y hacer de nuevo ula estructura de datos en cada fotograma, lo cual es mortal para la GPU. En cambio los BVH la subdivisión no es respecto al espacio sino respecto al objeto.

Un tipo de subdivisión espacial es el KD-Tree que es un tipo de arbol binario de posición, el KD-Tree entraría en el mismo grupo que los Octree pero pudiendo llegar a una precisión mucho más alta.

Tanto el KD-Tree como el Octree toman como nodo 0 del arbol el espacio de pantalla al completo y este lo van subdividiendo a medida que vamos bajando de nivel, esto obliga que la consulta tenga que hacerse en la memoria principal de la GPU con los problemas de rendimiento que esto supone. El motivo por el cual Nvidia ha escogido el BVH por encima de cualquier estructura de datos espacial dependiente de la subdivisión del espacio de pantalla es porque el BVH se mapea mejor en las arquitecturas de GPU aparte de ser la estructura de aceleración que se construye más rápido y permite tiempos de renderizado más rápidos.

Esto es algo que se lleva años investigando:

En este trabajo, proporcionamos un análisis completo de las estructuras de aceleración de GPU para el trazado de rayos vóxel. Comparamos los octetos de uso común con los árboles BVH y KD, que son el estándar en el trazado de rayos triangular de GPU. La evaluación y el análisis del comportamiento son complicados, ya que las GPU modernas proporcionan unidades vectoriales amplias con jerarquías de caché complejas. Incluso con simuladores SIMD sofisticados, es cada vez más difícil modelar el hardware con detalles suficientes para explicar el rendimiento observado. Por lo tanto, en lugar de confiar en la simulación SIMD, usamos contadores de hardware para medir directamente métricas clave como la coherencia de ejecución en una GPU moderna. Ofrecemos un extenso análisis comparando diferentes estructuras de aceleración para diferentes escenarios de trazado de rayos, como los rayos de oclusión primaria, difusa y ambiental. Para diferentes escenas, mostramos que las estructuras de datos comúnmente conocidas por su buen rendimiento, como KD-trees, en realidad no son adecuadas para unidades SIMD muy anchas. En nuestro trabajo, mostramos que los árboles BVH son más adecuados para el trazado de rayos de GPU y explicamos cómo la estructura de aceleración afecta la coherencia de ejecución y, en última instancia, el rendimiento, proporcionando información crucial para el diseño futuro de las estructuras de aceleración de GPU.

Nvidia por otro lado llevo tiempo investigando sobre que tipo de estructura de datos era la mejor para el Raytracing via GPU y cientificamente llegaron a la conclusión de que el BVH es mejor, lo cual ha llevado que la Tree Traversal Unit que es ahora conocida como RT Core no se base en recorrer KD-Trees u Octrees.

Una vez explicada la premisa vayamos a lo que realmente me interesa comentar. Hace unos días apareció una demo de Crytek llamada Neon Noir que os comente en una entrada. El caso es que como habréis podido deducir el SVOGI y el SVOTI son la contraparte del método de renderizado utilizando el BVH como estructura de datos por el hecho de basarse en Octree. Pues bien, uno de los comentarios que me habéis dejado es el siguiente:


No veo problema en que la geometría la pasen a voxels
Cryengine ya tenía svoti y svogi
Desde ahí a que los rayos o conos funcionen como el raytracing de microsoft no debe haber mucha distancia.
De todas formas el camino a seguir es svoti como hace cryengine en vez de multiplicar el coste por graphic whorismo.

El problema es que el uso de una estructura de datos u otra supone una forma de realizar el Raytracing dispar la una con la otra y por tanto si que hay diferencia . Decir que el camino es SVOTI o SVOGI cuando precisamente la que ha marcado el estándar es Nvidia con el BVH es cuanto menos… curioso. Pero claro, yo estoy dispuesto a comer cuervo si es necesario y reconocer mis errores. Mi hipotesis es que la demo Neon Noir esta construida utilizando las librerias Radeon Rays 2.0 y yo creía que la librería de AMD se basaba en construir la escena utilizando KD-Trees, pues resulta que estaba equivocado:

Estrategias de Aceleración

La estructura de aceleración por defecto es el Bounding Volume Hierarchy (BVH) utilizando diviiones espaciales medianes. Este mantiene rápidos tiempos de construcción y provee un rendimiento en el calculo de la intersecció decente.

Dicho de otra manera, tanto Nvidia como AMD van a utilizar la misma estrategia y lo que ocurre en el caso de AMD con Vega no es diferente a lo que ocurre en las arquitecturas de Nvidia pre-Turing donde son los shaders los encargados de la intersección en vez de la TTU/RT Core al no estar esta disponible en el hardware.

Pero el paradigma de cara al futuro es acelerar dichas estructuras utilizando unidades especializadas, Nvidia ha dado el primer paso y AMD esta siguiendo los mismos por lo que no sería de extrañar ver en la Compute Unit de Navi no solo el cambio en la cache L1 de Datos y la Shared Memory que he comentado antes sino que tuviese una unidad TTU/RT Core como ocurre en Turing.

En realidad el Raytracing es posible realizarlo en GPUs sin unidades RT, pero viendo la comparación de rendimiento entre Volta y Turing (recordemo que Volta es más potente en cuanto a potencia de los shaders) el rendimiento del Raytracing va a ser cuento menos bajo ya que el calculo de la intersección es altamente costoso para los shaders y con el RT Core estos acaban reduciendose enormemente.

¿Pero a donde iría conectada el RT Core? Obviamente iría conectada a la Cache L1 de Datos, organización que ya se encuentra en Turing, aunque personalmente no se si AMD va a implementar los Tensor Cores en el caso de Navi pero no tengo dudas que dado que se esta entandarizando el Raytracing híbrido a alta velocidad si que vamos a ver una unidad TTU/RT Core pero en versión AMD posiblemente dentro de cada Compute Unit de Navi.

Esto es todo, tenéis los comentarios de la entrada y el Discord para comentar.

Anuncios