Cómo funciona la renderización de juegos en 3D: texturizado y filtrado de texturas

imagen

En el tercer artículo sobre renderizado en juegos 3D, descubriremos qué le sucede al mundo 3D después de procesar el procesamiento de vértices y rasterizar la escena. El texturizado es una de las etapas más importantes de la representación, a pesar de que solo calcula y cambia los colores de una cuadrícula bidimensional de bloques multicolores.

La mayoría de los efectos visuales en los juegos modernos se reducen al uso deliberado de texturas; sin ellos, los juegos parecerían aburridos y sin vida. ¡Entonces veamos cómo funciona todo!

Parte 1: procesamiento de vértices

Parte 2: rasterización y trazado de rayos

Comencemos con un simple


Puede tomar los juegos tridimensionales más vendidos lanzados durante el año pasado y decir con confianza que todos tienen algo en común: usan mapas de textura (o solo texturas ). Este es un término tan común que al pensar en texturas, la mayoría de las personas presentan la misma imagen: un cuadrado o rectángulo plano simple que contiene una imagen de una superficie (hierba, piedra, metal, tela, cara, etc.).

Pero cuando se usa y combina con cálculos complejos, imágenes tan simples en una escena 3D pueden crear imágenes increíblemente realistas. Para entender cómo es esto posible, desactívelos por completo y veamos cómo se verán los objetos del mundo 3D sin texturas.

Como vimos en artículos anteriores, el mundo 3D está formado por vértices, formas simples que se mueven y luego colorean. Luego se utilizan para crear primitivas, que a su vez se comprimen en una cuadrícula de píxeles bidimensional. Como no usaremos texturas, necesitamos colorear estos píxeles.

Uno de los métodos que se pueden aplicar se llama sombreado plano : se toma el color del primer vértice de la primitiva, y luego este color se aplica a todos los píxeles cubiertos por la figura en el ráster. Se ve algo como esto:


Obviamente, la tetera parece poco realista, y no menos importante debido a los colores irregulares de la superficie. Los colores saltan de un nivel a otro, no hay transiciones suaves. Una solución al problema podría ser usar el sombreado de Gouraud .

En este proceso, se toman los colores de los vértices, después de lo cual se calcula el cambio de color a lo largo de la superficie del triángulo. Para esto, se utiliza la interpolación lineal . Suena complicado, pero en realidad esto significa que si, por ejemplo, un lado de la primitiva tiene un color de 0.2 rojo y el otro 0.8 rojo, entonces el centro de la figura tendrá un color en el medio entre 0.2 y 0.8 (es decir, 0.5).

Este proceso es bastante simple, y esta es su principal ventaja, porque la simplicidad significa velocidad. Muchos juegos 3D más antiguos usaban esta técnica porque el equipo de cómputo tenía capacidades limitadas.


Barrett y Cloud en toda la grandeza del sombreado de Gouraud (Final Fantasy VII, 1997)

Pero incluso tal solución tiene problemas: si la luz cae justo en el medio del triángulo, es posible que sus esquinas (y vértices) no transmitan esta propiedad. Esto significa que el resplandor creado por la luz se puede perder por completo.

Aunque el sombreado plano y el sombreado de Gouraud han ocupado el lugar que les corresponde en las herramientas de renderizado, los ejemplos que se muestran arriba son claros candidatos para mejorar la textura. Y para comprender bien lo que sucede cuando la textura se superpone en la superficie, retrocedemos en el tiempo ... ya en 1996.

Breve historia del juego y la GPU


Hace unos 23 años, id Software lanzó Quake, y se convirtió en un hito importante. Aunque este no fue el primer juego en usar polígonos y texturas 3D para renderizar entornos, definitivamente fue uno de los primeros en usarlos de manera efectiva.

Pero también hizo algo más: mostró lo que se puede hacer con OpenGL (esta API de gráficos estaba en el estado de la primera versión en ese momento), y también ayudó mucho a la primera generación de tarjetas gráficas como Rendition Verite y 3Dfx Voodoo .


Picos de iluminación y texturas simples. Clean 1996, clean Quake.

Según los estándares modernos, Voodoo era extremadamente simple: sin soporte de gráficos 2D, sin procesamiento de vértices, solo el procesamiento de píxeles más simple. Sin embargo, ella era hermosa:


Imagen: Museo VGA

Ella tenía un chip completo (TMU) para obtener un píxel de una textura y otro chip (FBI) para luego mezclarlo con un píxel de trama. El mapa podría llevar a cabo un par de procesos adicionales, por ejemplo, la implementación de efectos de niebla o transparencia, pero esto, en esencia, terminó sus capacidades.

Si observamos la arquitectura subyacente a la estructura y el funcionamiento de la tarjeta gráfica, veremos cómo funcionan estos procesos.


Especificación 3Dfx. Fuente: Falconfly Central

El chip del FBI recibió dos valores de color y los mezcló; uno de ellos podría ser un valor de una textura. El proceso de mezcla es matemáticamente bastante simple, pero varía ligeramente según lo que se mezcle y qué API se use para ejecutar las instrucciones.

Si observa lo que Direct3D nos ofrece con respecto a las funciones y las operaciones de mezcla, veremos que cada píxel se multiplica primero por un número de 0.0 a 1.0. Esto determina cuánto afectará el color del píxel al resultado final. Luego se suman dos colores de píxel cambiados, restados o multiplicados; En algunas funciones, se realiza una operación lógica en la que, por ejemplo, siempre se selecciona el píxel más brillante.


Imagen: blog de tecnología Taking Initiative

La imagen de arriba muestra cómo funciona esto en la práctica; Observe que el valor alfa del píxel se utiliza como coeficiente para el píxel izquierdo . Este número indica la cantidad de transparencia del píxel.

En otras etapas, se aplica el valor de niebla (se toma de la tabla creada por el programador y luego se realizan los mismos cálculos de mezcla); realizar controles y cambios en visibilidad y transparencia; Al final, el color del píxel se escribe en la memoria de la tarjeta gráfica.

¿Por qué necesitas esta excursión a la historia? Bueno, a pesar de la relativa simplicidad del diseño (especialmente en comparación con los monstruos modernos), este proceso describe los principios fundamentales de la textura: tomamos los valores de los colores y los mezclamos para que los modelos y entornos se vean como deberían en una situación particular.

Los juegos modernos hacen lo mismo, la única diferencia es la cantidad de texturas utilizadas y la complejidad de los cálculos de mezcla. Juntos, simulan los efectos visuales encontrados en las películas, o la interacción de la iluminación con diferentes materiales y superficies.

Conceptos básicos de texturizado


Para nosotros, una textura es una imagen 2D plana superpuesta a los polígonos que componen la estructura 3D en el marco. Sin embargo, para una computadora, esto es solo un pequeño bloque de memoria en forma de matriz 2D. Cada elemento de la matriz denota el valor de color de uno de los píxeles en la imagen de textura (comúnmente llamados texels - píxeles de textura).

Cada vértice del polígono tiene un conjunto de dos coordenadas (generalmente denotadas como u, v ), que le indican a la computadora qué píxel de la textura está asociado. El vértice en sí tiene un conjunto de tres coordenadas ( x, y, z ), y el proceso de vincular texels a los vértices se denomina mapeo de texturas .

Para ver cómo sucede esto, pasemos a la herramienta que ya hemos usado varias veces en esta serie de artículos: RealGL Rendering en tiempo real . Por ahora, también descartamos la coordenada z de los vértices y consideramos todo en un plano plano.


De izquierda a derecha: las coordenadas u, v de la textura, ligadas directamente a las coordenadas x, y de los vértices de las esquinas. En la segunda imagen, las coordenadas y se incrementan en los vértices superiores , pero como la textura todavía está unida a ellas, se estira verticalmente. La textura ya ha cambiado en la imagen correcta: los valores de u han aumentado, pero como resultado, la textura se ha comprimido y luego se ha repetido.

Esto sucedió porque, a pesar del hecho de que, de hecho, la textura se ha vuelto más alta debido al mayor valor de u , todavía debe caber en la primitiva; de hecho, la textura se repite parcialmente. Esta es una forma de implementar el efecto que a menudo se encuentra en los juegos 3D: texturas repetidas. Se pueden ver ejemplos de este efecto en escenas con paisajes pedregosos o cubiertos de hierba, así como con paredes de ladrillo.

Ahora cambiemos la escena para que haya más primitivas, y nuevamente regresemos a la profundidad de la escena. La vista clásica del paisaje se muestra a continuación, pero ahora la textura del cuadro se copia y se repite para todas las primitivas.


La textura de la caja en su formato gif original tiene un tamaño de 66 KB y una resolución de 256 x 256 píxeles. La resolución inicial de la parte del marco cubierta por las texturas de la caja es 1900 x 680, es decir, desde el punto de vista del “área” de píxeles, dicha área debe mostrar solo 20 texturas de caja.

Pero es obvio que vemos mucho más de veinte cuadros, y esto significa que la textura del cuadro en la distancia debe ser mucho menor que 256 x 256 píxeles. De hecho , se sometieron a un proceso llamado "minificación de textura" (sí, ¡esa palabra existe en inglés!). Ahora, repitamos, pero esta vez acerca la cámara a uno de los cajones.


No olvide que la textura tiene un tamaño de solo 256 x 256 píxeles, pero aquí vemos una textura que es más grande que la mitad de la imagen con un ancho de 1900 píxeles. Esta textura fue sometida a una operación de "aumento de textura" .

Estos dos procesos de textura ocurren constantemente en los juegos 3D, porque cuando la cámara se mueve alrededor de la escena, los modelos se acercan o se alejan, y todas las texturas aplicadas a las primitivas deben escalarse junto con los polígonos. Desde el punto de vista de las matemáticas, este es un pequeño problema, de hecho, incluso los chips gráficos integrados más simples pueden hacer fácilmente ese trabajo. Sin embargo, la reducción y ampliación de texturas son nuevos desafíos que deben abordarse de alguna manera.

Mini-copias de texturas aparecen en la escena.


El primer problema a resolver para las texturas es la distancia. Si volvemos a la primera imagen con un paisaje de cuadros, los cuadros ubicados cerca del horizonte tienen un tamaño de solo unos pocos píxeles. Por lo tanto, tratar de comprimir una imagen de 256 x 256 píxeles en un espacio tan pequeño no tiene sentido por dos razones.

En primer lugar, la textura más pequeña ocupa menos memoria de la tarjeta gráfica, lo cual es conveniente, ya que puede intentar encajarla en un caché más pequeño. Esto significa que es menos probable que se elimine de la memoria caché, es decir, el uso repetido de esta textura proporcionará un mayor rendimiento, ya que los datos estarán en la memoria cercana. Por la segunda razón, volveremos pronto, porque está asociado con el mismo problema que surge en las texturas cercanas a la cámara.

La solución estándar al problema de la necesidad de comprimir texturas grandes en primitivas pequeñas es usar texturas mip (mipmaps) . Estas son versiones reducidas de la textura original; pueden ser generados por el propio motor (usando los comandos API apropiados) o creados previamente por diseñadores de juegos. Cada nivel posterior de textura mip tiene un tamaño medio en comparación con el anterior.

Es decir, para la textura de la caja, las dimensiones serán: 256 x 256 → 128 x 128 → 64 x 64 → 32 x 32 → 16 x 16 → 8 x 8 → 4 x 4 → 2 x 2 → 1 x 1.


Todas las texturas mip se empaquetan juntas, por lo que la textura tiene el mismo nombre de archivo, pero se hace más grande. La textura está empaquetada de tal manera que las coordenadas u, v no solo determinan qué texel se superpone en el píxel en el marco, sino también con qué textura de mip. Luego, los programadores escriben un renderizador, basado en el valor de la profundidad de píxel del cuadro, que determina qué textura de mip utilizar. Por ejemplo, si el valor es muy alto, entonces el píxel está muy lejos, lo que significa que puede usar una textura de mip pequeña.

Los lectores atentos podrían notar la falta de texturas mip: tienen que pagarlas aumentando el tamaño de las texturas. La textura original de la caja era de 256 x 256 píxeles, pero como puede ver en la imagen de arriba, la textura con texturas MIP ahora tiene un tamaño de 384 x 256. Sí, tiene mucho espacio vacío, pero no importa cómo empaquetamos texturas más pequeñas, en general El tamaño de la textura en un lado aumentará en al menos un 50%.

Pero esto es cierto solo para texturas mip creadas previamente; Si el motor del juego está programado para generarlos correctamente, el aumento no es más del 33% del tamaño de la textura original. Por lo tanto, debido a un pequeño aumento en la cantidad de memoria para almacenar texturas mip, obtenemos una ganancia en rendimiento y calidad visual.

A continuación se muestra una comparación de imágenes con texturas mip deshabilitadas / habilitadas:


En el lado izquierdo de la imagen, las texturas de las cajas se utilizaron "tal cual", lo que condujo a la aparición de granularidad y el llamado muaré en la distancia. A la derecha, el uso de texturas mip permitió transiciones más suaves, y en el horizonte la textura de la caja se vuelve borrosa en un color uniforme.

Sin embargo, ¿quién quiere texturas borrosas para estropear los fondos de su juego favorito?

Bilineal, trilineal, anisotrópico: todo esto es para mí una letra china


El proceso de seleccionar un píxel de una textura para superponerlo en un píxel en un cuadro se denomina texturas de muestreo , y en un mundo ideal habría una textura que coincida idealmente con la primitiva para la que está diseñada, independientemente del tamaño, posición, dirección, etc. En otras palabras, muestrear la textura sería un simple mapeo de píxeles de texel uno a uno.

Pero como esto no es así, hay varios factores a considerar al muestrear texturas:

  • ¿Se ha reducido o ampliado la textura?
  • ¿Es la textura una fuente o textura de mip?
  • ¿A qué ángulo se muestra la textura?

Analicémoslos en orden. El primer factor es bastante obvio: si se ha aumentado la textura, entonces en la primitiva habrá más elementos de textura que cubran el píxel en la primitiva de lo requerido; cuando disminuye, lo contrario es cierto: cada texel ahora debe cubrir varios píxeles. Y eso es un problema.

El segundo factor no causa problemas, porque las texturas mip se usan para evitar el problema de muestrear las texturas de primitivas lejanas, por lo que la única tarea es mostrar las texturas en ángulo. Y sí, esto también es un problema. ¿Por qué? Porque todas las texturas son imágenes generadas para ver "estrictamente al frente". Hablando en lenguaje matemático, la textura normal de la superficie coincide con la superficie nominal en la que se muestra actualmente la textura.

Por lo tanto, si los texels son muy pocos o demasiados, o están ubicados en ángulo, entonces se requiere un proceso adicional llamado "filtrado de texturas" . Si este proceso no se usa, obtenemos esto:


¡Aquí reemplazamos la textura de la caja con una textura con la letra R, para mostrar más claramente en qué desorden se convierte la imagen sin filtrar las texturas!

Las API gráficas como Direct3D, OpenGL y Vulkan proporcionan el mismo conjunto de tipos de filtrado, pero usan nombres diferentes para ellos. De hecho, todos se reducen a lo siguiente:

  • Muestreo de punto cercano
  • Filtrado de textura lineal
  • Filtrado de textura anisotrópica

De hecho, muestrear el muestreo de punto más cercano no es un filtro, porque con él solo se muestrea el texel más cercano del píxel de textura requerido (por ejemplo, copiado de la memoria), y luego se mezcla con el color original del píxel.

Aquí el filtrado lineal viene en nuestra ayuda. Las coordenadas de texel requeridas u, v se transfieren al equipo de muestreo, pero en lugar de tomar el texel más cercano a estas coordenadas, la muestra toma cuatro texel. Estos son los texels ubicados arriba, abajo, a la izquierda y a la derecha del texel que se selecciona muestreando los puntos más cercanos.

Estos cuatro texels se mezclan usando una fórmula con pesas. En Vulkan, por ejemplo, la fórmula se ve así:


T denota el color del texel, donde f es el resultado de la filtración, y 1-4 es el color de cuatro texels muestreados. Los valores alfa y beta se toman según cuán lejos esté el punto con las coordenadas u, v del centro de la textura.

Afortunadamente para aquellos involucrados con gráficos en 3D, esto sucede automáticamente en el chip de gráficos. De hecho, esto es exactamente lo que hizo el chip TMU de la tarjeta Voodoo 3dfx: tomó muestras de cuatro texels y luego los mezcló. En Direct3D, este proceso tiene un nombre extraño para el filtrado bilineal.pero desde los días de Quake y el chip TMU, las tarjetas gráficas ya han aprendido cómo realizar el filtrado bilineal en un solo ciclo de reloj (por supuesto, si la textura ya se encuentra en la memoria más cercana).

El filtrado lineal se puede usar junto con texturas mip, y si desea complicar el filtrado, puede tomar cuatro texels de la textura y luego cuatro más del siguiente nivel de mip-texture, mezclándolos todos. ¿Y cómo se llama en Direct3D? Filtración trilineal . ¿De dónde vinieron los "tres" en este proceso ? Así que no sabemos ...

El último método de filtrado que vale la pena mencionar es el anisotrópico . De hecho, es una mejora en el proceso realizado por filtrado bilineal o trilineal. Inicialmente, calculaEl grado de anisotropía de la superficie primitiva (y este es un proceso sorprendentemente complejo ): este valor aumenta el cambio en la relación de aspecto de la primitiva debido a su orientación:


La figura de arriba muestra la misma primitiva cuadrada con lados iguales; pero girando gradualmente, se convierte en un rectángulo, y su ancho cambia más que su altura. Por lo tanto, la primitiva a la derecha tiene un mayor grado de anisotropía que a la izquierda (y en el caso de un cuadrado, el grado es cero).

Muchos juegos 3D modernos le permiten activar el filtro anisotrópico y luego cambiar su nivel (de 1x a 16x), pero ¿qué cambia realmente? Este parámetro controla el número máximo de muestras de texel adicionales que se toman en cada muestra lineal inicial. Supongamos que en el juego se activa un filtrado bilineal anisotrópico de 8x. Esto significa que en lugar de cuatro valores de texel, obtendrá 32 valores.

La diferencia al usar el filtro anisotrópico es claramente notable:


Simplemente vaya a la imagen de arriba y compare el muestreo de los puntos más cercanos con un máximo de 16 filtros anilotrópicos trilineales. Increíblemente suave!

Pero por esta belleza suave de las texturas, debe pagar con el rendimiento: en configuraciones máximas, el filtrado trilineal anisotrópico recibirá 128 muestras de la textura por cada píxel de renderizado. Incluso con las mejores GPU modernas, esto no se puede lograr en un ciclo de reloj.

Si toma, por ejemplo, AMD Radeon RX 5700 XT, cada uno de los bloques de texturas dentro del procesador puede usar hasta 32 direcciones de texel en un ciclo de reloj, y luego en el siguiente ciclo de reloj cargar 32 valores de texel de la memoria (cada uno de los cuales tiene un tamaño de 32 bits), y luego mezclar cuatro de ellos en uno más tacto. Es decir, mezclar 128 muestras de texel en una requiere al menos 16 ciclos de reloj.


GPU AMD RDNA Radeon RX 5700 con tecnología de proceso de 7 nanómetros

Si la velocidad del reloj del 5700 XT es de 1605 MHz, dieciséis ciclos toman solo 10 nanosegundos . La realización de estos ciclos para cada píxel en un cuadro de 4K con una sola unidad de textura solo tomará 70 milisegundos. ¡Genial, parece que el rendimiento no es gran cosa!

Incluso en 1996, 3Dfx Voodoo y tarjetas similares hicieron frente rápidamente a las texturas. A lo sumo, podían entregar 1 texel con filtrado bilineal por ciclo, y con una frecuencia de chip TMU de 50 MHz, esto significaba que se podían procesar 50 millones de texels por segundo. Un juego que se ejecuta a 800 x 600 y 30 fps solo requiere 14 millones de texels con filtrado bilineal por segundo.

Sin embargo, esto es cierto solo bajo el supuesto de que todas las texturas están en la memoria más cercana y que solo un texel corresponde a cada píxel. Hace veinte años, la idea de la necesidad de superponer varias texturas en una primitiva era completamente extraña, pero hoy es un estándar. Veamos por qué todo esto cambia.

Agregar iluminación


Para entender por qué la textura se ha vuelto tan importante, eche un vistazo a esta escena de Quake:


Esta es una imagen oscura, porque la oscuridad era la atmósfera del juego, pero vemos que la oscuridad no es la misma en todas partes: algunos fragmentos de paredes y pisos son más claros que otros, lo que crea una sensación de ligereza en estas áreas.

Las primitivas que componen las paredes y el piso se superponen con las mismas texturas, pero hay otra textura llamada "mapa de luz" mezclado con los valores de los texels antes de que se apliquen a los píxeles del marco. En los tiempos del terremoto, los mapas de iluminación se calculaban por adelantado y los creaba el motor del juego. Se utilizaron para generar niveles de iluminación estáticos y dinámicos.

La ventaja de su uso es que los cálculos de iluminación complejos se realizaron con texturas en lugar de vértices, lo que mejoró en gran medida la apariencia de la escena a expensas de los costos de baja velocidad. Obviamente, la imagen es imperfecta: en el piso se nota que el borde entre las áreas iluminadas y las sombras es muy nítido.

En muchos sentidos, un mapa de luz es solo otra textura (no olvide que todos son conjuntos de datos 2D normales), por lo que esta escena es uno de los primeros ejemplos de uso de texturas múltiples. Como su nombre lo indica, este es un proceso en el que dos o más texturas se superponen en una primitiva. El uso de mapas de iluminación en Quake se ha convertido en una forma de superar las limitaciones del sombreado de Gouraud, pero en el proceso de aumentar la gama de capacidades de las tarjetas gráficas, los métodos de aplicación de texturas múltiples también se han expandido.

3Dfx Voodoo, como muchas otras tarjetas de esa época, estaba limitado en la cantidad de operaciones que podía realizar en un solo pase de renderizado. De hecho, un pase es un ciclo de renderizado completo: desde procesar vértices hasta rasterizar el marco, y luego cambiar los píxeles y escribirlos en el búfer de marco terminado. Hace veinte años, los juegos casi siempre usaban renderizado de una pasada.


Nvidia GeForce 2 Ultra, a finales de 2000. Imagen: Wikimedia

Esto sucedió porque el segundo procesamiento de vértices solo para aplicar texturas adicionales era demasiado costoso en términos de rendimiento. Después de Voodoo, tuvimos que esperar un par de años cuando aparecieron las tarjetas gráficas ATI Radeon y Nvidia GeForce 2, capaces de multitexturar en una sola pasada.

Estas GPU tenían varias unidades de textura en el área de procesamiento de píxeles (es decir, en la tubería ), por lo que la tarea más simple fue obtener un texel con filtrado bilineal de dos texturas separadas. Esto aumentó aún más la popularidad de los mapas de iluminación y permitió que los juegos los hicieran completamente dinámicos, cambiando los valores de iluminación dependiendo de las condiciones del entorno de juego.

Pero con algunas texturas, se podría hacer mucho más, así que exploremos sus capacidades.

Cambiar la altura es normal


En esta serie de artículos sobre renderizado 3D, no hablamos sobre cómo el papel de la GPU afecta todo el proceso (hablaremos de esto, ¡pero no ahora!). Pero si vuelve a la parte 1 y lee sobre todo el complejo proceso de procesamiento de vértices, podría pensar que esta es la parte más difícil de todo el trabajo que debe hacer la GPU.

Durante mucho tiempo lo fue, y los programadores de juegos hicieron todo lo posible para reducir esta carga. Tuvieron que recurrir a todo tipo de trucos para garantizar la misma calidad de imagen que cuando se utilizan múltiples vértices, pero no los procesen.

La mayoría de estos trucos usaban texturas llamadas mapas de altura y mapas normales.. Estos dos conceptos están conectados por el hecho de que el último puede crearse a partir del primero, pero por ahora, solo veamos una técnica llamada "mapeo de relieve" .


Imágenes creadas en una representación de demostración por Emil Persson . La textura en relieve está deshabilitada / habilitada La textura en relieve

utiliza una matriz 2D llamada "mapa de altura" que se parece a una versión extraña de la textura original. Por ejemplo, la imagen de arriba muestra una textura de ladrillo realista superpuesta en dos superficies planas. La textura y su mapa de altura se ven así:


Los colores del mapa de altura indican las normales de la superficie de los ladrillos (hablamos de las normales en la parte 1 de una serie de artículos). Cuando el proceso de renderizado alcanza la etapa de aplicar la textura de ladrillo a la superficie, se realizan una serie de cálculos para cambiar el color de la textura de ladrillo en función de sus valores normales.

Como resultado de esto, los ladrillos se ven más tridimensionales, a pesar de que continúan siendo completamente planos. Si observa de cerca, especialmente en los bordes de los ladrillos, puede ver las limitaciones de esta técnica: la textura se ve ligeramente distorsionada. Pero este es un truco rápido que le permite agregar más detalles de superficie, por lo que la textura en relieve es muy popular.

Un mapa normal es similar a un mapa de altura, solo los colores de textura son los mismos normales. En otras palabras, no se requieren cálculos para convertir el mapa de altura a normal. Puedes hacer una pregunta: ¿cómo pueden los colores describir un vector en el espacio? La respuesta es simple: cada texel tiene un conjunto de valores r, g, b (rojo, verde, azul) y estos valores corresponden directamente a los valores x, y, z del vector normal.


El diagrama de la izquierda muestra el cambio en la dirección de las normales en una superficie irregular. Para describir las mismas normales con una textura plana (contorno medio), les asignamos colores. En este caso, utilizamos los valores r, g, b (0.255.0) para el vector dirigido directamente hacia arriba, y luego aumentamos el valor de rojo para la inclinación hacia la izquierda y azul para la inclinación hacia la derecha.

Tenga en cuenta que este color no se mezcla con el píxel original, simplemente le dice al procesador en qué dirección indica la normalidad para que pueda calcular correctamente los ángulos entre la cámara, las fuentes de luz y la superficie texturizada.

Las ventajas de la textura en relieve y los mapas normales son completamente evidentes cuando se utiliza iluminación dinámica en la escena, y cuando el proceso de renderizado calcula el efecto del cambio de iluminación píxel por píxel, y no para cada vértice. Hoy en día, los juegos modernos usan un conjunto de texturas para mejorar la calidad de este truco.


Imagen: Ryan Benno de Twitter

Sorprendentemente, esta pared de aspecto realista es solo una superficie plana, los detalles de ladrillos y cemento de mampostería no están hechos con millones de polígonos. En cambio, solo cinco texturas y el uso reflexivo de los cálculos son suficientes.

Se usó un mapa de altura para generar sombras proyectadas con ladrillos, y un mapa normal para simular todos los cambios menores en la superficie. La textura de rugosidad se utilizó para cambiar la forma en que la luz se refleja desde varios elementos de la pared (por ejemplo, el ladrillo liso refleja la luz de manera más uniforme que el cemento en bruto).

La última tarjeta, nombrada en la imagen AO, crea una parte del proceso llamada oclusión ambiental: examinaremos esta técnica con más detalle en los siguientes artículos, pero por ahora digamos que ayuda a aumentar el realismo de las sombras.

El mapeo de texturas es un proceso crítico.


La textura es absolutamente esencial al desarrollar juegos. Tomemos, por ejemplo, el juego de 2019 Kingdom Come: Deliverance , un juego de rol en primera persona ambientado en Bohemia en el siglo XV. Los diseñadores buscaron crear el mundo más realista de ese período. Y para sumergir al jugador en la vida que era hace cientos de años, es mejor implementar un paisaje, edificios, ropa, peinados, artículos cotidianos y mucho más históricamente precisos.

Cada textura en esta imagen del juego fue creada manualmente por artistas, y también gracias a un motor de renderizado controlado por programadores. Algunos de ellos son pequeños, con detalles simples y, por lo tanto, están ligeramente filtrados o procesados ​​con otras texturas (por ejemplo, alitas de pollo).


Otros tienen alta resolución y muchos pequeños detalles; se someten a un filtrado anisotrópico y se mezclan con mapas normales y otras texturas, solo mire la cara de la persona en primer plano. Los programadores tienen en cuenta la diferencia en los requisitos de textura de cada objeto de escena.

Todo esto sucede hoy en muchos juegos, porque los jugadores esperan niveles cada vez más altos de detalle y realismo. Las texturas se hacen cada vez más grandes, y cada vez más se superponen en la superficie, pero el proceso de muestreo de texels y superposición de ellos en píxeles esencialmente sigue siendo el mismo que en los días del terremoto. ¡Las mejores tecnologías nunca mueren, sin importar la edad que tengan!

All Articles