Crea hermosos edificios de tratamiento con Blueprint

Introduccion


El proyecto que genera edificios procesales es una idea tentadora. El uso de módulos estandarizados y la colocación automática son bastante lógicos, porque, después de todo, esta es la misma arquitectura. Pero, ¿cómo podemos nosotros, al texturizar, lograr la diversidad natural en lugar de la repetición?

Este edificio se creó a partir de un solo módulo, copiado automáticamente a Construction Blueprint . La idea es que el material no requiere casi ningún ingreso manual de datos. Solo se usa un material para todo el edificio (excluyendo ventanas). Sus funciones se utilizan para controlar la aleatorización del color de los vértices y la posición de los píxeles en el espacio mundial.


El único módulo es todo lo que necesitamos.


Sin colocación manual o scripting. Toda aleatorización se realiza en el material.

El material descrito en este tutorial:

  • Tiene una capa de suciedad dependiente de la altura que cubre el objeto solo hasta la altura absoluta especificada
  • Selecciona el color de los objetos para cada piso y segmento al azar
  • Cambia ligeramente la posición de los objetos pequeños, también al azar
  • Permite al usuario seleccionar 2 colores para las paredes, así como el valor de su destrucción.


Color de vértice como datos


03:34

Además de las posiciones de vértices y normales, los motores de juego suelen proporcionar acceso a otros valores, por ejemplo, el color de los vértices. Al sombrear un triángulo de malla, el color se interpola entre los vértices. Puede dibujarlo en un editor 3D o usar la pestaña Paint en el UE. Si hace esto en el motor, tendrá la oportunidad de modificar una instancia separada de la malla en el mundo. Le expliqué este caso de uso en el tutorial sobre el dibujo de vértices . Sin embargo, en este caso, nos quedaremos con el color importado, porque decidí usar canales RGB como máscaras exactas que controlan la aleatorización.


No olvide que el color en los gráficos 3D es solo un vector de tres componentes . Sus componentes son el brillo del rojo, el verde y el azul en el rango de 0 a 1. El valor es arbitrario, porque el color del vértice son solo datos. En lugar de usarlos directamente para pintar texturas, decidí empaquetar los colores de las tapas de las máscaras en cada canal:

  • El canal rojo es la máscara de los colores primarios y secundarios de las paredes . Los polígonos con un valor de 0 usan el color primario, con 1 - el color secundario.
  • Canal verde : se utiliza para seleccionar un color de la paleta . Esto le permite controlar la variación de color de artículos pequeños, como secar la ropa. Un valor entre 0 y 1 se redondea al índice (posición UV) en la textura de la paleta.
  • Canal azul : desplazamiento de las posiciones de los vértices para mover los vértices horizontalmente. Esto significa que se usará 0 para paredes (sin movimiento), y se pueden asignar valores de hasta 1 al aire acondicionado o al lino. Este canal también controla la visibilidad (máscara de opacidad). Si el valor es mayor que 0, se agrega un valor aleatorio, propio para cada segmento del edificio, para crear variabilidad.

En cualquier editor 3D serio, hay una función para pintar el color de los vértices. Puede encontrar fácilmente instrucciones sobre cómo hacer esto en su editor. Solo recuerde decirle a Unreal Engine en la ventana de importación de malla para que reemplace ( Reemplace ) el color de los vértices (en lugar de ignorarlo ( Ignorarlo )).

Como dije anteriormente, el color en este proyecto es un conjunto de valores exactos. Para una tarea similar, y casi cualquier tarea técnica del arte del juego, prefiero usar Houdini . Sin embargo, se puede lograr un resultado similar (con un poco más de esfuerzo) en cualquier otro editor 3D. Solo preste atención a lo que cada canal de color debe indicar en el sombreador.

Destaqué todo el proceso de asignación de valores a canales de color de vértice en un tutorial separado: almacene datos en color de vértice usando Houdini . En este tutorial, uso las complejas herramientas de Houdini para hacer que el proceso sea más eficiente.

Anteproyecto de construcción


07:57

El plan que creé es simple. Simplemente crea una pared plana del edificio, duplicando la malla horizontal y verticalmente. Tiene variables mutables MeshWall (malla estática), NumberOfFloors (entero), NumberOfSegments (entero) y Material .


El resultado del proyecto: 4 pisos, 2 segmentos.

Todo el proceso se realiza en Construction Script, es decir durante la edición de nivel. Gracias a esto, la malla resultante se comportará como cualquier otro objeto estático. Por ejemplo, se tendrá en cuenta al construir iluminación.


Las dimensiones de la malla se miden primero. La longitud del borde significa la mitad del tamaño del objeto. Podemos calcularlo una vez y guardarlo, porque para todos los segmentos el valor será el mismo.


El resto del código se ejecuta en dos ciclos. El bucle externo crea pisos como un todo, el bucle interno crea segmentos dentro del piso actual. La ubicación se calcula mediante los índices de iteración del bucle multiplicados por el ancho y la altura de la malla.



Se agrega un nuevo componente de malla estática a cada segmento. En algunos casos, será útil usar instancias. Agregar componentes conduce a un aumento en el número de llamadas de extracción, que en escenas "pesadas" pueden causar problemas.


Eso es todo Al configurar nuevos NumberOfFloors y NumberOfSegments, el edificio se actualizará automáticamente.

Dos colores de pared enmascarados por el color del vértice


21:16


Se accede a ambos colores como parámetros. El canal rojo del color de los vértices se usa como coeficiente de mezcla entre ellos.


Canal de embalaje y mezcla


14:22


Queremos que los colores de las paredes afecten solo las paredes mismas, pero no afecten los marcos de las ventanas y los aires acondicionados. Además, no deben afectar las áreas dañadas. Esto se puede hacer envolviendo la máscara en el canal alfa del color base. En otras palabras, la textura del color base tiene un fondo transparente, y es allí donde se ven afectados los colores de las paredes.

Por cierto, empaqué las texturas metal, rugosidad y oclusión (todo en tonos de gris) en los canales R / G / B de la misma textura . Esto reduce el número de muestreadores, archivos y Lerp en tres veces, una gran optimización que no requiere ningún compromiso. Un tutorial sobre esta técnica se puede encontrar en las notas.


Ruido de la textura



Este patrón de ruido se usó para mezclar entre el primer conjunto de texturas (limpio) y el segundo (dañado). En lugar de calcularlo en tiempo real, que para un ruido de alta calidad será un procedimiento costoso, simplemente lo cargo desde la textura. El nodo WorldAlignedTexture lo proyecta desde tres lados ( genera coordenadas UV procesalmente ).


Suciedad dependiente de la altura. Función de reasignación


18:00


La suciedad es un color plano aplicado por un gradiente en el espacio mundial. El componente Z de la posición del píxel en el mundo se convierte al intervalo 0-1. Esto nos da una máscara útil: el coeficiente de Lerp . El usuario transmite los parámetros mínimos y máximos iniciales (por ejemplo, de 150 a 700 cm) como parámetros escalares. Se agrega un poco de ruido para que la transición sea más natural.



La función TAA_Remap_01_Clamped fue creada por mí. Lo uso en casi todos los sombreadores. Convierte el valor en el intervalo de origen en el intervalo 0-1. Ideal para crear máscaras basadas en la distancia (desde la cámara, desde el suelo o incluso para formas en el espacio UV).

Aleatorización del color, elementos ocultos.


10:55 p.m.


La obtención de un valor aleatorio desde el punto de referencia de la posición del segmento le permite cambiar la paleta de colores para objetos pequeños. Una paleta es una textura con colores alineados horizontalmente, por lo que mover la imagen utilizada para leer nos da el color final.



La textura de la paleta en una escala ampliada. Su tamaño habitual es de 8 × 1 píxel con compresión deshabilitada


El canal de color del vértice verde sirve como valor de aleatorización y máscara. Un valor de 0 significa "no aplicar color aquí".


Aplicar desplazamiento de posición local



La última función es mover objetos al azar a lo largo del eje X. Para hacer esto, se agrega un desplazamiento de posición controlado por el material a los vértices. Al usar este truco, debes estar atento a dos cosas: colisiones complejas (para disparar) y campos de distancia. Tanto el uno como el otro parámetro no saben que se ha realizado dicho desplazamiento.

Tomaré el canal azul nuevamente y agregaré un número aleatorio, el mismo ruido basado en la posición del segmento que usamos anteriormente. Convirtámoslo del intervalo 0-1 al intervalo de -0.5 a 0.5, para que el movimiento se realice en ambas direcciones. Luego lo multiplicamos por PositionOffsetStrength . El nodo Append agregará los ejes restantes (constante 0 en Y y Z).

Muy inesperadamente, Unreal requiere que la salida se desplace en coordenadas mundiales . Calculamos la posición local . ¿Cómo convertirlo?

Esto se puede hacer transformando el espacio de esta nueva posición local en espacio mundial utilizando el nodo Transformar . Luego resto la posición inicial del vértice en el mundo de esta nueva posición del vértice, obteniendo el desplazamiento del mundo en lugar de la posición. Combine esto con el lanzamiento del material World Position Offset , y ahí es donde se realiza el trabajo.


Material terminado


Espero que hayas aprendido algo nuevo de este tutorial. Aquí hay una captura de pantalla de todo el gráfico del nodo de material:


Archivos de proyecto y discusión


Puede descargar archivos de proyecto de forma gratuita (o por donación, si lo desea): archivos de proyecto . Si tiene comentarios o preguntas, únase a la discusión en Reddit .

Lectura adicional


  • Una manera fácil de empaquetar texturas en canales RGB es guardar tres texturas en escala de grises en canales de una sola imagen RGB usando Photoshop. El empaquetado le permite ahorrar espacio y, lo que es más importante, obtener tres texturas en una operación de lectura. Vale la pena el esfuerzo porque leer texturas desde la memoria es una de las operaciones de GPU que requiere más tiempo.

Source: https://habr.com/ru/post/479880/


All Articles