During my 2018 Summer Vacation, I spent 4 weeks [30/07/2018 – 24/08/2018] with the PAULEY LTD. development team at the National College of High Speed Rail. In the final 2 weeks, I practised and applied Shaders in Unity and GLSL. In the end, I had produced a full water scene in Unity, using vertex & fragment shaders, and surface shaders; this is the end result:Although poor quality, it’s a little showcase of what I got up to.
In my second week at PAULEY, I created a 2D water scene in ShaderToy: an online GLSL code editor.The premise behind the waves is simple: combine multiple sine waves. I then added foam above a certain height, and made the water transparent. To see the animated wave, and the code behind it, click the image above.
Converting to 3D
The waves can be easily ported over to 3D, and by adding in an extra variable for z [3D depth], you can create convincing waves. The water itself is simply a plane with a vertex shader that moves the points up and down based on the x, z and time values.Making the foam is much more difficult. Part of it is based on the water height; the tips of the waves. To create the foam around the rock, I conducted a depth test. If the line of sight to the water was obstructed (e.g. by a rock), then the small area around was to be foam. This process is shown better by Linden Reid Here.
The final part of the above water was the reflection. I used a cube map of the skybox and the built in reflection HLSL command. As a final detail, I added in slight distortion based on the height of the water.
Under the Sea
The scene below the waves comprised of multiple different objects and shaders. The first shader I completed was the swaying of the vegetation.
This shader only had a vertex part to make the objects sway. Again I used a sine wave to push higher parts of the object further and back. Clicking the code above will take you to Minions Art: a developer who creates small GIF tutorials.
The next part was the water caustics, the light refracting of the water. I first created a simple fragment shader in ShaderToy which generated vertical and horizontal lines with random movements. These could be scaled up of down, and had varying transparency values based on its distance from a set point. For example: the centre of the grid to minimise any artefacts visible. Click the image below to view the code.I could then quickly port it over to HLSL and apply it to the sand floor. Although not accurate, it produces a fairly convincing effect.
The final shader for my scene was the fog. This also uses the depth test to find distances to the camera. It could then cloudy-up parts of the objects based on their distance and the visible range through the fog.
You may notice that below the waves, there is no foam. I ran into a problem with having multiple depth tests and different rendering patterns. At first the water plane was not detected by the depth test due to it not having shadows. However once enabling shadows, the foam went very chaotic. I decided to keep shadows on and just remove the foam from the code. Although without foam, the fog made it difficult to see anyway.
This finishes off my summer work experience project. I learnt a lot from the 4 weeks and I look forward to continuing it further. 🙂