
Este fin de semana tuve algo de tiempo libre entre clases
(tenga en cuenta que el autor estaba recibiendo una Maestría en Ciencias en el momento del artículo) , y decidí volver a crear sombreadores inventando este efecto de escaneo posterior al proceso. Imaginé que se usa en el juego como una especie de efecto de escaneo a distancia. También utilizamos una distorsión de ruido simple para que el efecto se vea un poco más interesante.
En este artículo te diré cómo implementar este efecto en UE4. Hay varias formas en que puede crear este efecto. Uno de estos métodos fue elegido por mí.
Puede abrir imágenes en una nueva pestaña para verlas en una resolución más alta.
Componentes principales
La idea principal de este efecto es crear una versión del renderizado de la escena usando
el operador Sobel , y luego mezclarlo con el renderizado de escena basado en SphereMask, que animaremos para crear un efecto de escaneo.
Este efecto consta de 3 componentes principales:
- Campo escalable SphereMask
- Función Sobel-Edge (no explicaré cómo funciona esta función, ya que es un tema separado, pero me referiré al código que usé)
- Superponer la textura proyectada en la cuadrícula mundial
Campo escalable SphereMask
Esta parte trata sobre cómo creamos SphereMask escalable. Para hacer esto, transferimos la posición del plano al conjunto de parámetros del material, después de lo cual lo usamos de la siguiente manera

Conecte el resultado del nodo
Clamp a la salida
emisiva de su material y verá algo como esto

"TexLoc" es
vector3 , que determina la ubicación de la fuente de la esfera, en mi caso se lee de un conjunto de parámetros materiales, de modo que también se puede leer desde el juego mismo, por ejemplo, para determinar la posición del jugador.
El conjunto de parámetros de nodo especificados anteriormente crea un campo con un radio de esfera de 1024 unidades. Lo usé solo para mostrar el resultado en la ventana de vista previa. Si desea obtener más información sobre cómo trabajar con funciones remotas y entender cómo usarlas, le recomiendo que
visite el sitio web de Inigo Quilez .
Ahora usaremos el
tiempo para escalar la esfera con un intervalo de tiempo establecido.

Esto nos dará el siguiente resultado
Frac (tiempo) básicamente nos da un período constante que continúa yendo 0-1.0-1.0-1. Multiplicamos el tiempo por 0.25 para controlar la velocidad de escala, y luego multiplicamos el resultado por el radio de la esfera, lo que lleva a un cambio en el radio de 0 a 1024, y nos da una máscara animada.
Este es un buen resultado, pero no es lo que queremos del efecto. Necesitamos un anillo de escala. Esto se puede hacer fácilmente usando cálculos simples.

Esto nos dará lo que queremos, un anillo en crecimiento, con un buen gradiente de desvanecimiento que se pueda controlar.

Las operaciones matemáticas en el bloque Edge_Mask básicamente seleccionan la posición en la máscara de degradado, en este caso el valor es 0.5, y determina el borde de la máscara desde la posición actual con un ancho dado, lo que nos permite obtener un anillo. No entraré en los detalles técnicos para obtener los bordes de la máscara, lo más probable es que hable sobre esto en una de las siguientes publicaciones.
Como puede ver, tiene control total sobre el ancho del anillo sin un parámetro escalar, y si quisiéramos, incluso podríamos controlar la atenuación de los bordes, pero no necesitamos esto en este efecto.
El siguiente paso es usar el ruido para crear una versión visualmente interesante del anillo.
Para esto, utilizaremos el nodo
Vector Noise , que forma parte de UE4. Puede leer sobre esto
aquí , o puede usar una textura de ruido que contenga coordenadas UV alineadas en el mundo.
En mi sombreador, configuré el parámetro
Function en Cellnoise en el
nodo Vector Noise , siéntase libre de experimentar con otros tipos de este parámetro para obtener su propio efecto único.

El resultado será el siguiente

Esta es la primera etapa de nuestro shader que se completa, luego consideraremos la implementación de la función Sobel-Edge.
Función Sobel-Edge
Hay muchas opciones diferentes para esta función, algunas de las cuales están más optimizadas que otras, no explicaré su esencia, ya que este es un tema separado, pero una búsqueda regular en Google con las palabras clave "Sobel Edge" u "Sobel Operator" le dará muchas opciones . O utilice el artículo en el
centro de
Gepard_vvk -
Algoritmos para seleccionar contornos de imágenes .
La idea principal del operador de Sobel es esta: tomamos el
objetivo Render de la escena (imagine que es una textura que contiene lo que está viendo actualmente en su ventana gráfica) y comparamos cada píxel con todos los píxeles vecinos a su alrededor. A continuación, comparamos la diferencia de brillo, y si la diferencia está por encima de cierto umbral, la marcamos como un borde, y en este proceso obtenemos una
máscara de textura
RenderTarget en blanco y negro, en la que se ajusta una máscara en los bordes.
El siguiente código es un ejemplo simple de la función del operador de Sobel que
RebelMoogle creó en el sitio web de Shadertoy (lo más probable es que esta opción no esté completamente optimizada, por lo que puede intentar otra implementación), la recrearemos en UE4 en nuestro material.
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; vec3 TL = texture(iChannel0, uv + vec2(-1, 1)/ iResolution.xy).rgb; vec3 TM = texture(iChannel0, uv + vec2(0, 1)/ iResolution.xy).rgb; vec3 TR = texture(iChannel0, uv + vec2(1, 1)/ iResolution.xy).rgb; vec3 ML = texture(iChannel0, uv + vec2(-1, 0)/ iResolution.xy).rgb; vec3 MR = texture(iChannel0, uv + vec2(1, 0)/ iResolution.xy).rgb; vec3 BL = texture(iChannel0, uv + vec2(-1, -1)/ iResolution.xy).rgb; vec3 BM = texture(iChannel0, uv + vec2(0, -1)/ iResolution.xy).rgb; vec3 BR = texture(iChannel0, uv + vec2(1, -1)/ iResolution.xy).rgb; vec3 GradX = -TL + TR - 2.0 * ML + 2.0 * MR - BL + BR; vec3 GradY = TL + 2.0 * TM + TR - BL - 2.0 * BM - BR; fragColor.r = length(vec2(GradX.r, GradY.r)); fragColor.g = length(vec2(GradX.g, GradY.g)); fragColor.b = length(vec2(GradX.b, GradY.b)); }
En UE4, se ve así

Una nota
rápida sobre la implementación de la función: asegúrese de que sus nodos
SceneTexture estén configurados para usar
PostProcessInput0
Dos nodos
personalizados GradX y
GradY , configúrelos de manera similar
GradX :
return -TL + TR - 2.0 * ML + 2.0 * MR - BL + BR;
Graduado :
return TL + 2.0 * TM + TR - BL - 2.0 * BM - BR;
Esto no tiene que hacerse en
Personalizado , lo usé solo por conveniencia, ya que de lo contrario habría demasiados nodos y se formarían espaguetis.
Si conecta el resultado de la función a una salida de material
emisivo , verá lo siguiente

También multiplicamos el resultado por
vector3 regular para hacer los bordes de cualquier color que queramos.

Como resultado, el color del borde cambia.

Mundo de superposición de textura de rejilla
La parte más simple: solo usamos la textura de malla y la proyectamos alrededor del mundo, y luego la combinamos con la función Sobel-Edge para obtener un efecto genial.

Si conecta el resultado de la función a la salida
emisiva , verá

Poniendo todo junto
¡Ahora juntaremos las tres partes para nuestro efecto posterior!
Primero, combinamos las características Sobel-Edge y World-Aligned-Grid, uniéndolas

Luego creamos un nodo
SceneTexture y le agregamos el resultado de Sobel-Edge y World-Aligned-Grid.
Luego interpolamos entre la escena normal y la añadida, usando el resultado de la máscara de anillo que creamos en la primera parte

Y listo, lo hicimos. El resultado final se verá más o menos así. Por supuesto, puede ajustar los parámetros e intentar cambiar sus valores para obtener opciones más interesantes.

Espero que encuentre útil esta información, todo lo mejor :)
Un proyecto de ejemplo con este sombreador se puede encontrar en
github .