¿Cómo puede la textura virtual ser realmente eficiente?


27

Como referencia, a lo que me refiero es al "nombre genérico" de la técnica primero (creo) introducida con la tecnología MegaTexture de idTech 5 . Vea el video aquí para ver rápidamente cómo funciona.

Últimamente he estado hojeando algunos documentos y publicaciones relacionados con él, y lo que no entiendo es cómo puede ser eficiente. ¿No requiere un recálculo constante de las coordenadas UV desde el espacio de la "página de textura global" en las coordenadas de textura virtual? ¿Y cómo no frena la mayoría de los intentos de agrupar por completo la geometría? ¿Cómo puede permitir un acercamiento arbitrario? ¿No requeriría en algún momento subdividir polígonos?

Hay tantas cosas que no entiendo, y no he podido encontrar ningún recurso realmente accesible sobre el tema.

Respuestas:


20

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).

sistema de texturizado virtual

  • Page Filesson 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 Managermantiene una representación del lado de la aplicación de las texturas Page Tabley 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 Provideres 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 Indirectiontextura es una textura con un píxel para cada página / mosaico en la textura virtual, que asignará los UV entrantes a la Page Tabletextura 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 ResolverEnter.

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 Resolverpara 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 :)


Hola, gracias por la excelente respuesta. Sé que esto generalmente está mal visto, pero tengo varios problemas, por lo que en su mayoría solo hojeo las cosas, para obtener una visión general intuitiva de los temas para el futuro (me temo que aprender e implementar cosas adecuadamente está fuera de mi alcance por el momento ) - de todos modos, si es posible, ¿podría publicar un ejemplo de pseudocódigo que describa el proceso en sí, idealmente, pero no necesariamente, ilustrado?
Llamageddon

1
@Llamageddon, da la casualidad de que todavía tenía un diagrama a mano;) Me temo que el pseudocódigo será un poco difícil de proporcionar, ya que tiene bastante código real. Pero espero que la respuesta ampliada ayude a dar una idea general de la técnica.
glampert

3
Vale la pena señalar que el hardware más moderno ahora expone tablas de páginas programables, eliminando la necesidad de una textura de redireccionamiento. Esto se expone a través de, por ejemplo , recursos reservados de directx12 , que se basa en recursos en mosaico de directx11 o texturas dispersas de opengl .
MooseBoys

1
@Llamageddon, el pre-pase de comentarios se puede hacer a una resolución más baja para ahorrar la mayor cantidad de cómputo y memoria posible, ya que los píxeles de una página generalmente se repetirán (puede notar los cuadrados de colores grandes en mi demostración). Tienes razón en que eventualmente podría perderse una página visible como esa, pero eso no suele tener un gran impacto visual porque el sistema siempre debe mantener al menos el mipmap más bajo de todo el VT disponible en caché. Ese segundo documento que vinculé tiene todos los ejemplos de sombreadores en el apéndice, también puede consultar el repositorio para mi propio proyecto, son similares.
glampert

1
@glampert Ahh, ya veo; eso tiene sentido. Aún así, creo que hay muchas opciones para manejar transparencias; en el pase de ID de página, puede difuminar (para que la histograma vea todas las páginas, a menos que haya una gran cantidad de capas transparentes), o utilice un enfoque de k-buffer , o incluso basar la residencia de textura transparente en los objetos que están cerca del cámara (en lugar de representarlos en un pase de comentarios).
Nathan Reed

11

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:

Ejemplo de Atlas de textura

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.

Textura virtual

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.

float2 pageLocInPhysicalTex = ...
float2 inPageLocation = ...
float2 physicalTexUV = pageLocationInPhysicalTex + inPageLocation;


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.

float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);


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.

ingrese la descripción de la imagen aquí

En este ejemplo, el número es:

number = 0 + (1/2) + (1/8) + (1/16) = 0.6875

Ahora veamos una versión simplificada de la textura virtual:

Textura virtual simple

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 ()

float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
inPageLocation = fract(inPageLocation);

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)

inPageLocation = float2(0.6875, 0.375) * exp2(sqrt(int2(4, 4));
               = float2(0.6875, 0.375) * int2(2, 2);
               = float2(1.375, 0.75);

inPageLocation = fract(float2(1.375, 0.75));
               = float2(0.375, 0.75);

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

inPageLocation *= physicalTextureSize / virtualTextureSize;



Entonces la función terminada es:

float2 CalculatePhysicalTexUV(float2 virtTexUV, Texture2D<float2> lookupTable, uint2 physicalTexSize, uint2 virtualTexSize, uint2 numTiles) {
    float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);

    float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
    inPageLocation = fract(inPageLocation);
    inPageLocation *= physicalTexSize / virtualTexSize;

    return pageLocInPhysicalTex + inPageLocation;
}

No lo estoy, me refiero a la textura virtual, más conocida como la tecnología MegaTexture de idTech 5 . También vea esto y esto . Lo he visto mencionado en una descripción general de las tuberías de renderizado de muchos motores modernos, y en algunos documentos que utilizan un enfoque similar para los mapas de sombra. Tiene mucho en común con los atlas de texturas, sí, los usa, en cierto modo, pero no lo estoy confundiendo con los atlas de texturas.
Llamageddon

Ahh Gracias por los enlaces. ¿Puedes agregarlos a la pregunta? Actualizaré mi respuesta en consecuencia
RichieSams

3
En mi opinión, el principal inconveniente de los atlas de texturas simples (no texturas virtuales) es que pierdes los modos de envoltura como repetir y sujetar, y el sangrado se produce debido al filtrado / mipmapping, no a la precisión de punto flotante. Me sorprendería ver que la precisión de flotación se convierte en un problema para las texturas ordinarias (no virtuales); Incluso una textura de 16K (el máximo permitido por las API actuales) no es lo suficientemente grande como para realmente tensar la precisión del flotador.
Nathan Reed

@RichieSams Por cierto, creo que su respuesta es buena, incluso si se trata de una pregunta diferente. Debes hacer una publicación de preguntas y respuestas.
Llamageddon

Hmm, esto lo explica bastante bien, aunque realmente no entiendo cómo funciona con los niveles de mip. Desearía poder escribir mi problema específico para entenderlo, pero me elude un poco ...
Llamageddon
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.