Smoothness
Heightmap

Normal map (Bump mapping)

Los Normal Maps son un tipo de Bump Map. Son un tipo especial de textura que le permite a usted agregar detalles en las superficies como golpes/bultos/bumps, surcos, rayones a un modelo que atrapa la luz como si fuera representado por una geometría real.

Por ejemplo, usted podría querer mostrar una superficie que tiene surcos y tornillos o remaches a través de la superficie, como los cascos de los aviones. Una manera de hacer esto sería modelar estos detalles como geometría, como se muestra abajo.

Una hoja de metal de un avión con detalles modelados como una geometría real.
Una hoja de metal de un avión con detalles modelados como una geometría real.

Dependiendo de la situación, normalmente no es buena idea tener tantos detalles modelados como geometría “real”. En la derecha usted puede ver los polígonos requeridos para hacer el detalle de un solo cabeza de tornillo. Sobre un modelo grande con muchas superficies detalles esto requiere un gran número de polígonos que sean dibujados. Para evitar esto, nosotros usualmente utilizamos un normal map para representar el detalle fino de las superficies, y una superficie poligonal con baja resolución para la parte forma del modelo.

Si más bis bien representamos este detalle con un bump map, la superficie de la geometría se puede volver más simple, y el detalle se representa como una textura que modela cómo la luz se refleja de la superficie. Esto es algo que el hardware moderno de gráficas puede hacer bastante rápido. Su superficie metálica ahora puede ser un plano bajo-poly, y los tornillos, remaches, surcos y rasguños van a capturar la luz y parecer como si tuvieran profundidad debido a la textura.

Los tornillos, surcos y rasguños se definen en un normalmap, el cual modifica cómo la luz refleja la superficie de este plano bajo-poly, dando la impresión de un detalle en 3D. Al igual que con los remaches y tornillos, una textura nos permite incluir mucho más detalle como rasguños y golpes sutiles.
Los tornillos, surcos y rasguños se definen en un normalmap, el cual modifica cómo la luz refleja la superficie de este plano bajo-poly, dando la impresión de un detalle en 3D. Al igual que con los remaches y tornillos, una textura nos permite incluir mucho más detalle como rasguños y golpes sutiles.

En los pipelines de arte moderno de desarrollo de juegos, los artistas utilizan sus aplicaciones de modelado 3D para generar normal maps basándose en modelos fuentes de alta resolución. Los normal maps luego son mappeados a una versión lista del juego de baja resolución del modelo, para que el detalle original de alta resolución se renderiza utilizando el normalmap.

Cómo crear y utilizar Bump Maps

El Bump Mapping es una técnica relativamente vieja de gráficas, pero sigue siendo uno de los métodos fundamentales para crear gráficas en tiempo real detalladas reales. Los Bump Maps también son referidos como Normal Maps o Heigh Maps, sin embargo, estos términos tienen pocas diferencias cuanto a significado que explicaremos abajo.

Qué son Surface Normals (Normales de superficie)

Para explicar realmente cómo el normal mapping funciona, primero describiremos qué es una normal, y cómo se utiliza en la iluminación en tiempo real. Tal vez el ejemplo más básico sería un modelo dónde cada polígono de una superficie se prende de acuerdo a los ángulos de la superficie relativos a la luz. El ángulo de la superficie se puede representar como una linea saliente en una dirección perpendicular de una superficie, y esta dirección (que es un vector) que es relativa a la superficie se llama una “surface normal”, o simplemente, una normal.

Dos cilindros de 12 lados, a la izquierda con un flat shading (sombreado plano), y a la derecha con smoothed shading (sombreado suvizado)
Dos cilindros de 12 lados, a la izquierda con un flat shading (sombreado plano), y a la derecha con smoothed shading (sombreado ‘suvizado’)

En la imagen de arriba, el cilindro izquierdo tiene un flat shading (sombreado plano) básico, y cada polígono está shaded (sombrado) de acuerdo a ángulo de referencia a la fuente de luz. La iluminación en cada polígono es constante a través del área del polígono ya que su superficie es plana. Aquí están los mismos dos cilindros, con su wireframe (forma de alambre) mesh visible:

Dos cilindros de 12-lados, a la izquierda con flat shading (sombreado plano), y a la derecha con smoothed shading (sombreado suavizado)
Dos cilindros de 12-lados, a la izquierda con flat shading (sombreado plano), y a la derecha con smoothed shading (sombreado ‘suavizado’)

El modelo a la derecha tiene la misma cantidad de polígonos que el modelo a la izquierda, sin embargo el shading (sombreado) parece suave - la iluminación a través de los polígonos da una apariencia de una superficie curva. Por qué sucede esto? La razón es que la surface normal en cada punto utilizado para reflejar luz gradualmente varía con la anchura del polígono, entonces en cualquier punto dado en la superficie, la luz rebota como si la superficie fuera curva y no como un polígono plano constante como en realidad es.

Visto como un diagrama 2D, tres de los polígonos de la superficie alrededor del cilindro flat-shaded (sombreado plano) se vería así:

Un flat shading (sombreado plano) en tres polígonos, visto como un diagrama 2D
Un flat shading (sombreado plano) en tres polígonos, visto como un diagrama 2D

Las surface normals son representados por las flechas anaranjadas. Estas son valores utilizados para calcular cómo la luz refleja la superficie, y puede ver que la luz responde de la misma manera a través de la longitud de cada polígono, ya que surfaces normals apuntan en la misma dirección. Esto da el “flat shading”, y es la razón por la cual los polígonos del cilindro de la izquierda parecen tener bordes rígidos.

No obstante, para el cilindro smooth shaded, las surface normals varian a través de los polígonos planos, como se representa aquí:

Smooth shading en tres polígonos, vistos como un diagrama 2D
Smooth shading en tres polígonos, vistos como un diagrama 2D

Las direcciones normales gradualmente cambian a través de las superficies de polígonos planos, para que el sombreado a través de la superficie de la impresión de una curva suave (como se representa con las lineas verdes). Esto no afecta la naturaleza polígonal del mesh, solamente cómo la luz se calcula en superficies planas. Esta superficie aparentemente curva realmente no está presente, y ver las caras en unos ángulos relevará la naturaleza real de los polígonos planos, sin embargo en la mayoría de ángulos de vista, el cilindro parece tener una superficie curva suave.

Utilizando este smooth shading básico, los datos que determinan la dirección normal solamente se almacena per vertex (por vértice), por lo que los valores cambiantes a través de la superficie son interpolados de un vértice al siguiente. En el diagrama de arriba, las flechas rojas indican la dirección normal almacenada en cada vértice, y las flechas anaranjadas indican ejemplos de las direcciones normales interpoladas a través del área del polígono.

Qué es Normal Mapping?

Normal mapping toma esta modificación de surface normals un paso más allá, al utilizar una textura para almacenar información acerca de cómo modificar las surface normals a través del modelo. Un normal map es una textura de imagen mapeada a la superficie del modelo, similar a unas texturas de color regulares, sin embargo cada pixel en la textura del normal map (llamado texel) representa una desviación en la dirección de la surface normal de la surface normal “verdadera” del polígono plano (o suavizado interpolado).

Normal mapping a través de tres polígonos, vistos como un diagrama 2D
Normal mapping a través de tres polígonos, vistos como un diagrama 2D

En este diagrama, que es nuevamente una representación 2D de tres polígonos en la superficie de un modelo 3D, cada flecha anaranjada corresponde a un pixel en la textura normalmap. Abajo, hay un corte de un solo-pixel de una textura normalmap. En el centro, usted puede ver que las normales han sido modificadas, dando la apariencia de un par de golpes en la superficie del polígono. Estos golpes solamente serían aparentes debido a la manera que la luz aparece en la superficie, ya que estas normales modificadas son utilizadas en los cálculos de la iluminación.

Los colores visibles en un archivo crudo normal map típicamente tienen un hue azul, y no contienen una luz o sombreado oscuro - esto se debe a que los colores en sí no tienen la intención de ser mostrados como son. Más bien, los valores RGB de cada texel representa los valores X, Y & Z de un vector de dirección, y son aplicados como modificaciones a las normales suaves interpoladas básicas de las superficies de los polígonos.

Una textura normal map ejemplo
Una textura normal map ejemplo

Esta es una normal map simple, que contiene la información de golpes para algunos rectángulos elevados y texto. Este normal map puede ser importado a Unity colocado a la ranura de Normal Map del Standard Shader. Cuando se combine con un material con un color map (el Albedo map) y se aplique a la superficie el mesh cilíndrico de arriba, el resultado sería así:

La normal map ejemplo aplicada a la superficie del mesh cilíndrico utilizado arriba
La normal map ejemplo aplicada a la superficie del mesh cilíndrico utilizado arriba

Nuevamente, esto no afecta la naturaleza actual del polígono del mesh, solamente cómo la iluminación se calcula en las superficies. Estas letras aparentemente elevadas y formas en la superficie en realidad no están presentes, y ver las caras en unos ángulos relevará la naturaleza verdadera de la superficie plana, sin embargo en la mayoría de los ángulos el cilindro aparece tener un detalle elevado en la superficie.

Cómo obtengo o hago normal maps?

Comúnmente, las Normal Maps son producidas por artistas 3D o de Texturas en conjunto con el modelo o texturas que están produciendo, y a veces reflejan el diseño y contenido del Albedo map. A veces son producidas a mano, y a veces son renderizadas de una aplicación 3D.

Cómo renderizar normal maps de una aplicación 3D va más allá del alcance de esta documentación. Sin embargo, el concepto básico es que un artista 3D produciría dos versiones de un modelo - un modelo de alta resolución conteniendo todo el detalle como polígonos, y un modelo “listo para el juego” de baja resolución. El modelo de alta resolución estaría muy detallado para correr de manera optima en un juego (muchos triángulos en el mesh), pero es utilizado en una aplicación de modelado 3D para genera normal maps. La versión de baja resolución luego puede omitir el fino detalle de geometría de detalle que es almacenada en los normal maps, para que pueda ser utilizado para renderizar normal mapping mas bien. Un caso de uso típico de esto sería mostrar el detalle golpeado de arrugas, botones, hebillas, y costuras en la ropa de los personajes.

Hay algunos paquetes de software que pueden analizar la iluminación de una textura fotográfica regular, y extrae un normalmap de esto mismo. Esto trabaja asumiendo que la textura original está prendida desde una dirección constante, y las áreas iluminadas y oscuras son analizadas y se asumen que corresponden con las superficies angulares. Sin embargo, cuando en realidad utilice un bump map, usted se tiene que asegurar que su textura Albedo no tenga iluminación de cualquier dirección en particular en la imagen - idealmente debería representar los colores de la superficie sin iluminación - ya que la información de iluminación será calculada por Unity de acuerdo a la dirección de la luz, ángulo de la superficie e información del bump map.

Aquí hay dos ejemplos, uno es una textura de una pared de una piedra simple que se repite con su normal map correspondiente, y otro es el texture atlas de un personaje con su normal map correspondiente:

Una textura de una pared de piedra y su textura normal map correspondiente.
Una textura de una pared de piedra y su textura normal map correspondiente.
Un texture atlas de un personaje, y su texture atlas normal map correspondiente.
Un texture atlas de un personaje, y su texture atlas normal map correspondiente.

Cuál es la diferente entre Bump Maps, Normal Maps y Height Maps?

Normal Maps y Height Maps ambos son tipos de un Bump Map. Estos contienen datos que representan un detalle aparente en la superficie o meshes de polígonos simples, pero cada uno almacena estos datos de una manera diferente.

En la izquierda, un height map para hacerle bump mapping a una pared de piedras. En la derecha, un normal map para hacerle bump mapping a una pared de piedras..
En la izquierda, un height map para hacerle bump mapping a una pared de piedras. En la derecha, un normal map para hacerle bump mapping a una pared de piedras..

Arriba, en la izquierda usted puede ver el height map utilizado para hacerle el bump mapping a la pared de piedras. Un height map es una textura simple negra y blanca, dónde cada pixel representa la cantidad que ese punto en la superficie debería ser elevado. Entre más blanco sea el color del pixel, más alto el área aparecerá estar elevada.

Un normal map es una textura RGB, dónde cada pixel representa la diferencia en dirección que la superficie debería parecer estar enfrentando, relativo a su surface normal sin modificar. Estas texturas tienden a tener un tinge morado-azul, debido a la manera que el vector es almacenado en valores RGB.

El hardware moderno de gráficos 3D en tiempo real dependen en Normal Maps, ya que contienen los vectores requeridos para modificar cómo se ve la luz al rebotar en una superficie. Unity también acepta Height Maps para bump mapping, pero este debe estar convertido a Normal Maps en la importación para usarlo.

Por qué los colores morados-azulosos

Entender esto no es vital para utilizar normal maps! Es aceptable omitir este párrafo. Sin embargo, si usted realmente quiere saber: los valores de color RGB están siend utilizados para almacenar la dirección X, Y, Z del vector siendo Z “arriba” (contrario a la convención usual de Unity de utilizar Y como “arriba”). Adicionalmente, los valores en la textura son tratados como direcciones en ser almacenadas. Por lo tanto convertir un color RGB a una dirección de un vector, usted debe multiplicar por dos, luego restar 1. Por ejemplo, un valor RGB de (0.5,0.5,1) o #8080FF en los resultados hex en un vector de (0,0,1) el cual es “arriba” para los propósitos de normal mapping - y representa ningún cambio a la superficie del modelo. Este es el color que usted ve en las áreas planas del normal map “ejemplo” qué se menciono antes en esta página.

Un normal map utilizando solamente #8080FF, que se traduce a un vector de 0,0,1 o para arriba. Esto aplica ninguna modificación a la surface normal del polígono, y por lo tanto produce ningún cambio a la iluminación. Cualquier pixel que sea diferente a este color resultará en un vector que apunta en una diferente dirección - que por lo tanto modifica el ángulo que es utilizado para calcular cómo la luz rebota ese punto.
Un normal map utilizando solamente #8080FF, que se traduce a un vector de 0,0,1 o “para arriba”. Esto aplica ninguna modificación a la surface normal del polígono, y por lo tanto produce ningún cambio a la iluminación. Cualquier pixel que sea diferente a este color resultará en un vector que apunta en una diferente dirección - que por lo tanto modifica el ángulo que es utilizado para calcular cómo la luz rebota ese punto.

Un valor de (0.45, 0.91, 0.80) da un vector de (–0.14, 0.82, 0.6) lo cual es una modificación bastante empinada a la superficie. Los colores como este pueden verse en las áreas cian brillantes del normal map de la pared de piedras encima de algunos bordes de piedra. El resultado es que estos bordes atrapan la luz en un ángulo bastante diferente a las caras más planas de las piedras.

Las áreas cian brillantes en el normal map de estas piedras muestra una modificación empinada a las surface normals del polígono encima del borde superior de cada piedra, causando que atrapen la luz en el ángulo correcto.
Las áreas cian brillantes en el normal map de estas piedras muestra una modificación empinada a las surface normals del polígono encima del borde superior de cada piedra, causando que atrapen la luz en el ángulo correcto.

Normal maps

Una pared de piedra sin efecto bumpmap. Las caras y bordes de la piedra no atrapan la luz directional en la escena.
Una pared de piedra sin efecto bumpmap. Las caras y bordes de la piedra no atrapan la luz directional en la escena.
La misma pared de piedra con el bumpmapping aplicado. Los bordes de las piedras que encaran el sol reflejan la luz directional del sol de manera diferente a las caras de las piedras, y los bordes que miran lo opuesto.
La misma pared de piedra con el bumpmapping aplicado. Los bordes de las piedras que encaran el sol reflejan la luz directional del sol de manera diferente a las caras de las piedras, y los bordes que miran lo opuesto.
La misma pared de piedra bumpmapped, en un escenario de iluminación diferente. Una antorcha con luz point ilumina las piedras. Cada pixel de la pared de piedra se prende de acuerdo a cómo la luz golpea el ángulo del modelo base (el polígono), ajustado por los vectores en los normal maps. Por lo tanto los pixeles que encaran la luz son más brillantes, y los pixeles que dan la espalda a la luz son más oscuros, o en una sombra.
La misma pared de piedra bumpmapped, en un escenario de iluminación diferente. Una antorcha con luz point ilumina las piedras. Cada pixel de la pared de piedra se prende de acuerdo a cómo la luz golpea el ángulo del modelo base (el polígono), ajustado por los vectores en los normal maps. Por lo tanto los pixeles que encaran la luz son más brillantes, y los pixeles que dan la espalda a la luz son más oscuros, o en una sombra.

Cómo importar y utilizar Normal Maps y Height Maps

Un normal map puede ser importado al colocar el archivo textura en su carpeta assets, como es usual. Sin embargo, usted necesita decirle a Unity que esta textura es un normal map. Usted puede hacer esto al cambiar el ajuste de “Texture Type” a “Normal Map” en los ajustes de importación en el inspector.

Para importar un heightmap negro y blanco como un normal map, el proceso es casi idéntico, excepto que usted necesita marcar la opción “Create from Greyscale”.

Con “Create From Greyscale” seleccionado, un deslizador de Bumpiness (rebotes) aparecerá en el inspector. Usted puede utilizar esto para controlar qué tan empinados los ángulos son en el normal map, cuando sean convertidos de las alturas de su heightmap. Un valor bajo de bumpiness significará que incluso el contraste más definido en el heightmap será traducido a unos ángulos gentiles y bumps (golpes). Un valor alto va a crear bumps exagerados y respuestas de alto contraste de iluminación a los bumps.

Ajustes de Bajo y Alto Bumpiness cuando importe un height map como un normal map, y el efecto resultante en el modelo.
Ajustes de Bajo y Alto Bumpiness cuando importe un height map como un normal map, y el efecto resultante en el modelo.

Una vez usted tenga un normalmap en sus assets, usted puede colocarlo en la ranura Normal Map de su Material en el inspector. El Standard Shader tiene una ranura de normal map, y muchos de los shaders viejos legacy también soportan normal maps.

Colocando una textura normal map a la ranura correcta en un material utilizando el Standard Shader
Colocando una textura normal map a la ranura correcta en un material utilizando el Standard Shader

Si usted importo un normalmap o heightmap, y no lo marco como un normal map (Al seleccionar Texture Type: Normal Map como se describe arriba), el inspector del Material le advierte acerca de esto y ofrece arreglarlo:

La advertencia Fix Now aparece cuando se intente utilizar un normalmap que no ha sido marcado como tal en el inspector.
La advertencia “Fix Now” aparece cuando se intente utilizar un normalmap que no ha sido marcado como tal en el inspector.

Oprimir “Fix Now” tiene el mismo efecto que seleccionar Texture Type: Normal Map en los ajustes del inspector de la textura. Esto funcionará si su textura en realidad es un normal map. Sin embargo, si es un heightmap greyscale, esta no detectará esto automáticamente - entonces para los heightmaps usted siempre tiene que seleccionar la opción “Create from Greyscale” en la ventana del inspector de la textura.

Normal Maps secundarios

También se puede dar cuenta que hay una segunda ranura para Normal Map más abajo en el inspector del Material para el Standard Shader. Esta le permite a usted utilizar un normal map adicional para crear un detalle extra. Usted puede agregar un normal map a esta ranura de la misma manera que se hace en la ranura regular del normal map, pero la intención aquí es que debe utilizar una escala o frecuencia de tejas (tiling) diferente para que las dos normal maps produzcan un detalle de alto nivel en diferentes escalas. Por ejemplo, su normal map regular puede definir los detalles del artesonado de una pared o vehículo, con surcos en los bordes. Un normal map secundario puede proporcionar un detalle bump fino para los rasguños y ponerse en la superficie que puede ser tiled (tejas) en 5 a 10 veces más la escala del normal map base. Estos detalles se pueden ver bien solamente cuando se examinan de manera cercana. Tener esta cantidad de detalle en el normal map base requeriría que el normal map base sea bastante grande, sin embargo, al combinar dos en diferentes escalas, se puede lograr un nivel de detalle bastante general con dos texturas normal maps relativamente pequeñas.

Smoothness
Heightmap