Cómo transferir un sombreador de un motor de juego a Substance Painter

Mi nombre es Taras Uleisky, soy un artista técnico en Plarium Kharkiv. Para optimizar los gráficos de nuestro juego de rol de supervivencia en dispositivos móviles, utilizamos nuestros sombreadores personalizados. Implican el uso de texturas y mapas únicos que no son similares a las texturas y mapas en otros métodos de sombreado populares. Como resultado, no está del todo claro para los artistas 3D cómo crear estas texturas para los activos del juego. Para que pueda ver de inmediato cómo se verá el modelo 3D en el motor del juego en la etapa de texturizado, moví el sombreador a Substance Painter. Prácticamente no hay materiales de API en Substance Painter en este momento, estudié este tema yo mismo, así que decidí compartir mis propias ideas.



Sombreador de la unidad


El juego usa sombreado matcap. Además de la textura diff habitual, dos texturas Matcap creadas previamente también se transfieren al sombreador. Se interpolan y se difuminan usando dos máscaras, respectivamente. Como resultado, la textura Matcap se multiplica por reflejos difusos y falsos, y se pueden ver reflejos en el material.



El siguiente ejemplo muestra cómo se implementa Matcap en un gráfico de sombreador. En este caso, dos texturas de Matcap se empaquetan en una y se dividen en canales. Es decir, metal y no metal en los canales R y G, respectivamente.



Dos matcaps se interpolan para un ejemplo por el verificador.



El resultado es una cierta analogía con el metal y el no metal como en el sombreado PBR.

Queríamos agregar rugosidad y suciedad a los materiales, para crear algún tipo de rugosidad análoga en el sombreado PBR. Para hacer esto, utilizamos el método de texturizado.MIP-mapping . Una secuencia de texturas crea la llamada pirámide MIP con una resolución máxima de 1x1. Por ejemplo: 1 × 1, 2 × 2, 4 × 4, 8 × 8, 16 × 16, 32 × 32, 64 × 64, 128 × 128. Cada una de estas texturas se denomina nivel MIP. Para implementar raspaduras en el sombreador píxel por píxel, según la máscara, debe seleccionar el nivel MIP requerido. Resulta de esta manera: donde el píxel de la máscara es negro, el nivel máximo de MIP se selecciona en Matcap, y donde el color del píxel es blanco, el nivel de MIP es 0.





Como resultado, el sombreador hace posible simular reflejos y reflejos, agregar rugosidad de la luz y raspaduras. Y todo esto sin el uso de Cubemap, sin cálculos complejos de iluminación y otras técnicas que reducen significativamente el rendimiento de los dispositivos móviles.



Configurar Substance Painter para crear un sombreador


Todos los sombreadores disponibles en Substance Painter están escritos en GLSL.
Específicamente, para escribir un sombreador para Substance Painter, utilizo el código VS gratuito. Para resaltar la sintaxis, es mejor usar el soporte de idiomas Shader para la extensión VS Code.



Hay muy poco material sobre la API en Substance Painter, por lo que la documentación estándar que se encuentra en la Ayuda / Documentación / Shader API no tiene precio.



La segunda cosa que ayudará a escribir el sombreador son los sombreadores estándar en Substance Painter. Para encontrarlos, vaya a ... / Allegorithmic / SubstancePainter / resources / shelf / allegorithmic / shaders.

Tratemos de escribir el sombreador sin luz más simple que muestre el color base. Primero, cree un archivo de texto con la extensión .glsl y escriba un sombreador tan simple. Quizás, aunque nada está claro, contaré con más detalle acerca de la estructura del sombreador en Substance Painter.



Cree un nuevo proyecto y arrastre el sombreador a su shell. En la lista desplegable Importar sus recursos a , seleccione el proyecto 'nombre_proyecto' .



Esto es necesario para que todos los cambios puedan actualizarse.

Ahora vaya a Configuración de ventana / Vistas / Sombreador y seleccione su nuevo sombreador en la ventana que aparece. Puedes usar la búsqueda.



Si ve que todo el modelo es blanco y puede dibujar el color Base en él, entonces hizo todo bien. Ahora puede guardar el proyecto y pasar a la siguiente sección.



Si el modelo es rosado, lo más probable es que haya un error en el sombreador: una notificación al respecto estará en la consola.

Construyendo un sombreador en Substance Painter


Considere la estructura de un sombreador que usa el sombreador no iluminado descrito anteriormente como ejemplo.



El método de sombreado es la parte básica del sombreador; no funcionará sin él. Todo lo que se describirá en el interior se puede mostrar en un modelo 3D. Todos los cálculos finales se envían a través de la función diffuseShadingOutput () .

Las líneas 3 y 4 crean un parámetro y una variable, respectivamente. El parámetro asocia el canal de color Base con la variable en la que se almacenará la textura pintada. Todos los parámetros se detallan en la ayuda , en el caso del color base, todo se debe detallar como en el ejemplo. La línea 8 presenta la textura en las coordenadas uv del modelo 3D. Observo que para la textura con Color base, se usa el sistema Sparse Virtual Textures , porque la biblioteca está conectada con la primera línealib-sparce.glsl .

Puede encontrar muchas implementaciones de Matcap, pero su punto principal es que las normales del modelo se dirigen hacia la cámara y la textura se gira a lo largo de los ejes x e y. Para rotar lo normal hacia la cámara, necesitamos ver la matriz, o el tipo de matriz . Puede encontrar uno en el certificado mencionado anteriormente.



Entonces, estos son los mismos nombres declarados que en el caso del color Base. Ahora necesitamos obtener las normales del modelo 3D.


Se requiere cero como cuarto elemento del vector.

Multiplicar una matriz de vista con un vector normal expandirá lo normal a la cámara.



No olvide que al multiplicar matrices, el orden de los factores es importante. Si cambia el orden de multiplicación, los resultados serán diferentes.

Ahora puede crear coordenadas uv desde viewNormal .



Es hora de conectar la textura matcap.



En este caso, el parámetro creará un campo de textura en la interfaz del sombreador, y si el proyecto tiene una textura con el nombre "Matcap_mip", el Substance Painter lo ajustará automáticamente.



Veamos qué pasó.



Aquí la textura de Matcap se expande en nuevas coordenadas y se multiplica con el color Base en la salida. Quiero prestar atención al hecho de que la textura Matcap se expande a través de la función texture () y Color base, a través de la función textureSparse () . Esto se debe a que las texturas especificadas a través de la interfaz del sombreador no pueden ser del tipo SamplerSparse .

El resultado debería verse así:



Ahora agregue una máscara que mezcle dos Matcap's. Para mayor comodidad, agregue dos Matcap'a en una textura, dividiéndolos en canales. Como resultado, dos texturas Matcap estarán en los canales R y G, respectivamente.

Resultará algo así:



comencemos a agregar una máscara al sombreador. El principio es similar a la adición de Color base.



Es suficiente reemplazar el valor de color base con user0 en el parámetro.

Ahora obtenga el valor de la máscara en el sombreador de píxeles y mezcle las texturas matcap.



Aquí, solo se usa el canal R en la máscara, porque será en blanco y negro. Los dos canales matcap se mezclan utilizando la función mix () , un análogo de lerp en Unity.

Actualicemos el sombreador y agreguemos canales personalizados en la interfaz. Para hacer esto, vaya a Ventana / Vistas / Configuración de conjunto de texturas, en la ventana cerca del encabezado Canales, haga clic en el signo más y seleccione usuario0 de la lista grande.



El canal se puede llamar como quieras.

Ahora, dibujando en este canal, puede ver cómo se mezclan las dos texturas de Matcap.



El sombreador de Unity también usó mapas normales para Matcap, que se hornearon a partir de un modelo de alta poli. Intentemos hacer lo mismo en Substance Painter.

Para utilizar todas las operaciones en normales, debe conectar la biblioteca adecuada :



ahora conectamos los mapas normales. Hay dos de ellos en Substance Painter: uno se obtiene horneando y el segundo se puede dibujar.



De acuerdo con los parámetros, puede adivinar que channel_normal es un mapa normal, según el cual puede dibujar y texture_normal- Mapa normal al horno. También noto que el nombre de la variable texture_normal está incrustado en la API y no puede nombrarlo a su discreción.

A continuación, desempaquete las tarjetas en el sombreador de píxeles:



luego mezclamos los mapas normales y los normales que se encuentran en los vértices del modelo. Para hacer esto, en la biblioteca conectada anteriormente, hay una función normalBlend () .



Primero mezclamos los dos mapas normales, y luego los normales normales. Aunque en realidad no importa en qué orden mezclarlos.

La rotación de las normales en la dirección de la mirada de la cámara se verá así:



entonces no se puede cambiar nada, todo seguirá igual. Debería ser algo como esto:



El mapeo MIP, como se mencionó anteriormente, en este caso es necesario para simular desgastes, algo así como una tarjeta de rugosidad en el sombreado PBR. Pero el problema principal es que la pirámide de las tarjetas mip no se genera para la textura, que se transmite desde la interfaz del sombreador, y en consecuencia el método textureLod () de glsl no funcionará. Uno podría ir hacia otro lado y cargar la textura Matcap a través del canal de usuario, como se hizo para mezclar Matcap. Pero entonces la calidad de la textura disminuirá considerablemente y aparecerán artefactos extraños.

Una solución alternativa es crear una pirámide de tarjetas MIPmanualmente, en Adobe Photoshop u otro editor similar, y luego seleccione el nivel MIP. La pirámide está construida de manera bastante simple. Es necesario proceder del tamaño de la textura original; en mi caso, es de 256x256. Creamos un archivo con un tamaño de 384x256 (384, porque 256 + 256/2) y ahora reducimos la textura original a la mitad hasta que tenga un tamaño de un píxel. Todas las versiones de texturas reducidas se colocan a la derecha de la textura original en orden ascendente. Debería ser así:



ahora puede comenzar a escribir una función que encuentre las coordenadas de cada textura en la pirámide dependiendo del color de cada píxel en la máscara.

La forma más fácil es almacenar las coordenadas uv que se calcularán para cada textura en una matriz. El tamaño de la matriz se determinará como log2 (altura). Necesitamos el uv original , por lo que los agregamos al argumento de la función. Para determinar qué elemento de matriz usar en un píxel en particular, agregue nivel al argumento de la función.



Ahora calcule uv para la textura original, es decir, recorte esos 128 píxeles adicionales de ancho. Para hacer esto, multiplique la coordenada x por ⅔.



Para usar el resto de la textura de la pirámide, debes encontrar patrones. Cuando creamos la pirámide a partir de las texturas, pudimos notar que cada vez la textura se reduce a la mitad del tamaño anterior. Es decir, cuántas veces disminuye el tamaño de la textura, puede determinar elevando 2 a la potencia del nivel MIP .



Resulta que si selecciona el nivel, por ejemplo, 4, la textura disminuirá 16 veces. Comolas coordenadas uv se determinan de 0 a 1, luego el tamaño debe normalizarse, es decir, 1 dividido por cuántas veces ha disminuido la textura, por ejemplo, 1 dividido entre 16.

Usando el valor obtenido de la variable de tamaño, puede calcular las coordenadas para un nivel MIP específico .



El tamaño de los rayos uv disminuye al igual que el tamaño de la textura. En la coordenada x, la textura siempre cambia por ⅔. El cambio de coordenadas y se puede definir como la suma de todos los valores de la variable de tamaño para cada valor de nivel . Es decir, si el valor es level = 1 , entonces uv en la coordenada y se desplazará en 0 píxeles, y si level = 2 , entonces el desplazamiento será la mitad de la altura de la textura: 128 píxeles. Si nivel = 3, entonces el cambio resultará en 128 + 64 píxeles y así sucesivamente. La suma de todos los turnos se puede obtener usando el ciclo.



Ahora, en cada iteración, la variable de desplazamiento se sumará y desplazará la textura a lo largo del eje y en la cantidad deseada de píxeles. El algoritmo paso a paso se parece a esto:



el último paso es mostrar un canal que seleccionará el nivel deseado en cada píxel. Ya hemos hecho esto, nada nuevo.





Para seleccionar el nivel MIP como textura, simplemente multiplique la longitud de la matriz por la textura. Ahora puede conectar nuevas coordenadas uv a través del método recién escrito.



No olvide traducir la textura al tipo int, ya que ahora es un índice para la matriz.
A continuación, debe agregar un canal personalizado en Substance Painter, como lo hicimos antes. Debería ser así: lo





único que falta para el sombreador es la fuente de luz y la capacidad de rotar presionando shift. En primer lugar, para esto necesitamos un parámetro que produzca el ángulo de rotación presionando shift y la matriz de rotación .





Colocamos al azar la fuente de luz y multiplicamos la posición por la matriz de rotación.



Ahora la fuente de luz girará alrededor del eje y presionando shift, pero hasta ahora este es solo un vector en el que se almacena la posición de la fuente de luz. Hay cosas buenasCómo implementar la luz direccional en un sombreador. Nos centraremos en él. Nos queda por determinar la dirección de la luz y la iluminación de nuestro modelo.



Los parámetros establecerán el color de la sombra y el color de la fuente de luz: los parámetros de



color se interpolan de acuerdo con la iluminación calculada anteriormente.



Resultará así: con



estos parámetros, puede ajustar el color de la sombra y el color de la fuente de luz a través de la interfaz del Substance Painter.



Crear y configurar un preset


Cuando el sombreador está listo, debe importar la textura Matcap y el sombreador con la configuración de estante.



Eliminamos todos los canales no utilizados y agregamos canales de usuario: el valor



predeterminado para exportar texturas se verá como cualquier otro, excepto que usará nuestros canales personalizados.



Crearemos una plantilla para todas las configuraciones para que cuando cree el proyecto, se asigne inmediatamente el sombreador deseado y se configuren todos los canales de textura. Para hacer esto, vaya a Archivo / Guardar como plantilla y guarde la plantilla.



Ahora, al crear un nuevo proyecto, no necesita configurar nada, solo seleccione la plantilla deseada.



Qué obtuviste


Un artista técnico puede crear efectos especiales, personalizar escenas y optimizar los procesos de renderizado. También quería que los modelos de armaduras y armas en Stormfall: Saga of Survival fueran exactamente lo que pretendían los artistas 3D. Como resultado, el modelo 3D en Substance Painter se ve igual que en el motor del juego.


Modelo 3D en Substance Painter con sombreado personalizado.


Modelo 3D en Unity con sombreado personalizado.

¡Espero que el artículo haya sido útil y te haya inspirado a nuevos logros!

All Articles