Comentario #1:

Hola Urian, “creo” que en una entrada explicaste que para activar el raytracing hacían falta 2teraflops de potencia, si la Ps5, finalmente tiene uno 14 Teraflops, no sería ningun drama que la consola consumiera 2T para la iluminación.

¿ quizás en esa entrada te referías a 2T para 2k? Para 4k serían 8T … si es así quedaría al nivel de una XBonx one x con el hardware que has mencionado.

En cuantas cosas de lo que he dicho en los párrafos anteriores me he equivocado.

Es un gusto leerte.

PD: Creo que se trataba de una entrada donde algún responsable de EPIC hablaba del Unreal Engine y del motivo por el que el RT no estaba activado.

Antes de ayer hice una entrada para explicar el tema del Raytracing, os recomiendo a todos leerla para entender mejor ciertos conceptos que mencionare en esta entrada. Lo que tengo muy claro es que a la cita que te refieres a es a lo siguiente:

sweeneytflops

Lo de los 2.5 TFLOPS es acerca de la potencia necesaria para aplicar Iluminación Global via Rasterización aplicando una técnica llamada SVOGI para el Unreal Engine 4 que al final descarto al final por la alta potencia que requiere dicho algoritmo para la iluminación global, pero su funcionamiento se puede ver en la Elemental Demo que Epic mostro en el 2012.

Pero par entender el motivo por el cual fue descartado tenemos que entender antes de nada que son las técnicas de sub-división del espacio y un tipo de estructura de datos que son los Octree.

Las técnicas de sub-división del espacio son métodos que considera el total del espacio del objeto (3D) y de alguna manera etiquetan cada punto del espacio de acuerdo a lo que ocupe el objeto en el espacio. Las técnicas de subdivisión del espacio se basan en un simple elemento cúbico llamado voxel que es un elemento primitivo y es el cubo más pequeño utilizado en una representación. Podemos dividir todo el espacio en en voxeles cúbicos regulares y etiquetar cada voxel de acuerdo a sí se encuentra en un objeto o en el espacio vació. La forma más común de organizar los voxeles en datos es el uso de un octree, una estructura de datos jerarquica que describe como los objetos de una escena son distribuidos a través del espacio tridimensional ocupado por la escena.

Octree

En el caso de la ilustración de arriba, (a) es la representación general de un Octree y (b) se refiere a como se «representaría» ese objeto en el Octree. Obviamente no vemos las escenas compuestas por Octrees pero gracias a ello podemos saber sin problemas que espacio de la escena ocupan cada uno de los objetos en una representación tridimensional del mismo.

Esto implica que el uso de los Octrees en el renderizado es por tanto la organización de una escena que contiene varios objetos, la cual por lo tanto esta construida por muchos polígonos en una estructura de ocupación espacial. No se representan los objetos utilizando los voxeles sino que estos nos sirven para almacenar donde se encuentran los objetos. En una hoja del Octree podemos incluir referencias a los objetos, varios objetos, partes de objetos o incluso simples poligonos que se encuentran en el area ocupada por ese voxel y que esta representa en el Octree. Su existencia es debido a que para cualquier tipo de iluminación global necesitamos una estructura de datos en la que colocar ordenadamente la geometría.

Pe… pero Urian… En la entrada Raytracing, Radiosidad y Path Tracing no hablabas de los Octree sino de los KD-Tree.

Cualquier estructura de datos para almacenar la informacións sobre la geometria de la escena nos es válida, unas son más precisas que otras pero a cambio de ser mucho más lentas a la hora de aplicarse. El motivo por el cual necesitamos una estructura de datos para la geometría es porque de cara a realizar el calculo de la interesección con los objetos en el Raytracing necesitamos tener almacenados donde se encuentran estos en el espacio tridimensional con mayor o menor precisión. Obviamente esto no lo necesita el rasterizado y las GPUs que renderizan utilizando dicho algoritmo es obvió que carecen de algo que no es esencial.

¿Que es lo que se hace? Voxelizar la escena, aunque lo primero que hacemos es renderizar la escena teniendo solo en cuenta lo que es la iluminación directa. Es decir, ignoramos por completo la iluminación generada por los objetos por el impacto de la iluminación directa a la hora de renderizar la escena pero no la renderizamos a en forma de búfer de imagen convencional sino de manera voxelizada.

Voxelization2

Novus-VXGITest-2015-05-03-14-10-27-55.png

Esto no es lo que vamos a mostrar en pantalla sino que nos va a servir como estructura de datos después. El tiempo de generar el Octree dependerá de la precisión, de los niveles del mismo.

Octree-subdivision

Una vez tenemos el Octree generado toca calcular la iluminación indirecta dinámica. ¿Como? Aplicando sobre el Octree una técnica llamada Cone/Beam Tracing y ya que hemos llegado a ese punto lo mejor es dar una definición. Por cierto lo de Beam es porque es el apellido de quien publico el algoritmo en 1984. Basicamente la idea es que en vez de proyectar un rayo por cada pixel lo que hacemos es proyectar conos de luz.

TC 12

Esto reduce enormemente la cantidad de intersecciones a calcular porque en vez de aplicar el algoritmo de intersección a cada pixel de la escena lo aplicamos a menos precisión. ¿A que nivel de precisión? Pues a nivel de voxel/nodo del octree.

El algoritmo sería más o menos algo así:

Genera una cantidad de Conos de Luz y guarda la lista en una cola(*).
Mientras haya conos de luz en la cola.
{
Por cada voxel en el Octree 
 Calcula la interseción del cono con la geometría del Voxel. 
  Si hay intersección 
   Ejecuta el Fragment/Pixel Shader y calcula el BRDF 
   Inserta el resultado en el nodo de Octree correspondiente al Voxel 
   Si la superficie es emisiva 
    Almacena la contribución de la radiancia a la imagen 
   Fin del proceso. 
  Si no hay intersección. 
   Avanza al siguiente cono de luz en la lista de conos de luz.}

(*) Una cola (también llamada fila) es una estructura de datos, caracterizada por ser una secuencia de elementos en la que la operación de inserción push se realiza por un extremo y la operación de extracción pop por el otro. También se le llama estructura FIFO (del inglés First In First Out), debido a que el primer elemento en entrar será también el primero en salir.

Obviamente la representación de la luz es menos precisa que si la hiciesemos a nivel de pixel pero tenemos una forma simplificada de realizar iluminación indirecta dinámica tanto para luces indirectas producidas por superficies especulares como difusas. ¿Parece bonito no? Pues ahora viene el cubo de agua fria, es decir, la ducha de realidad.

 

 

Cuando Sweeney hablo de los 2.5+ TFLOPS estaba comentando el hecho que la demostración se estaba ejecutando en una GeForce 680 con una potencia de 3 TFLOPS en el video de arriba de la Elemental Demo. ¿El handicap? El video de arriba se renderizaba a una resolución de 1080p30 y para actualizar el Octree por cada objeto en movimiento de la escena consumia unos 5ms, por lo que si tuvieramos unos 6 objetos dinámicos la generación del Octree tardaría unos 30ms solamente dejando solo 3ms de tiempo, por lo que la técnica es inviable para el renderizado a tiempo real dedicado a los juegos.

¿Y esto a que es debido? En la entrada La Naturaleza de los Shaders lo explique.

Pero aquí lo voy a resumir. Basicamente las ALUs que ejecutan los programas shader en una GPU no están pensadas para ejecutar instrucciones en Los Shaders nunca, absolutamente nunca ejecutan en modo directo ni indirecto. Solo en modo inmediato que se traduce en que solo pueden ejecutar instrucciones del tipo instruccion+dato a procesar y no pueden procesar instrucciones del tipo instrucción+dirección de memoria de manera eficiente ya que son extremadamente lentas y mucho menos recorrer una estructura de datos compleja a suficiente velocidad por lo que recorrer el Octree es un problema.

¿Que es lo que se hizo? Pues simplemente simplificar el algoritmo eliminando el Octree y  almacenando la escena voxelizada en forma de textura 3D, dicho de otra manera, en una matriz cubica.

directx-11-3-volume-tiled-resources

volume-tiled-resources

Pero seguimos teniendo el problema de tener que recorrer toda una estructura de datos… ¿Como lo solventamos? Pues utilizando las Texturas Parcialmente Residentes con tal de ir cargando en pequeños trozos dentro de la memoria interna de la GPU.

 

prt1prt2prt3

Pero en el caso que nos ocupa el concepto sería el de mover las tiles 3D del búfer generado por la voxelización uno por uno hacía la memoria interna de la GPU.

Axxtgrx

Las Texturas Parcialmente Residentes tienen su implementación a nivel de API en DX11.3 y a nivel volumetrico en DX12. El mecanismo para el PRT esta integrado de serie desde la GCN 1.0 y posteriores por lo que se puede aplicar en dicha arquitectura. El problema es que tampoco es la panacea ya que:

  • La cantidad de conos de luz (fuentes de luz) que apliquemos en la escena dependerá realmente de la potencia que tenga nuestro sistema.
  • La precisión del Octree dependerá realmente de la potencia que tenga nuestro sistema.
  • Utilizando el Octree nos podemos saltar los espacios vacios, aquí vamos a ver como la GPU realiza todas las comprobaciones de intersección en todos los Tiles 3D y eso un consumo de recursos enorme.

Por cierto, el único juego en aplicar el Cone Tracing en la actual generación es el Tomorrow Children.

 

Por cierto, os recomiendo leer el post-mortem tecnológico del juego. Esto os ayudará a entender que incluso sin el Octree por el medio el Cone Tracing es una técnica que requiere una gran potencia computacional. Y por otro lado, perdonad por no responder al resto de comentarios, pero he pensado que esto requería una explicación introductoria bien detallada sobre lo que es el Cone Tracing.

¿Que pretendo con ello? Pues mostar que el Cone Tracing es una versión «ligera» del Ray Tracing y que comparten los siguientes problemas:

  • Necesidad de una estructura de datos espacial que las GPUs tienen problemas para recorrer.
  • El continuo calculo de la intersección de los rayos/conos.

Y con esto termino esta entrada.