Some people asked me how I’m doing the water reflections in Last Voyage Of The Orlova, so here’s a quick look at the shader. Download at the bottom of the post.
I’m 90% sure I got the base code from this Unify community shader, so I can’t take any credit for inventing this, but the shader didn’t behave quite like I wanted it to and threw some errors in Unity 5, so I hacked some stuff together to get the effect you see below.
I edited the reflection shader to support tinting, so now you no longer need a texture to give the water color. I have a limited understanding of shader programming so it might not be 100% perfect – for instance it doesn’t support transparency (though that can be easily added by changing the RenderType). I also updated the script to use the newer MirrorReflection4 code which was written for Unity 5.
This solution consists of two components: a shader for the groundwork, and a script to render it on a 2D plane (or quad in this case).
The shader has a texture slot and a color picker. The texture is optional, you can just change the water color using the color picker.
The script has settings for the reflection resolution, offset, and which layers should be reflected. I keep the resolution intentionally low (256) because otherwise the reflection is too perfect and it doesn’t look like water anymore. And I like the way it shimmers when you walk.
If you’re looking to add waves (with physics!) to the water surface, the Zippy Water 2D asset is pretty good. I tried it and this method works on their water prefab.
When working in Unity, you sometimes get a never-ending Screen position out of view frustum error in the console. This is because the camera is rendering the reflection using the resolution setting (0, 0, 256, 256 by default) which falls outside of Unity’s camera bounds (0, 0, 1, 1).
If you turn off the script on the water object, or turn off 2D mode for the scene view, the error will stop (it seems it needs at least one perspective camera active to make sense of what it’s doing). While annoying, this error shouldn’t affect any standalone builds, and is a known issue with the Unity engine.It looks like changing line 72 in MirrorReflection.cs from reflectionCamera.projectionMatrix = projection; to reflectionCamera.projectionMatrix = cam.projectionMatrix; stops the error.