Efecto del agua en Unity para Chronoloop

Efecto del agua en Unity para Chronoloop

El efecto de agua que usamos en el juego usa tres conceptos clave:

  • 1: Puedes usar una textura para almacenar información, usando cada canal por separado.
  • 2: Las UVs de un objeto pueden ser alteradas.
  • 3: Las dimensiones de la pantalla contiene información útil.

Refiriéndonos al primer punto, podemos observar en la siguiente textura cómo hay patrones de color raros que no muestran una imagen agradable:

Esto es porque los colores en una textura contienen 4 valores: Rojo, Verde, Azul, y Alpha (Transparencia); y en cada color está colocado un valor diferente:

Water-Chronoloop

Con esto podemos hacer uso de una sola textura para almacenar hasta 4 patrones diferentes.

Refiriéndonos al segundo punto, las UVs son coordenadas que tiene un objeto 3D que basicamente le dicen a la tarjeta gráfica “Quiero que me pases el pixel de la textura que se encuentra en estas coordenadas”. Las coordenadas en la textura van siempre de 0 a 1, pero cuando se obtiene un valor más alto a 1, el valor se repite (por ejemplo, 2.5 sería 0.5, y -0.3 sería 0.7).

Si nosotros modificáramos las coordenadas base de las UVs, el punto donde normalmente se obtendría un pixel de la textura cambiaría y obtendríamos otro pixel de la misma textura. Este efecto produce una distorsión que se puede usar para dar la impresión de una superficie acuosa.

Refiriéndonos al tercer punto, la pantalla contiene la información de la posición como valor numérico de cada uno de los pixeles en pantalla. Si nosotros tratáramos como UVs dicha posición, podríamos hacer proyecciones de textura.

Sin embargo, dada la perspectiva del juego, también pudiéramos usar la posición como profundidad, como veremos más adelante.

El agua de Chronoloop parte de un plano con una gran matriz de UVs.

Nuestro primer paso consiste en aplicar un ligero desplazamiento en horizontal y en vertical de las UVs y obtener 2 muestreos de la textura base, tomando únicamente los canales ROJO (r) y VERDE (g).

Ambos muestreos son combinados y posteriormente agregados a los valores de UV para poderlos distorsionar.

La primera capa visual se obtiene con la muestra del canal azul, la cual es distorsionada con las UVs modificadas.

El resultado es demasiado uniforme y el patrón es muy evidente, por lo cual se modificará usando una máscara. Dicha máscara es obtenida muestreando la textura nuevamente (usando UVs sin distorsionar y luego cambiando el tamaño) en su canal rojo.

La máscara es luego aplicada a la primera capa obtenida para obtener un resultado visual más interesante.

El siguiente paso es obtener los bancos de arena, los cuales están almacenados en el canal alpha de la textura. Los bancos de arena también tienen sus UVs alteradas para volverlos acuosos.

Para darle una ligera variación a la apariencia de los bancos de arena, se vuelve a muestrear la textura, pero aplicándole la máscara localizada en el canal rojo.

Luego se combinan ambos patrones. Al combinarse, tenemos básicamente  una textura a blanco y negro a la cual le podemos asignar fácilmente colores (es decir, un color para blanco y otro para el negro), lo cual nos deja este resultado:

Usando la información de pixel en pantalla y sabiendo que un pixel que se encuentre “arriba” en la pantalla significa que está más al fondo, podemos obtener una máscara del plano de agua.

Chronoloop-09

Con esta máscara podemos simular una profundidad visual en el agua, volviendo invisible el patrón de los bancos de arena y sustituyéndolo por un color.

A este patrón se le agrega otro patrón obtenido anteriormente para lograr la superficie del agua.

Y para finalizar, así como usamos el valor de “altura” para obtener profundidad, también lo usamos para simular el reflejo del sol en el agua y se lo agregamos a la superficie para obtener el resultado final.

Por Ricardo Ibarra (Cubo)

1 Simple Game’s Technical Artist

*Descarga el editable aquí*