Introducción a Shader Graph I : Dissolve Effect

¿Que es Shader Graph?

La creación de shaders en Unity ha sido tradicionalmente el terreno de juego de personas con habilidades para programar. Shader Graph abre el campo para artistas y otros miembros del equipo para que la creación de shaders sea mucho más sencilla. Solo conecta nodos en una red gráfica y podrás ver los cambios al instante.

Requisitos

El Shader Graph está disponible desde Unity 2018.1. Está diseñado para funcionar con otra característica de Unity 2018.1: Scriptable Render Pipeline (SRP). Por lo tanto, no puede usarlo con el Built-In Unity Renderer. Tiene por tanto soporte tanto para LWRP como para HDRP (o para su propio SRP). 

Para este tutorial usaré la versión 2019.2.9f1. 

Lo primero que necesitamos es abrir Unity y crear un nuevo proyecto. Asegúrese de que elige usar el nuevo SRP. En nuestro caso elegiremos el LWRP.

Confirmamos y esperamos que Unity lo prepare todo. Una vez dentro de Unity ya podemos ponernos a trabajar. Por defecto debería tener incluido el paquete Shader Graph. Puedes comprobar ese y otros paquetes instalados en Windows/Package Manager. 

Nuestro primer Shader

En la ventana Project, pulsamos el botón y elegimos Create/Shader/PBR Graph. Si queréis conocer más acerca del PBR está es una buena guía: https://blog.teamtreehouse.com/beginners-guide-physically-based-rendering-unity

Nombramos el archivo con el nombre que queráis. En este caso le llamaremos Standard_Color. Ya tendríamos nuestro primer Shader creado, vamos abrirlo. Lo seleccionamos y en la ventana Inspector pulsamos Open Shader Editor.

oCufYyKYv9EAD9bC6wmb3Gj3lKAX24wheouKo2y2

Si todo ha ido bien, deberíamos ver esto:

LSvbSAtDIGwl8qq3TIM5t9wJsMqp8LKTFPeBI5Tn


Dentro del Shader Editor podemos ver tres sectores claramente diferenciados:

  • PBR Master Node: Es el nodo principal, al que acaban llegando todos los demás. Es el encargado de mostrar las características en el material. 
  • BlackBoard: Puedes activarlo y desactivarlo arriba a la derecha. Es donde creas y guardas las propiedades que necesitas usar. Encontrarás Colores, Vectores, Texturas etc… Estas pueden aparecer en el inspector del material para ser usadas más adelante. 
  • Preview: Es la previsualización actual de la entrada del PBR Master Node. Puedes cambiar el tipo de renderización pulsando el botón derecho. (Cubo, quad,sphere…) 


Una vez conocemos las partes vamos a añadirle funcionalidad a nuestro nuevo Shader. Comencemos añadiendo color. Vamos a abrir el Blackboard y vamos a pulsar en el +. Con esto podremos crear una variable de entre las que Shader Graph nos ofrece. En este caso elegiremos Color. Ahora podremos cambiarle el nombre, pero en nuestro caso lo dejaremos tal y como está, con el nombre Color, que al fin y al cabo es lo que será para nosotros. 

Zc4ARGnCKRs6RflHobuFFRZsabsuTZ2-bIM25O3_

El toggle de Exposed indica si quieres que esa variable aparezca posteriormente en el material para ser editada de forma rápida. En nuestro caso así lo queremos así que la dejamos marcada. En Default puedes elegir el color que desees por defecto, como he dicho podrás cambiarlo después en el material pero si quieres ver como queda en el Shader Editor tendrás que cambiarlo aquí. Por último el Mode te permite establecer el color como HDR. Puedes hacer efectos realmente atractivos con esto pero de momento lo dejaremos como está. 

Una vez creado nuestro Color vamos a arrastrarlo hacia el Grid donde esta el PBR Master y lo soltamos. 

9V5-mopc1-Cky0ysGQIv3jwmbCANYmhqlKriwsEG

Como vemos este nodo Color solo tiene una salida, conectamos la salida con la entrada de Albedo. Si habías cambiado el color default verás que la Preview ahora aparece de otro color. Sino puedes ir ahora y cambiarlo. Una vez hecho esto pulsamos arriba a la izquierda en Save Asset y podemos cerrar el editor. 

Ahora solo nos falta ver nuestro shader en pantalla. Para esto añadimos una esfera a la escena y creamos un nuevo material. Le pondremos de nombre Standard_Color_MAT, por ejemplo. Una vez creado el material, lo seleccionamos y en el desplegable del Shader elegimos ShaderGraph/Standard_Color o como llamases a tu Shader. Arrastramos nuestro nuevo material y lo soltamos encima de la esfera y … 

Gt5MakfAHlvd59SfJa1-gFOTF3T5e0pXV9k8RDDg

Ahora podemos cambiar cambiar desde el Material el Color, ya que anteriormente lo activamos. 

Nodos importantes

Antes de continuar el tutorial voy a explicar algunos de los nodos más usados ya que los vamos a usar más adelante. Me dejo muchos pero para esta introducción son suficientes:

  • Math Basic: Son las operaciones matemáticas más comunes. Suma, División, Multiplicación, Resta …
  • UV: Son nodos que actúan sobre las coordenadas de uv. Podemos rotarlas, moverlas y darle algunos efectos como el Twirl o Spherize. Veremos un ejemplo más adelante. 
  • Shapes: Son texturas generadas proceduralmente dentro del editor. Podemos crear círculos, rectángulos, polígonos etc… 
  • One Minus: es simplemente la operación 1 – x. Es muy útil como veremos más tarde, tanto que tiene su propio nodo. 
  • Noise: es un nodo generador de ruido. Veremos también su uso más adelante. 
  • Step: es un nodo que dado un valor entre 0 y 1, compara la entrada con ese valor y devuelve 0 si es menor y 1 si es mayor. Por ejemplo: si nuestro valor es 0.4, todos los valores por encima que entren en el nodo, serán convertidos a 1 y todos los inferiores serán 0. 
  • Dot: es un nodo que calcula el Producto Escalar entre vectores. Devuelve 1 si apuntan exactamente en la misma dirección, -1 si apuntan en direcciones completamente opuestas y 0 si los vectores son perpendiculares.
  • Lerp: es un nodo que devuelve el resultado de la interpolación lineal entre las dos entradas en función de la entrada T. El valor de la entrada T está sujeto al rango de 0 a 1. Por ejemplo, cuando el valor de la entrada T es 0, el valor de retorno es igual al valor de la entrada A , cuando es 1, el valor de retorno es igual al valor de la entrada B y cuando es 0.5, el valor de retorno es el punto medio de la dos entradas A y B .
dvfKuIFk0uHo9usXA_W0Nh8a-OKOjAehvVNvjAoP
_iYZAzCTRd_ZsZO4OxYaWPGqy82wBP_QXRxP0_PX
TqqHSav3PthMKFK2_S6IEdCJJMW_T-3-uhMYksxc

Dissolve Shader

Una vez conocemos los nodos más importantes, vamos a hacer un Shader algo más complejo que el anterior. Vamos a crear un efecto que disuelva el objeto haciendo que desaparezca y aparezca a nuestro gusto:

b0cuMImmXaSoyFYLaeIUBK29fZ_Ci3bg0F4q0IBE

Para esto volvemos a crear un nuevo Shader y le ponemos de nombre Dissolve. Lo abrimos y seleccionando el PBR Master pulsamos en el icono del engranaje. 

mTfH5f59J9-D1SuPhlEQMOhJQ5EIIg7nUyppt5qa

Aquí vamos a encontrar algunos ajustes interesantes como si el objeto es Opaco o Transparente. En este caso lo dejaremos como está (Opaque) y lo único que marcaremos será el Two Sided. Esto hará que el objeto pinte también sus caras internas, lo que conlleva eso sí, un coste extra. Tenlo en cuenta en el futuro, en este caso para el Cubo en cuestión, nos interesa que las caras internas también se vean cuando está disolviendo. 

Una vez marcado, vamos a crear algunas variables que usaremos. En primer lugar necesitaremos un valor comprendido entre 0 y 1 que se encargue de llevar el progreso disuelto. Será 0 cuando el objeto se vea por completo y 1 cuando esté completamente disuelto. Para eso en el BlackBoard crearemos un Vector1(que no es más que un simple número) y lo nombraremos como Dissolve Value por ejemplo. Para facilitarnos el trabajo, podemos cambiar el tipo de número con Mode. En nuestro caso está comprendido entre 0 y 1 por lo que elegiremos Slider y rellenaremos el min y el max con esos valores. 

GVjdrXdUd5wgo68VAZXzgnXoAZ4zKJUYFfsHsL6F

A su vez, necesitaremos también un Color para el objeto, como en nuestro anterior Shader y un Color diferente para la parte que se esté disolviendo. Creamos ambas variables, estableciendo el Color para disolver cómo HDR si quieres que brille como el del gif (necesitarás también tener el paquete de post procesos y activar el Bloom). Por último necesitaremos un valor que indique el grosor que tendrá el dissolve. Podemos revisar el Gif para ver el grosor que tiene la parte que se está disolviendo. Creadas todas las variables en mi caso quedó así:

BHTqwjabXIcNQITSp4giE7vYqYap_jo8py9gmODQ

Para el efecto de disolver necesitamos en primer lugar una textura que genere ruido donde las zonas negras indiquen lo que llevamos disuelto y las zonas blancas lo que nos queda por disolver. Por suerte, como vimos antes, tenemos un nodo de ruido perfecto para este uso: Simple Noise, asique lo añadimos. Podemos cambiar el valor de Scale del nodo a nuestro gusto. Cuanto menor sea el valor más “zoom” hará el ruido. También vamos a necesitar el nodo Step que si tenías dudas de su uso, en este caso lo vas a entender perfectamente. Ahora unimos la salida de Simple Noise a la entrada Edge del Step.

OBDAu8ofqH97NmiDyLd-C8DjUM5inHHd6RWooXQP

Ahora podemos cambiar el valor del Step entre 0 y 1 para ver su utilidad real. Los valores de ruido que estén por debajo de ese valor devolverán 0 y los que estén por encima devolverán 1. Es decir cuando el Step sea 0 el objeto no se verá y cuando sea 1 se verá completamente. Justo lo que queremos que ocurra. Simplemente conectamos nuestra variable DissolveValue a la entrada In del Step. Para hacer pruebas vamos a colocar la salida del Step en el Albedo del PBR Master. 

47IBegY1oY-JqJAdgG9YmpPuJkA-FWixi2w4_XkZ


Vamos a guardar y vamos a Añadir un cubo a nuestra escena. Crearemos un material con nuestro shader y se lo colocaremos al cubo. En nuestro material podremos cambiar el valor del DissolveValue. Como vemos el efecto se acerca a lo que buscamos, aunque tenemos dos problemas. Primero no se está disolviendo realmente ya que está pasando de negro a blanco simplemente. Y segundo que el efecto está al contrario, cuando el DissolveValue vale 0 debería verse el objeto completo y cuando está a 1 indica que el objeto está completamente disuelto. Vamos a volver a abrir el Shader Editor para solucionar ambas cosas. Primero vamos a hacer que la parte negra se convierta en transparente. Para ello simplemente tienes que conectar la salida del Step con el Alpha del PBR Master. También tendrás que activar el AlphaClip. Aunque el valor que entra por defecto es 1 tendrás que ponerle tu el valor a través de un nodo. Simplemente crea un nodo Integer (que es un número sin decimal) y conectalo a AlphaClip.

2vZGktCs5QVrK93PriAVRbr2Odh7C2cP1E_QRo8J

Para el segundo problema simplemente usaremos el nodo que comentamos anteriormente. OneMinus. Si a 1 le restamos el DissolveValue obtendremos la parte contraria, que es justo lo que necesitamos. 

L97AeLwmUsegX8XJg4b-ZgGuLI_ASeUYPZduertP


Si guardamos y probamos comprobamos nuestro material ahora podemos ver que funciona como queriamos. Se disuelve de blanco a negro con el ruido que creamos. Solo nos falta añadirle color. Para ello volvemos al editor. Necesitamos pintar el borde que se disuelve y a raíz de ahí lo que tengamos a un lado del borde lo borramos y lo demás lo pintamos del color normal. Una forma de encontrar el borde es sumar el DissolveValue y el borde y restar por un lado el Step de la suma y por otro el Step del DissolveValue solo. Es más fácil de entender con una imagen (para que sea más visual he cambiado el valor default del Dissolve Value a 0.5):

aAQZ0f8JRqF_oDtbc_dzo4jdR9mpYq47K6yNK0o3

Como vemos ahora tenemos el borde diferenciado, pero no lo estamos usando. Lo que vamos a hacer es pintar con los colores que creamos al principio. Una buena forma de hacerlo es usar Lerp. Podemos hacer que si la resta es 1(blanco) se coloree con el Color del Borde y si es 0(negro) el color sea el normal. Y esa salida del Lerp la conectamos a Albedo. 

77QSouSTijg3RBGCZaSpa-Q4iE-om4P60Jwrql9t

Ahora podemos guardar y probar el shader. Si todo ha ido bien debería funcionar como esperábamos. Puedes cambiar a tu gusto los valores del material, como los colores o el borde. 

Si eres perfeccionista te darás cuenta de que si el borde es muy grande, pueden quedar algunos restos al disolverse. Esto podemos arreglarlo con un simple cambio. Sumando el valor del borde al dissolve antes de hacer el OneMinus. 

xA1RtGy73NEMVyfmF3Ho5SUAMzdH3OF_mbjKFUCL


También podrías crear una variable para el Scale del Simple Noise. Así tendrías un valor más que podrías modificar desde fuera sin tener que cambiar el shader. Por último vamos a añadir una textura que se añada al color, así lo podremos usar en más objetos. Simplemente crea una variable de tipo Texture2D y arrastrala al grid con los demás nodos. Tendrás que sacar un nodo llamado Sample Texture 2D y arrastrar la textura a la entrada correspondiente. Luego solo queda multiplicar por el color normal y sustituirlo en la entrada A del Lerp anterior. 

wvermOeXjNGp4T217mMOsYIzY6F721hE4dZsHjBk

Guardamos y desde el inspector del material añadimos la textura que queramos y habríamos terminado. 

No es la única forma de hacer este efecto, hay muchas otras, esta es la forma que yo usé. Espero que os sea útil. Cualquier duda que tengáis hacérmela saber y estaré encantado de ayudaros.  Nos vemos en el siguiente.

Language »