Visión general
La razón principal de la textura virtual (VT), o texturas virtuales dispersas , como a veces se le llama, es como una optimización de memoria. La esencia del asunto es mover solo a la memoria de video los texels reales (generalizados como páginas / mosaicos) que pueda necesitar para un marco renderizado. Por lo tanto, le permitirá tener muchos más datos de textura en el almacenamiento sin conexión o lento (HDD, Optical-Disk, Cloud) de lo que cabría en la memoria de video o incluso en la memoria principal. Si comprende el concepto de memoria virtual utilizado por los sistemas operativos modernos, es lo mismo en su esencia (el nombre no se da por accidente).
VT no requiere volver a calcular los UV en el sentido de que haría cada fotograma antes de renderizar una malla y luego volver a enviar los datos de vértice, pero requiere un trabajo sustancial en los sombreadores de vértices y fragmentos para realizar la búsqueda indirecta de los UV entrantes. Sin embargo, en una buena implementación, debe ser completamente transparente para la aplicación si está utilizando una textura virtual o una textura tradicional. En realidad, la mayoría de las veces una aplicación mezclará ambos tipos de texturas, virtual y tradicional.
En teoría, el procesamiento por lotes puede funcionar muy bien, aunque nunca he examinado los detalles de esto. Dado que los criterios habituales para agrupar la geometría son las texturas, y con VT, cada polígono en la escena puede compartir la misma textura "infinitamente grande", teóricamente, podría lograr un dibujo de escena completo con 1 llamada de dibujo. Pero en realidad, entran en juego otros factores que lo hacen poco práctico.
Problemas con la TV
Acercar / alejar y movimientos bruscos de la cámara son las cosas más difíciles de manejar en una configuración de TV. Puede parecer muy atractivo para una escena estática, pero una vez que las cosas comienzan a moverse, se solicitarán más páginas de textura / mosaicos de los que puede transmitir para almacenamiento externo. El archivo asincrónico IO y el subprocesamiento pueden ayudar, pero si se trata de un sistema en tiempo real, como en un juego, solo tendrá que procesar algunos fotogramas con mosaicos de menor resolución hasta que lleguen los de alta resolución, de vez en cuando , lo que resulta en una textura borrosa. No hay una bala de plata aquí y ese es el mayor problema con la técnica, IMO.
La textura virtual tampoco maneja la transparencia de una manera fácil, por lo que los polígonos transparentes necesitan una ruta de representación tradicional separada para ellos.
En general, VT es interesante, pero no lo recomendaría a todos. Puede funcionar bien, pero es difícil de implementar y optimizar, además hay demasiados casos de esquina y ajustes específicos de casos necesarios para mi gusto. Pero para grandes juegos de mundo abierto o aplicaciones de visualización de datos, podría ser el único enfoque posible para adaptar todo el contenido al hardware disponible. Con mucho trabajo, se puede hacer que funcione de manera bastante eficiente incluso en hardware limitado, como podemos ver en las versiones PS3 y XBOX360 de id's Rage .
Implementación
He logrado que VT funcione en iOS con OpenGL-ES, hasta cierto punto. Mi implementación no es "enviable", pero posiblemente podría hacerlo si quisiera y tuviera los recursos. Puede ver el código fuente aquí , podría ayudarlo a tener una mejor idea de cómo encajan las piezas. Aquí hay un video de una demostración que se ejecuta en iOS Sim. Se ve muy lento porque el simulador es terrible para emular sombreadores, pero funciona sin problemas en un dispositivo.
El siguiente diagrama describe los principales componentes del sistema en mi implementación. Difiere bastante de la demostración SVT de Sean (enlace abajo), pero está más cerca en arquitectura al presentado por el documento Accelerating Virtual Texturing Using CUDA , que se encuentra en el primer libro de GPU Pro (enlace abajo).
Page Files
son las texturas virtuales, ya cortadas en mosaicos (páginas AKA) como un paso de preprocesamiento, por lo que están listas para moverse del disco a la memoria de video cuando sea necesario. Un archivo de página también contiene todo el conjunto de mapas MIP, también llamados mapas MIP virtuales .
Page Cache Manager
mantiene una representación del lado de la aplicación de las texturas Page Table
y Page Indirection
. Dado que mover una página del almacenamiento fuera de línea a la memoria es costoso, necesitamos un caché para evitar recargar lo que ya está disponible. Esta memoria caché es una memoria caché menos utilizada recientemente (LRU) muy simple . El caché también es el componente responsable de mantener las texturas físicas actualizadas con su propia representación local de los datos.
El Page Provider
es una cola de trabajo asíncrona que buscará las páginas necesarias para una vista dada de la escena y las enviará a la caché.
La Page Indirection
textura es una textura con un píxel para cada página / mosaico en la textura virtual, que asignará los UV entrantes a la Page Table
textura de caché que tiene los datos reales de texel. Esta textura puede ser bastante grande, por lo que debe usar un formato compacto, como RGBA 8: 8: 8: 8 o RGB 5: 6: 5.
Pero todavía nos falta una pieza clave aquí, y así es cómo determinar qué páginas deben cargarse desde el almacenamiento en la caché y, en consecuencia, en el Page Table
. Ahí es donde pasan el Feedback y el Page Resolver
Enter.
Feedback Pass es una representación previa de la vista, con un sombreador personalizado y con una resolución mucho más baja, que escribirá los identificadores de las páginas requeridas en el buffer de cuadros de color. Ese mosaico colorido del cubo y la esfera de arriba son índices de páginas reales codificados como un color RGBA. Esta representación previa al paso se lee en la memoria principal y la procesa Page Resolver
para decodificar los índices de página y activar las nuevas solicitudes con el Page Provider
.
Después del paso previo de Feedback, la escena se puede representar normalmente con los sombreadores de búsqueda VT. Pero tenga en cuenta que no esperamos que finalice la nueva solicitud de página, eso sería terrible, ya que simplemente bloquearíamos el archivo síncrono IO. Las solicitudes son asíncronas y pueden o no estar listas para cuando se presente la vista final. Si están listos, dulce, pero si no, siempre mantenemos una página bloqueada de un mapa MIP de baja resolución en la memoria caché como respaldo, por lo que tenemos algunos datos de textura para usar, pero será borroso.
Otros recursos que vale la pena ver
La TV sigue siendo un tema candente en Computer Graphics, por lo que hay toneladas de buen material disponible, debería poder encontrar mucho más. Si hay algo más que pueda agregar a esta respuesta, no dude en preguntar. Estoy un poco oxidado sobre el tema, no he leído mucho al respecto durante el año pasado, pero siempre es bueno para la memoria volver a visitar cosas :)
La textura virtual es el extremo lógico de los atlas de texturas.
Un atlas de texturas es una única textura gigante que contiene texturas para mallas individuales en su interior:
Los atlas de textura se hicieron populares debido al hecho de que el cambio de texturas provoca un enjuague completo de la tubería en la GPU. Al crear las mallas, los UV se comprimen / desplazan para que representen la 'porción' correcta del atlas de texturas completo.
Como @ nathan-reed mencionó en los comentarios, uno de los principales inconvenientes de los atlas de texturas es perder modos de ajuste como repetir, pinzar, borde, etc. Además, si las texturas no tienen suficiente borde alrededor, puede accidentalmente muestra de una textura adyacente al hacer el filtrado. Esto puede provocar artefactos sangrantes.
Los Atlas de textura tienen una limitación importante: el tamaño. Las API de gráficos establecen un límite suave sobre cuán grande puede ser una textura. Dicho esto, la memoria gráfica es tan grande. Por lo tanto, también hay un límite estricto en el tamaño de la textura, dado por el tamaño de su v-ram. Las texturas virtuales resuelven este problema, tomando prestados conceptos de la memoria virtual .
Las texturas virtuales explotan el hecho de que en la mayoría de las escenas, solo se ve una pequeña porción de todas las texturas. Entonces, solo ese subconjunto de texturas debe estar en vram. El resto puede estar en la RAM principal o en el disco.
Hay algunas formas de implementarlo, pero explicaré la implementación descrita por Sean Barrett en su charla de GDC . (que recomiendo ver)
Tenemos tres elementos principales: la textura virtual, la textura física y la tabla de búsqueda.
La textura virtual representa el mega atlas teórico que tendríamos si tuviéramos suficiente vram para todo. En realidad no existe en la memoria en ninguna parte. La textura física representa los datos de píxeles que realmente tenemos en vram. La tabla de búsqueda es el mapeo entre los dos. Para mayor comodidad, dividimos los tres elementos en mosaicos o páginas de igual tamaño.
La tabla de búsqueda almacena la ubicación de la esquina superior izquierda del mosaico en la textura física. Entonces, dado un UV a toda la textura virtual, ¿cómo obtenemos el UV correspondiente para la textura física?
Primero, necesitamos encontrar la ubicación de la página dentro de la textura física. Luego necesitamos calcular la ubicación de la radiación UV dentro de la página. Finalmente, podemos agregar estos dos desplazamientos para obtener la ubicación de los rayos UV dentro de la textura física.
Calculando pageLocInPhysicalTex
Si hacemos que la tabla de búsqueda tenga el mismo tamaño que el número de mosaicos en la textura virtual, solo podemos muestrear la tabla de búsqueda con el muestreo del vecino más cercano y obtendremos la ubicación de la esquina superior izquierda de la página dentro de la textura física.
Cálculo en la ubicación de la página
inPageLocation es una coordenada UV que es relativa a la esquina superior izquierda de la página, en lugar de a la esquina superior izquierda de toda la textura.
Una forma de calcular esto es restando el UV de la esquina superior izquierda de la página y luego escalando al tamaño de la página. Sin embargo, esto es bastante matemático. En cambio, podemos explotar cómo se representa el punto flotante IEEE. El punto flotante IEEE almacena la parte fraccionaria de un número por una serie de fracciones de base 2.
En este ejemplo, el número es:
Ahora veamos una versión simplificada de la textura virtual:
El 1/2 bit nos dice si estamos en la mitad izquierda de la textura o en la derecha. El cuarto bit nos dice en qué cuarto de la mitad estamos. En este ejemplo, dado que la textura se divide en 16, o 4 a un lado, estos dos primeros bits nos dicen en qué página estamos. El resto los bits nos dicen la ubicación dentro de la página.
Podemos obtener los bits restantes cambiando el flotador con exp2 () y eliminándolos con fract ()
Donde numTiles es un int2 que da el número de mosaicos por lado de la textura. En nuestro ejemplo, esto sería (4, 4)
Entonces, calculemos inPageLocation para el punto verde, (x, y) = (0.6875, 0.375)
Una última cosa que hacer antes de que hayamos terminado. Actualmente, inPageLocation es una coordenada UV en la textura virtual 'espacio'. Sin embargo, queremos una coordenada UV en la textura física 'espacio'. Para hacer esto, solo tenemos que escalar inPageLocation por la proporción del tamaño de textura virtual al tamaño de textura física
Entonces la función terminada es:
fuente