Comentario Original:

Y entonces ¿que tipo de ray tracing lleva o puede llevar el chip de imagination? La apariencia está muy bien para ser un mero asic que no ocupa ni un 33% de un chip que de base no es muy grande. Algo se me escapa.

El PowerVR GR6500 no deja de ser una GPU pensada para la rasterización pero con una serie de elementos adicionales que ayudan a acelerar el proceso del Raytracing moviendo a unidades especializadas y de función fija (y por tanto no programables) los elementos más recursivos y que más potencia de calculo requieren, estos elementos son:

  1. La construcción de la estructura de datos que nos servirá para almacenar la posición de la geometría en escena.
  2. El recorrido de dicha estructura de datos de manera recursiva para su actualización.
  3. La comprobación de la interacción de todos los rayos de luz de la escena con cada uno de los pixeles de la misma.

La explicación simple sería que esos elementos se encuentran ya en el PowerVR y por pensamiento mágico podemos llegar a concluir que gracias a ello se puede hacer el Raytracing o más dicho un pipeline de renderizado híbrido donde se rasteriza primero (iluminación directa) y luego se calcula el Raytracing utilizando las unidades especializadas integradas en el chip, que es lo que Imagination nos explico en su día cuando lo presento en el 2014.

1_PowerVR GR6500 GPU - PowerVR Wizard GPUs

Pero hemos de tener en cuenta que pese a que hemos añadido una serie de piezas para acelerar ciertos procesos en realidad estas piezas trabajan en conjunto con las piezas de una GPU convencional, no para el Raytracing puro sino para el Raytracing híbrido que tiene un pipeline combinado de rasterización y raytracing. En este caso haciendo uso de un pipeline pensado para el Deferred Rendering para extenderlo aún más.

08_Ray-tracing-in-games_Hybrid-rendering-in-a-game-engine

Pero hemos de tener en cuenta que el PowerVR tiene la particularidad de no ser una GPU al uso sino un Tile Renderer y esto es importante porque los Tile Renderers tienen o al menos tenían una ventaja enorme a la hora de ser adaptados para el Raytracing y es lo que voy a intentar explicar en esta entrada.

¿Como funciona un Tile Renderer? Muchos de los que sois habituales en el blog lo sabéis pero un Tile Renderer es un tipo de GPU que en vez de renderizar los fotogramas al completo lo que hace es renderizar porciones de fotogramas a las que llamamos Tiles.

tilebuffer

Cada Tile en los PowerVR es de unos 32×32 pixeles y esto significa que a la hora de renderizar en vez de utilizar buses de imagen gigantescos utilizamos uno lo suficientemente pequeño como para colocarlo en la memoria interna de la GPU y evitar de esta manera tener que tocar la memoria principal. Esto significa que los ROPS que son las unidades que escriben el backbuffer no la escribirán en la RAM asignada al video y solo el Frontbuffer será el que terminara en la RAM asignada a la GPU.

¿Y que elementos forman el Backbuffer? Pues principalmente 2, el Color Buffer que almacena el color de cada pixel y que puede tener varias muestras para lo que es el renderizado en diferido y el Depth Buffer que almacena la distancia de cada pixel respecto a la cámara y nos sirve para saber si el pixel correspondiente a un objeto rasterizado se muestra o esta opacado por otro que hay detrás.

Precisamente el hecho de tener el Z-Buffer en una memoria interna nos permite realizar lo que es el Hidden Surface removal que no es otra cosa que eliminar los pixeles no visibles al estar opacados por otros al haber otro objeto delane, el handicap del Hidden Surface Removal aplicado antes de la étapa de Texturizado+Fragment o Pixel Shader es que no sabemos el valor de la transparencia en el objeto y con escenas con transparencias esto es un problema porque el Hidden Surface Removal es inefectivo.

Ahora bien, con lo que quiero que os quedéis es que el Z-Buffer almacena información de la posición de cada objeto relativa al punto de vista del observador, pero solo la profundidad y con un eje de datos no hacemos suficiente. ¿Como obtenemos la posición en X e Y?

Los Tile Renderers al contrario de las GPUs convencionales son arquitecturas del tipo Middle Sort, esto significa que ordenan la escena después de calcular la geometría de la escena pero antes del rasterizado.

sortmiddle

En el caso del PowerVR lo que se hace es crear una lista de pantalla por cada tile antes de la rasterizacion para ordenar la geometría.

tiletriangle

Esto se almacena en una serie de Tile Buffers que corresponde cada uno a un Tile, estas se almacenan en buffer conjunto llamado Parameter Buffer. El Parameter Buffer no es más que una lista de Tiles que representan la pantalla o parte de la pantalla, en el caso de los PowerVR habra tantos PBs como «clusters» ya que cada uno de los clusters trabajara en una porción regular de la pantalla y tomando un Tile de 32×32 pixeles de esa porción.

powervr-series7xt-gpu

Por ejemplo si renderizamos con una PowerVR GT7200 tendremos 2 Parameter Buffers, si renderizamos con una PowerVR GT7900 entonces tendremos 16 Parameter Buffers.

ParameterBuffer.jpg

Así pues nos encontramos que antes de la rasterización la GPU ha construido una estructura de datos con las listas de los triangulos (geometria) y su posición respecto a cada Tile por lo que tenemos una estructura de datos construida por parte de la GPU que la podemos utilizar como la estructura de datos que necesitábamos en el punto 1. ¿Cierto? Pues no, porque lo que tenemos una estructura de datos de tipo lista…

LinealDataStructure.PNG

Necesitamos convertir dicha estructura de datos lineal en una jerarquica, en este caso si hacemos caso a Imagination en un Octree regular de 3 niveles (8^3=512 subdivisiones).

SceneHierarchy1

De esto se encarga el Scene Hierarchy Generator que es la pieza de función fija que construirá el Octree.

SceneHierarchy2

Al final de la etapa de renderizado cada Tile procesado será voxelizado. Esta información en conjunto con la información del Parameter Buffer le permitirán sin participación alguna de los Shaders al Scene Hierarchy Generator generar el Octree e incluso recorrerlo.

En las siguientes diapositivas se explica el proceso de manera visual.

SceneHierarchy3SceneHierarchy4SceneHierarchy5

Tened en cuenta que las GPUs por su arquitectura son altamente ineficientes a la hora de realizar este tipo de tareas. Como ya habréis deducido de las anteriores entradas que he ido haciendo esta semana sobre este tema dicha estructura de datos es utilizada para poder calcular la intererseccion de los rayos con los objetos de la escena.

 

Step-1-Ray-tracing-pipeline-scene-hierarchy-generation

En el caso de las GPU convencionales con las Rasterización por Tiles se ha adoptado el Middle Sort en las últimas GPUs de PC (Maxwell en adelante pero al contrario que los Tile Renders no se genera un Parameter Buffer por lo que en el caso de implementarse el Scene Hierarchy Generator con tal de generar el Octree y recorrerlo este tendría la misma funcionalidad pero diferente funcionamiento dado la inexistencia del Parameter Buffer en una GPU convencional.

El Pixel Local Storage

El Pixel Local Storage es una memoria en la que en el caso de los Tile Renderers se pueden escribir los resultados de los Fragment/Pixel Shader para realizar a continuación una etapa de post-procesado sobre los mismos. La particularidad del PLS es que su uso hace bypass a la etapa de Blending.

PixelLocalStorage2.PNG

Lo que significa hacer Bypass a los ROPS desde el Pixel/Fragment Shader, por cierto que las diapositivas son de la arquitectura Mali de ARM que también tiene un PLS pero su utilidad es la misma.

 

PixelLocalStorage.PNG

El PLS es lo que permite el Deferred Rendering en una GPU basada en Tiles, pero nos va a permitir a hacer cosas como la Voxelización del Tile y aplicar el Raytracing sin que ese Tile impacte a la memoria principal para luego tener que recuperarlo. El PLS es uno de los elementos del hardware de las GPU de Smartphone que «podrian» aparecer en futuras GPUs de sobremesa…

FIG1B

tenor.gif

¿Cual es el Raytracing utilizado en el PowerVR Wizard?

En vez de aplicar el Ray Tracing a toda la escena entera lo aplicamos Tile por Tile, donde realmente cada Voxel almacena un Tile, haciendo que el algoritmo al final sea el siguiente:

Genera Rayos a través del Frame Shader y almacenalos en una Cola.
Mientras haya Rayos en Cola
 Escoge un Voxel/Tile Volumétrico a Procesar 
 Intersecciona el Rayo con el siguiente pixel del Voxel
 Si hay Intersección
  Por cada Rayo en el Voxel
   Calcula el BDRF y ejecuta el Ray Shader
   Añade los Rayos Generados de manera Indirecta a la Cola 
   Si la Superficie es Emisiva
    Almacena su contribución a la Radiancia de la Imagen
 Si no hay intersección: 
  Avanza al Siguiente Pixel del Voxel/Tile Volumétrico

Obviamente la potencia a la hora de realizar el Raytracing es limitada a la cantidad de rayos que se pueden ser emitidos y procesados. ¿Pero que tipo de Raytracing utiliza? La respuesta es el Whitted Raytracing y es que el pipeline gráfico en este caso es curioso ya que el calculo de la iluminación en diferido no se realiza a priori de la etapa de Raytracing sino a posteriori porque el Whitted Raytracing como sabréis no puede calcular la luz indirecta difusa y para ello se necesita el Path Tracing/Ray Tracing Montercarlo e en una versión más simplificada la Radiosidad (sin poder combinar ambos tipos de luz).

Con esto supongo que habré solventado en lo máximo posible por mi parte tu pregunta.