¿Cómo puedo rastrear una escena que no cabe en la memoria?

11

Si la escena que se va a rastrear no se puede almacenar en la memoria, entonces, sin agregar más RAM a la máquina, parece poco realista procesarla en un lapso de tiempo práctico, debido a la necesidad de cargar diferentes partes de la escena desde el disco potencialmente varias veces por píxel .

¿Hay alguna forma de evitar esto? Estoy tratando de pensar en alguna forma de realizar una gran cantidad de cálculos que involucren un subconjunto particular de la escena de una sola vez, para reducir la cantidad de veces que necesita cargarse en la memoria. ¿Hay alguna otra forma de mejorar la velocidad en tal caso?

trichoplax
fuente

Respuestas:

10

Si la escena no cabe completamente en la memoria, está entrando en el campo de la representación fuera del núcleo. Aquí hay esencialmente dos enfoques: a) Generar su escena a pedido b) Cargar su escena a pedido

El primer enfoque se alinea bien con la mayoría de los flujos de trabajo de animación, donde los modelos se subdividen en gran medida usando, por ejemplo, Catmull-Clark y pueden volverse muy intensivos en memoria, pero las mallas base se ajustan fácilmente a la memoria. Pixar tiene algunos documentos sobre esto (por ejemplo, diferenciales de rayos y almacenamiento en caché de geometría multirresolución para el trazado de rayos de distribución en escenas complejas ), pero la esencia de esto es que los modelos solo se subdividen cuando son golpeados por un rayo, y solo se subdividen tanto como se razonable para tal rayo (por ejemplo, la interreflexión difusa necesita menos precisión que los reflejos de espejo). El resto lo maneja un caché de geometría, que mantiene los modelos subdivididos en la memoria y, con suerte, hace que el proceso sea eficiente mediante una buena estrategia de desalojo.

Mientras todas las mallas base quepan cómodamente en la memoria, puede salir fácilmente del núcleo y renderizar mallas en niveles de subdivisión que nunca encajarían en la memoria. El caché de geometría también se adapta muy bien con la cantidad de memoria que tiene, lo que le permite pesar la RAM frente a los tiempos de representación. Esto también se usó en Cars , creo.

El segundo enfoque es más general y no se basa en el uso intensivo de la subdivisión. En cambio, se basa en el hecho de que su escena probablemente fue hecha por un artista y ya se divide en objetos razonablemente pequeños que caben en la memoria individualmente. La idea es mantener dos jerarquías (árbol de kD o jerarquía de volumen delimitador): una jerarquía de nivel superior que solo almacena cuadros delimitadores de los objetos en su escena, y una jerarquía de bajo nivel que almacena la geometría real. Hay una jerarquía de bajo nivel para cada objeto.

En este enfoque, lo ideal es que ya almacene un cuadro delimitador junto con cada objeto en el disco. A medida que se carga la escena, solo construye la jerarquía de nivel superior inicialmente, lo que significa que solo tiene que mirar los cuadros delimitadores y no la geometría. Luego comienza a trazar rayos y los atraviesa por la jerarquía. Cada vez que un rayo golpea un nodo hoja en la jerarquía de nivel superior (es decir, golpea el cuadro delimitador de un objeto), ese objeto se carga en la memoria y se construye su jerarquía de bajo nivel. El rayo continúa hacia abajo para rastrear ese objeto. Combinado con un caché de objetos que mantiene la mayor cantidad posible de la jerarquía de bajo nivel en la memoria, esto puede funcionar razonablemente bien.

El primer beneficio de este enfoque es que los objetos que nunca son golpeados nunca se cargan, lo que significa que se adapta automáticamente a la visibilidad en su escena. El segundo beneficio es que si está rastreando muchos rayos, no tiene que cargar un objeto inmediatamente ya que es golpeado por un rayo; en su lugar, puede sostener ese rayo y esperar hasta que suficientes rayos hayan golpeado ese objeto, amortizando la carga en múltiples rayos.

También puede combinar este enfoque con un algoritmo de clasificación de rayos como el Sombreado diferido ordenado para el trazado de ruta de producción para evitar la agitación debido a rayos incoherentes. El artículo mencionado describe la arquitectura del renderizador Hyperion de Disney, utilizado para Big Hero 6, creo, por lo que probablemente pueda manejar escenas a escala de producción.

Benedikt Bitterli
fuente
1
Esto es super interesante! Así es el papel de Disney que vinculaste.
John Calsbeek
+1 ¡Tantas respuestas a cosas que siempre me he preguntado!
Rotem
7

Si organiza su escena en una estructura espacial (la forma habitual de ser una Jerarquía de volumen de límites ), puede usar una especie de escena virtual (estoy inventando este término, en referencia a las texturas virtuales ).

Un administrador de memoria mantendría solo un número limitado de cuadros delimitadores cargados a la vez y abstraería la operación que consiste en recuperar uno.

De esta manera, una caja se cargaría solo según sea necesario: cuando un rayo golpea una caja delimitadora, la caja se carga para resolver la colisión. Más tarde, cuando se necesita cargar otra casilla, la que no se utiliza se elimina para dejar espacio a la nueva.

Con todas estas cajas cargadas y eliminadas, la coherencia del rayo sería un factor importante en la velocidad. Supongo que una mejora adicional podría ser diferir la carga, reordenando los rayos para tratar primero las cajas que ya están cargadas.

Julien Guertault
fuente
Si algo como esto.
joojaa
1

Lo que haces es cargar triángulos en la memoria desde el disco en función de lo que se ha golpeado anteriormente. Puede comenzar primero con triángulos muy cercanos. El razonamiento es que en un área los rayos pueden golpear repetidamente los mismos triángulos. Y eventualmente serás algo eficiente. (Por esta razón, es una buena idea almacenar en caché el triángulo del último golpe en el trazado de oclusión que no importa el orden)

En segundo lugar, almacena los triángulos en un árbol espacial que le permite realizar búsquedas rápidas desde el disco, para renovar las porciones que tiene en la memoria por proximidad. Así que cargue solo ramas que se interpongan en el camino del rayo. Si es algún tipo de árbol de vóxel, como un octree, incluso puede clasificar los rayos secundarios y resolverlos por coherencia. Un árbol BSP también es algo bueno para podar áreas.

Hay casos en los que esto falla, pero es razonablemente eficiente en la mayoría de los segmentos de escenas si no está generando ruido ...

joojaa
fuente