Underwater Effects

There’s lots of resources that describe techniques for realistic rendering of water surfaces. Unity comes supplied with several standard water assets, and there are some excellent descriptions of more advanced water effects at scrawkblog to generate spectacular ocean surfaces such as this:

Or Martin Upitis’ blender file: http://www.blendswap.com/blends/view/68857

However, I see much less information and examples of creating underwater effects, so here’s some notes on how I’ve recently approached different elements of making an underwater game scene.

 

a.) Fog

However clear the water in which you’re swimming, visibility is always going to be less than that in air, and global fog is a pretty easy way to achieve this. I chose a grey-blue colour (say, RGB 60,100,120) with Exp2 fog mode, and density of around 0.005 – adjustable depending on how murky you want it.

 

b.) Sea Floor

I got this nice diffuse tiling sand texture from CGTextures.

image

I like this image because instead of having a detailed grain texture, it has those nice smooth marks that you expect from sand that (at least at some point in time) has had waves wash over it. I then generated a normal map from the texture using the GIMP NormalMap plugin (not to be confused with the BumpMap plugin):

image

Then I created a simple Quad and applied a bumped diffuse material to it using these two textures. For more detail you could of course use a sculpted mesh or terrain, but a flat plane was fine for me to start with. Here it is, along with the underwater fog defined previously:

image

 

c.) Caustics

Caustics are the patterns of light you see projected onto surfaces under the water.

http://habibs.files.wordpress.com/2008/04/caustics_rendering_example.jpg

Caustics are easily simulated by using a projector to show an animated texture. The projector should be set to point straight down (i.e. rotation of 90 degrees about the X axis), with an orthographic projection. Then, attach the following script to the projector, which will allow it to cycle through a series of frames of animation:

using UnityEngine;
using System.Collections;

public class AnimatedProjector : MonoBehaviour
{
    public float fps = 30.0f;
    public Texture2D[] frames;
    private int frameIndex;
    private Projector projector;

    void Start()
    {
        projector = GetComponent();
        InvokeRepeating("NextFrame", 0, 1 / fps);
    }

    void NextFrame()
    {
        projector.material.SetTexture("_MainTex", frames[frameIndex]);
        frameIndex = (frameIndex + 1) % frames.Length;
    }
}

To create the frames of caustic animation, you can use a tool such as http://www.dualheights.se/caustics/ (free for non-commercial use). I find that you’ll need to generate somewhere between 30 – 60 frames to get a convincing animation. The frames should look something like this:

image

Assign these textures to the frames[] array of the AnimatedProjector script above, and use a shader with an additive blend mode so that the white parts of the texture lighten the surface onto which they are projected. The caustic generator above creates tileable images, so you can position a grid of projectors next to each other if you want to cover a large area (that’s why you should also use an orthographic projection, to ensure the images don’t get distorted at the edges, which would mess up the tiling).

 

d.) Bubbles

Although I’ve personally never seen anything on the seabed that generates a constant stream of bubbles, it seems to be standard fare in computer games for conveying a sense of being underwater.

https://i2.wp.com/critical-gaming.com/storage/coin6.4.png

These are easy to achieve using a particle emitter to create billboard 2D sprites of a simple bubble texture, drawn using an additive shader. Here’s one example of a suitable bubble texture:

image

If you want to get fancy, you can create a slightly animated texture or apply random forces to make the bubbles “wobble” as they rise to the surface, but generally it’s acceptable to emit them at an angle close to vertical (here I use a cone emitter with radius of 5 degrees). You can add some slight randomness to the size and speed of bubbles too. I don’t understand the exact, complicated physics, but I believe bubbles grow larger as they rise towards the surface, and also large bubbles rise faster than small bubbles, which I’ve implemented through the “Size over lifetime” and “Size by speed” curves. Finally, I make my bubbles “fade out” using an alpha curve in “Color over lifetime”; I’m not sure this is realistic, but it prevents bubbles suddenly “popping” while still underwater. You could instead adjust the particle lifetime to ensure that bubbles just reach the surface before being destroyed. Here’s the complete settings I used:

image

and here’s the bubble stream they create:

image

 

e.) Flora, Fauna, and Furniture

The appropriate props to add to an underwater scene will depend on whether it’s intended to be tropical or polar, shallow or deep water, however, once again sticking with what people expect to find in an underwater game, I added a few rocks, corals, fish, and a sunken rowing boat. Goodness knows whether any of these are authentic or not, but at least they make the scene more interesting. You can find lots of suitable assets, many of them free, on the Unity Asset Store.

 

The Finished Scene

Here’s the final scene – nothing particularly innovative or hardware-taxing, and certainly suitable for mobile devices, but hopefully conveying what players expect from an underwater scene:

image

 

And a video to show the effect of the caustics in action…

This entry was posted in Game Dev and tagged , , , . Bookmark the permalink.

One Response to Underwater Effects

  1. Pingback: Castle Atlantis – Sea Dragons of Atlantis – Part Two | Fantasy Art - Fantasy Artists

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s