Aquamarina

Overview

Aquamarina was a demo project designed to explore the various applications of shaders in the development of realistic video games, by attempting to create realistic visual effects.

Technologies

Procedural generation

WebGL

2D

Case Study

The goal

The goal was to create a demo environment and, mostly focusing on shaders, try to make it as realistic as possible: from the distortion and fog of the water, to the particles and even the animation of the fish. There were a handful of mechanics to keep the player engaged including hidden collectables, as well as a camera to take photos, and fish bait that allowed you to attract fish to you – but it was kept deliberately simple and the mechanics were to guide the player into interacting with the game environment. The project was developed in Unity, C#, and Unity’s ShaderLab language.

 
Code snippet from the water shader

Looking like water

The first task was to create a scene that – without too much additional content – felt like you were underwater. The very first shader was a post-processing effect that distorted the screen based on depth: the further away something was, the more warped it appeared. This was achieved using the camera’s depth texture and different kinds of 2D noise that determined the level of distortion, and were scrolled over the screen to give the effect movement.

A simple fog shader was also made that gradually faded the environment to a constant blue colour, representing the murkiness and fogginess of the water.

The next thing that was worked on were the caustics.

 

Caustics are the light patterns that appear on surfaces near or under water and are created by light passing through the rippling water’s surface. There are lots of different ways of approaching this: one could calculate caustics using ray-tracing and calculating the reflection and refraction of the paths of light as it moved through the water for true physical accuracy using modern computing systems. However, a simpler effect was chosen using repeating animated textures and light cookies, which allowed it to be adjusted by changing the sun lights intensity and direction, and also meant that areas that were obscured by the sun would not have any caustic lighting.

The surface

The next thing the scene needed was the water’s surface: especially as it was supposed to feel as though one was in the shallows, looking up and seeing the endless blue expanse did not look right.

This part was not too difficult, but it was also kept simple, so no big waves or foam. The surface was also impassable for the player so only the appearance from underneath mattered. Using similar techniques to the first part, using scrolling noise and distorting the light coming from the other side, a nice simple effect that did the job well was created.

 

A sailboat model was also added just to set the scene!

With this done, god-rays were also added – the beams of light that one sees when the light from the sun is scattered by the water. These were also kept simple – again one could approach it using ray-tracing and volumetrics but using particles was enough to provide a satisfying effect in this case.

Adding life

The next things that were added were fish, and they were made to move in a way that felt realistic. In 1986 Craig Reynolds developed a program he called Boids, which was a simulation designed to mimic flocking behaviour of animals, and it follows these 3 rules:

Separation: boids move away from other boids that are too close.

Alignment: boids attempt to match the velocities of their neighbors.

Cohesion: boids move toward the center of mass of their neighbors.

Doing this resulted in some nice looking shoals of fish. Another shader was made to animate the fish by offsetting the mesh vertex positions using a sine wave to mimic their swimming motion.

A shark was also added using the same logic, and some simple first person movement was enabled so the underwater world could be explored.

Finally, the terrain was populated with all sorts of objects: seaweed, rocks, boats, and finally some collectables to attempt to bring the scene to life.

Finishing touches

To finish off the demo, some more features for the player were added: primarily, this was a camera that could take photos which would then be saved to the computer and some camera customisations, such as adjusting the exposure and focal point of the photo – as well as letting the user adjust the tint and temperature of the photo.

Another simple feature that was added was fish bait. This would attract the fish to a single point, allowing one to view them up close easily and take photos of them.