Crear hierba interactiva en Unreal Engine


Hasta hace poco, la hierba en los juegos generalmente se indicaba mediante una textura en el suelo, en lugar de representar tallos individuales. Pero con un aumento en el poder del hierro, se hizo posible producir hierba. Se pueden ver grandes ejemplos de esta representación en juegos como Horizon Zero Dawn y The Legend of Zelda: Breath of the Wild . En estos juegos, el jugador puede recorrer los prados de césped y, lo que es más importante, el césped responde a las acciones del jugador.

Afortunadamente, crear un sistema así no es muy difícil. De hecho, ¡el artículo te enseñará exactamente eso! En este tutorial aprenderá lo siguiente:

  • Cree un campo vectorial usando un sistema de captura de escena y partículas
  • Doblar la hierba de un jugador basándose en un campo vectorial
Nota: este tutorial asume que ya conoce los conceptos básicos de trabajar con Unreal Engine. Si eres nuevo en Unreal Engine, echa un vistazo a nuestra serie de diez partes de tutoriales de Unreal Engine para principiantes . En particular, consulte el tutorial de Particle Systems para saber cómo usar Cascade en este tutorial.
Nota: este tutorial es parte de una serie de tres tutoriales sobre cómo trabajar con objetivos de renderizado:

Llegar al trabajo


Comencemos descargando los materiales para este tutorial (puede descargarlos desde aquí ). Descomprímalos, vaya a InteractiveGrassStarter y abra InteractiveGrass.uproject . Verá un pequeño campo de hierba que será el tema de este tutorial. También creé un widget para mostrar el objetivo de renderizado de la captura de escena.



Antes de comenzar, debe estudiar el tutorial sobre cómo crear huellas en la nieve , ya que omitiré parte de la información. Vale la pena considerar que la captura y la proyección también se usan en este tutorial. Para ahorrar tiempo, preparé una captura de planos, similar al plano del tutorial sobre las pistas en la nieve.

Para comenzar, veamos otra forma de crear césped interactivo. La forma más común es transferir las coordenadas del jugador al material de hierba y usar una máscara esférica para doblar la hierba en un cierto radio del jugador.

Aunque este enfoque es bastante bueno, no se adapta bien cuando queremos agregar más actores a la hierba. Para cada actor que agregue, deberá agregar otro parámetro de coordenadas y una máscara esférica al material. Un método más escalable es usar un campo vectorial .

¿Qué es un campo vectorial?


Un campo vectorial es solo una textura, cada píxel corresponde a una dirección. Si solía trabajar con mapas de flujo, entonces son similares. Pero en lugar de mover UV, usaremos el contacto de Desplazamiento de posición mundial para mover los vértices. A diferencia de la solución con una máscara esférica, para obtener la dirección de flexión, es suficiente que los materiales muestreen el campo vectorial solo una vez .

Veamos cómo puedes guardar direcciones en una textura. Mira esta cuadrícula:


Digamos que el punto rojo es el objeto que queremos mover. Si lo movemos a la esquina inferior derecha, ¿qué vector denotará este movimiento? Si respondió (1, 1) , ¡tiene razón! Como probablemente sepa, también puede representar vectores como flores, y así guardarlos en textura. Insertemos este vector en el selector de color Unreal y veamos qué color devuelve.


Como puede ver, la dirección (1, 1) vuelve amarilla. Esto significa que si queremos doblar la hierba en la dirección de los ejes XY positivos, entonces tendremos que usar este color de textura. Veamos ahora los colores de todos los vectores.


El cuadrado inferior derecho se ve bastante bien porque tiene gradientes en ambos ejes. Esto significa que podemos almacenar cualquier vector en este cuadrante como un color, porque cada vector tiene un color único.

Pero hay un problema con los otros tres cuadrantes. Solo tenemos un gradiente a lo largo de un eje, o ningún gradiente en absoluto. Esto significa que varios vectores tendrán el mismo color. Por ejemplo, no podemos distinguir entre los vectores (-1, 1) y (0, 1) .

Estos tres cuadrantes no tienen colores únicos para cada vector porque solo podemos representar colores usando valores del 0 al 1. Sin embargo, estos tres cuadrantes usan valores negativos fuera de este rango.

La solución es redistribuir los vectores para que todos se ajusten en el intervalo de 0 a 1. Esto se puede hacer multiplicando el vector por 0.5 y sumando 0.5 . Aquí hay una visualización de lo que obtenemos:


Ahora cada vector tiene un color único. Cuando necesitamos usarlo para los cálculos, simplemente lo redistribuimos de nuevo al intervalo de -1 a 1. Aquí hay algunos colores y las direcciones correspondientes después de la redistribución:

  • (0, 0): negativo X e Y
  • (0.5, 0.5): sin movimiento
  • (0, 1): X negativo e Y positivo
  • (1, 0): X positivo e Y negativo

Ahora aprendamos cómo crear un campo vectorial en Unreal.

Crear un campo vectorial


A diferencia de crear huellas en la nieve, no realizaremos la captura de la forma de los objetos. En cambio, pintaremos en el objetivo de renderizado con pinceles. Estas serán solo imágenes del campo vectorial seleccionado. Los llamaré pinceles de dirección .

En lugar de dibujar en el objetivo de renderizado con romos, podemos usar partículas . Las partículas mostrarán un pincel de direcciones y las emitirá el jugador. Para crear un campo vectorial, solo necesitamos usar la captura de escena y capturar solo partículas. La ventaja de este método es que crear trazas es muy simple. Además, le permite administrar fácilmente propiedades como la duración del almacenamiento de pistas y su tamaño. Además, las partículas crean trazas temporalmente persistentes, porque existen después de abandonar el área de captura y volver a ella.

A continuación hay algunos ejemplos de pinceles direccionales que podemos usar, así como su efecto sobre el césped. Observe que en el siguiente ejemplo, las partículas son invisibles.


Para comenzar, creemos un material que muestre un pincel de dirección.

Crear material para indicaciones


Hay dos formas de crear un pincel de dirección:

  1. Matemática: las direcciones y la forma se establecen dentro del material. Su ventaja es que no requiere software de terceros y es conveniente para formularios simples.
  2. Conversión de mapa normal: cree un mapa normal de las direcciones y formas deseadas. Para convertir el mapa en un campo vectorial adecuado, es suficiente que eliminemos el canal azul. La ventaja de este método es que puedes crear formas complejas muy fácilmente. A continuación se muestra un ejemplo de un pincel que será difícil de crear matemáticamente.


Para este tutorial crearemos un pincel matemáticamente. Vaya a la carpeta Materiales y abra M_Direction . Tenga en cuenta que el modelo de sombreado Apagado está seleccionado para este material. Esto es importante porque permite la captura de una escena para capturar partículas sin afectarlas.

Para no complicarnos, crearemos un material que hará que la hierba se aleje del centro de la partícula. Para hacer esto, cree el siguiente esquema:


Ahora necesitamos redistribuir. Para hacer esto, agregue los nodos seleccionados y conecte todo de la siguiente manera:


Ahora demos al pincel una forma redonda. Para hacer esto, agregue los nodos seleccionados:


RadialGradientExponential controla el tamaño y la nitidez de la circunferencia del círculo. Multiplicarlo por Color de partícula le permite controlar la opacidad de las partículas del sistema de partículas. Discutiré esto con más detalle en la siguiente sección.

Así es como se ve el pincel:


Haga clic en Aplicar y cierre el material. Ahora que hemos creado el material, es hora de embarcarse en un sistema de trazas de partículas.

Crear un sistema de trazas de partículas


Vaya a la carpeta ParticleSystems y abra PS_GrassTrail . Para ahorrar tiempo, ya he creado todos los módulos necesarios.


Así es como cada módulo afecta las huellas de césped:

  • Engendro: la frecuencia de creación afecta la suavidad de las pistas. Si las pistas parecen intermitentes, entonces debe aumentar la frecuencia de creación. En este tutorial dejaremos el valor predeterminado (20).
  • Vida útil : la vida útil del sendero hasta que la hierba vuelva a su estado original.
  • Tamaño inicial: tamaño de traza
  • Color sobre la vida: dado que usamos Color de partícula en el material, puede controlar la opacidad aquí. También puede cambiar la curva alfa para controlar la desaparición de la pista. Por ejemplo, puede elegir desaparición lineal, entrada y / o salida. En este tutorial, dejaremos la configuración predeterminada, es decir, pérdida lineal.
  • Eje de bloqueo: se usa para dirigir partículas hacia la captura de escena
  • Rotación inicial: se utiliza para garantizar que las partículas estén orientadas a lo largo de los ejes correctos (más sobre esto a continuación)

Primero necesitamos establecer el material. Seleccione el módulo Requerido y establezca Material en M_Direction . También establezca el Modo de clasificación en PSORTMODE Edad más reciente primero .


Este modo de clasificación le permite renderizar nuevas partículas sobre las antiguas. Si esto no se hace, entonces no es nuevo, pero las partículas viejas afectarán la hierba.

El siguiente es la duración de la traza. Seleccione el módulo Lifetime y establezca Constant en 5 . Gracias a esto, el rastro desaparecerá en cinco segundos.


Ahora pasemos al tamaño de la traza. Seleccione el módulo Tamaño inicial y establezca la Constante en (150, 150, 0) . Debido a esto, cada partícula cubrirá un área de 150 × 150.


Ahora tenemos que hacer que se vea en la dirección de capturar la escena. Dado que la escena se captura desde arriba, las partículas deben mirar en la dirección del eje Z positivo. Para hacer esto, seleccione el módulo Bloquear eje y configure las Banderas de bloqueo del eje en Z.


Finalmente, necesitamos establecer la rotación de las partículas. Actualmente, los colores del pincel no están alineados con la dirección que representan. Esto sucedió porque, por defecto, el sistema de partículas se aplica con una rotación de 90 grados. Para solucionar esto, seleccione el módulo de Rotación inicial y establezca el valor Constante en -0.25 . Esto rotará las partículas 90 grados en sentido antihorario.


Y eso es todo lo que necesitamos para el sistema de partículas, así que cerrémoslo.

Luego, necesitamos unir un sistema de partículas a lo que se supone que crea trazas. En nuestro caso, necesitamos adjuntarlo al personaje del jugador.

Fijación del sistema de partículas


Vaya a Personajes \ Maniquí y abra BP_Maniquí . A continuación, cree el componente Partice System y asígnele el nombre GrassParticles .


Luego necesitamos definir un sistema de partículas. Vaya al panel Detalles y establezca Partículas \ Plantilla en PS_GrassTrail .


Sería extraño si el jugador pudiera ver la pista en el juego, por lo que vale la pena ocultarla. Para hacer esto, active Rendering \ Owner No See .


Dado que el sistema de partículas está conectado al jugador (propietario), el jugador no lo verá, pero será visible para todo lo demás.

Haga clic en Compilar y luego en Reproducir . Tenga en cuenta que las partículas no aparecen para la cámara del jugador, sino que se muestran en el objetivo de renderizado.


Hasta ahora, la captura de escena está configurada para capturar todo . Obviamente, esto no nos conviene, porque solo las partículas afectan la hierba. En la siguiente sección, aprenderemos cómo capturar solo partículas.

Captura de partículas


Si capturamos partículas ahora, realizaremos flexiones innecesarias en áreas sin partículas. Esto se debe a que el color de fondo del objetivo de renderizado es negro. La flexión ocurre porque el negro denota un movimiento hacia los ejes XY negativos (después de la redistribución). Para que las áreas vacías no contengan movimiento, debemos hacer que el objetivo de fondo se renderice (0.5, 0.5, 0) . La forma más fácil de hacer esto es crear un gran avión y adjuntarlo al jugador.

Primero, cree material para el fondo. Regrese al Navegador de contenido y abra Materials \ M_Background . Luego, conecte la constante (0.5, 0.5, 0) con Color emisivo .


Nota: al igual que con el material de partículas, cualquier material que capturemos debe tener un modelo de sombreador apagado .

Haga clic en Aplicar y cierre el material. Regrese a BP_Mannequin y luego cree un nuevo componente Plano . Nómbralo Fondo .


A continuación, establezca las siguientes propiedades:

  • Ubicación: (0, 0, -5000). Colocamos el plano tan bajo que no se superpone a ninguna partícula.
  • Escala: (100, 100, 1). Entonces escalamos a un tamaño suficiente para cubrir toda el área de captura.
  • Material: M_Fondo


Al igual que con las partículas, sería extraño si el jugador viera un enorme avión amarillo debajo. Para ocultarlo, active Renderizado \ Propietario sin ver .


Ahora que hemos configurado el fondo, es hora de capturar las partículas. Podemos hacer esto agregando un sistema de partículas a la lista de solo captura de la escena. Esta es una lista de componentes que capturarán la captura de escena.

Uso de la lista de solo visualización


Antes de que podamos agregar a la lista de solo exhibición, necesitamos una forma de obtener todos los actores que afectan la hierba. Una forma de obtenerlos es usar etiquetas . Las etiquetas son cadenas simples que pueden asignarse a actores y componentes. Luego puede usar el nodo Obtener todos los actores con etiqueta para obtener todos los actores con la etiqueta correspondiente.

Como el actor del jugador debe influir en la hierba, necesita una etiqueta. Para agregar una etiqueta, haga clic en el botón Valores predeterminados de clase . Luego cree una nueva etiqueta en Actor \ Tags y asígnele el nombre GrassAffector .


Dado que solo los componentes se pueden transferir a la lista de solo presentación, debemos agregar etiquetas a los componentes que afectan el césped. Seleccione el componente GrassParticles y agregue una nueva etiqueta ubicada en la sección Etiquetas . Nómbrelo GrassAffector también (no es necesario usar esta etiqueta). Repita lo mismo para el componente de fondo .


Ahora necesitamos agregar componentes que influyan en el césped a la lista de captura de escenas de solo presentación. Haga clic en Compilar y cierre BP_Mannequin . Luego abra Blueprints \ BP_Capture . Vaya a Evento BeginPlay y agregue los nodos resaltados. También asegúrese de que los pines marcados estén conectados.


Este circuito recorrerá a todos los actores con la etiqueta GrassAffector . Después de lo cual verificará si el actor tiene componentes con esta etiqueta y los agregará a la lista de solo exhibición.

A continuación, debemos decirle a la captura de escena que use solo la lista de solo presentación. Seleccione el componente SceneCapture y vaya a la sección Captura de escena . Establezca el Modo de renderizado primitivo para usar ShowOnly List .


Haga clic en Compilar y cierre el plano. Si hace clic en Reproducir , verá que el objetivo de renderizado ahora solo captura partículas y el plano de fondo.


En la siguiente sección, llegamos a lo que esperábamos. ¡Es hora de enseñar a la hierba a doblarse!

Doblar la hierba


Primero tenemos que proyectar el objetivo de renderizado en el césped. Vaya a la carpeta Materiales y abra M_Grass . Luego cree los nodos que se muestran a continuación. Establece la textura en RT_Capture .


Como redistribuimos los colores en el intervalo de 0 a 1, antes de usarlos, debemos redistribuir los colores en el intervalo de -1 a 1. Para hacer esto, agregue los nodos resaltados:


Ahora que tenemos la dirección de flexión, necesitamos alguna forma de rotar el césped en esa dirección. Afortunadamente, hay un nodo llamado RotateAboutAxis para esto. Vamos a crearlo.


Comencemos con el contacto NormalizedRotationAxis . Como su nombre lo indica, este es el eje alrededor del cual girará el vértice. Para calcular, solo necesitamos un producto vectorial de la dirección de flexión por (0, 0, -1) . Para hacer esto, necesitamos agregar los nodos seleccionados:


También debemos especificar el ángulo de rotación , es decir, la cantidad de rotación del vértice en relación con el punto de rotación. Por defecto, el valor debe estar entre 0 y 1, donde 0 es 0 grados y 1 es 360 grados. Para obtener el ángulo de rotación, podemos usar la longitud de la dirección de flexión, multiplicada por la rotación máxima.


Multiplicar por una rotación máxima de 0.2 significará que el ángulo de rotación máximo es de 72 grados.

Calcular PivotPoint es un poco más difícil, porque una sola malla de hierba contiene varios tallos. Esto significa que no podemos usar algo como el nodo Posición del objeto , porque devolverá un solo punto para todos los tallos de hierba.

Idealmente, debe usar un editor 3D de terceros para guardar puntos de pivote dentro de los canales UV. Pero para este tutorial, solo aproximamos el punto de pivote. Esto puede hacerse moviéndose de arriba hacia abajo a un cierto desplazamiento.


Para hacer esto, agregue los nodos seleccionados:


En este tutorial, el césped tiene aproximadamente 80 unidades de altura, por lo que establecí este valor para PivotOffset .

A continuación, debemos realizar dos máscaras. La primera máscara asegura que la raíz del tallo no se mueva. La segunda máscara asegura que ningún campo vectorial actúe sobre el césped fuera del área de captura.

Enmascaramiento


Para este tutorial, configuré los colores de la parte superior de la hierba para que los vértices inferiores sean negros y los vértices superiores sean blancos.


Para enmascarar las raíces, simplemente multiplicamos el resultado de RotateAboutAxis por el nodo Vertex Color .


Para enmascarar el césped fuera del área de captura, multiplicamos el resultado anterior por el nodo seleccionado:


Haga clic en Aplicar y cierre el material. ¡Haz clic en Jugar y corre por el césped para dejar huellas en él!


¿A dónde ir después?


El proyecto terminado se puede descargar desde aquí .

Aunque el método que se muestra en el tutorial funciona muy bien para objetos simples como el césped, no es suficiente cuando se usan objetos que requieren más dinamismo. Una solución parcial al problema es usar las versiones físicas del follaje. Consulte esta publicación sobre follaje interactivo para obtener más información.

Finalmente, quiero agradecer a Deathrey de la comunidad de Unreal Engine por la punta de este método de partículas.

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


All Articles