¿CÓMO PODEMOS DAR MOVIMIENTO A NUESTROS OBJETOS CON SHADERS?

Podemos dar movimiento a cualquier objeto utilizando shaders, ¿cómo? moviendo de posición sus vértices o su respectivo mapa UV. En el ejemplo de este artículo daremos vida a un alga marina usando la función seno.

  • Para este ejercicio, utilizaremos URP (Universal Render Pipeline), también funciona en Lightweight Render Pipeline y en HDRP.
  • Utilizaremos Shader Graph, eventualmente escribiré un artículo de cómo lograr esto en código.


Shader moviendo los vertices de nuestro mesh

Para guiarnos utilizaremos la página:

Escribiremos lo siguiente para ver la función seno(sine):
sin(x)


Ahora podremos ver la gráfica de seno que le dará movimiento a nuestra vegetación, sin embargo, para tener mayor control sobre la apariencia de nuestra onda, debemos poder controlar el comportamiento de ésta, agregaremos la variable h que nos permitirá trasladar la gráfica:
sin(x-h)



Si cambiamos el valor de la variable h, podremos ver como nuestra función se mueve, en el shader, esto servirá para dar movimiento a nuestra vegetación. Ahora, necesitamos controlar la frecuencia de nuestra función, agregaremos la variable b que pasará dividiendo el resultado de ' x - h ' y quedará así:
sin ( x - h / b) 


Ahora, modificando el valor de b, alteraremos la frecuencia de nuestra función seno, visualmente se apreciará como la cantidad de deformaciones aplicada sobre nuestra vegetación, entre más lineal sea la función nuestro objeto se verá más plano y viceversa:



Finalmente definiremos esta función como 'y' y la multiplicaremos por una variable 'a' con la que modificaremos la amplitud de nuestra onda, nuestra operación finalizará de la siguiente manera:
y = a sin (x - h / b) 



Con esto, ya tenemos la formula que aplicaremos a nuestro shader, podemos controlar la amplitud (a), la velocidad (h) y la frecuencia (b), eso va a  distorsionar nuestros vértices y por lo tanto crear movimiento.

Recordemos: Lo que vamos a hacer es pasar la información de nuestra onda a la posición de los vértices en la geometría designada para la vegetación, de esta manera, los vértices estarán actualizando constantemente su posición de acuerdo a la información de nuestra onda, en el siguiente ejemplo se puede ver con mejor claridad:

Podemos ver como los vértices se mueven tomando la forma de la función seno, y la textura simplemente se desplaza con ellos. 


SHADER GRAPH

PARTE 1

Teniendo esto, solo queda repetir el proceso dentro de los nodos de Shader Graph

Siguiendo la fórmula:

y = a sin(x - h / b) 




1-El nodo 'Split' separa todos los vectores que existen en nuestro nodo UV y los representa en 'R,G,B,A', recordemos que estos también significa 'X,Y,Z,W'.

Obtendremos nuestro valor 'x' de la coordenada UV de nuestro mesh, recordemos que:
U = X
V = Y 

Con esto, tenemos el valor 'x' de nuestra fórmula, ahora le restaremos el valor 'h', por lo que crearemos un valor flotante (o vector 1) de valor 1 y se lo restaremos a nuestro valor anterior (x).

2-Con esto tenemos (x - h), ahora debemos dividirlo entre 'b', simplemente ponemos un nodo de división y un valor flotante (o vector 1) y lo nombramos 'b' y este también tendrá un valor de 1. 

3-Hasta ahora tenemos (x - h / b), ahora debemos obtener el seno (sine) de este resultado, conectamos un nodo 'sine' al resultado de nuestra operación previa y tendremos por resultado:
y = sin (x - h / b) 

4-Solo necesitamos multiplicar ahora esto por una variable 'a', procedemos a multiplicarlo de la misma manera, se coloca un nodo 'multiply' y conectamos un valor flotante (o vector 1) de nombre 'a' con valor 1. 


Listo, con esto ya tenemos nuestra fórmula hecha dentro de shader graph:

y = a sin (x - h / b) 

PARTE 2


Ahora, agregamos un nodo 'Position' en 'Space Object',  éste nos permitirá acceder a la posición de los vértices de nuestro mesh y modificarlos. Usamos un nodo 'split'  para separar el vector Y (G) del nodo 'position', ya que éste es el que modificaremos con nuestra función seno. 

Colocamos un nodo 'Add' y conectamos el resultado de nuestra función seno con el vector Y(G) del nodo position.

Agregamos un nodo 'Combine' para combinar el resultado de la posición de los vértices de nuestro objeto, en el caso de X y Z (R, B) mantendrán su posición original, por lo que los conectamos directo del 'split', pero nuestro vector Y(G) está siendo alterado por nuestra función seno, ésta es la que le dará movimiento a esos vértices, conectamos el resultado del nodo 'Add' al vector Y(G) del nodo 'Combine' y finalmente lo conectamos al resultado final de 'Position' en nuestro Vertex Shader. 

Por supuesto, no olvides conectar una textura a tu material para poder visualizarlo.


Si creas un material a partir de este shader y se lo aplicas a un plano subdividido, te darás cuenta que al modificar el valor H los vértices del mesh se mueven, ya que este valor es el que está moviendo la onda. 
Si modificas el valor B, cambiaras la frecuencia y si modificas el valor A cambiaras la amplitud de la onda. Estos son los valores de nuestra fórmula anterior alterando nuestra geometría. 

Sin embargo, hay un detalle, y es que nuestra alga aún no se mueve por su cuenta, tenemos que hacerlo manualmente. Para arreglar esto basta con colocar un nodo de tiempo que multiplique nuestra variable 'h'. 



Ahora nuestra geometría se mueve por su cuenta y nosotros solo debemos controlar la velocidad con la variable 'h'.


PARTE 3

Solo queda una cosa por corregir, y es que ahora mismo toda el alga se deforma, necesitamos hacer que la raíz (la base del mesh) se mantenga quieta para lograr un mejor resultado. 

Para esto vamos a usar el nodo 'Lerp' con el fin de crear un efecto 'degradado' entre la posición original de los vértices del objeto y nuestra función seno. 


Creamos un nuevo nodo 'position' en 'Space Object' y lo conectamos en el módulo 'A' de nuestro nodo 'Lerp', éste mantendrá los vértices en su posición original (es decir sin movimiento), mientras que en el módulo 'B' conectamos el resultado de nuestra función seno afectando al vector Y

Finalmente, obtendremos nuevamente el valor Y(G) de un nuevo nodo de UV y lo conectaremos al módulo 'T' de nuestro Lerp, este servirá como degradado para indicar que sección de nuestro mesh se verá afectado por nuestra función seno y cuál no. 



El valor Y del UV devuelve este degradado de negro a blanco, en el cual: 

NEGRO = 0 
BLANCO = 1 
GRIS = Valores intermedios

Por lo tanto, los vértices que más se acerquen al color blanco (valor 1) se verán mayormente afectados por nuestra función seno conectada en el módulo 'B' del 'Lerp' y los vértices que se acerquen al color negro (Valor 0) se verán menos afectados ya que el el nodo 'Position' está conectado al módulo 'A' y éste hace que los vértices mantengan su posición original. 




FINALIZANDO

Y así es como obtenemos el resultado final de nuestro shader, no hay que olvidar que se puede modificar la frecuencia, velocidad y amplitud de la onda. Esto no solo sirve para una textura de alga, puede ser útil para pasto, árboles, agua, banderas, y un sin fin de objetos que pueden aprovechar la función seno para dar más vida a tu proyecto.

NOTAS:

  • Este shader mueve los vértices de un objeto 3D, por lo tanto entre más subdivisiones tenga se verá más suave.
  • Al mismo tiempo, trata de cuidar la cantidad de objetos con subdivisiones que usen un shader como éste, si hay demasiado puede llegar a ser pesado de procesar, ten en cuenta la plataforma a la que va destinada tu juego y considera métodos de optimización extras para mejor funcionamiento.
  • Un efecto parecido puede lograrse modificando la textura en lugar de los vértices, tocaré este tema en otro artículo. 



DESCARGAR

Si te interesa descargar directamente este shader, puedes hacerlo aquí a través de Ko-fi por una pequeña donación:


Estás en completa libertad de usarlo para cualquier fin una vez adquirido. 


Para cualquier duda o aclaración, házmelo saber en los comentarios o ponte en contacto directo conmigo aquí. De igual manera, si deseas contribuir a la página puedes hacerlo mediante mi cuenta en Ko-fi:


Comentarios

Publicar un comentario