Skip to content

Cut out visuals underwater

Goran Saric edited this page Jul 18, 2019 · 1 revision

If you wish to cut out any visuals from the underwater curtain, you have two possible solutions explained in this article. There are several use cases for this technique - we use it to display a side view of the interior of a submarine in our game.

Change renderQueue of a material

The most simple way is to manipulate the render queue of an object.

using UnityEngine;

public class SetRenderQueue : MonoBehaviour {
    [SerializeField]
    protected int[] m_queues = new int[] { 3000 };

    protected void Awake() {
        Material[] materials = GetComponent<Renderer>().materials;
        for (int i = 0; i < materials.Length && i < m_queues.Length; ++i) {
            materials[i].renderQueue = m_queues[i];
        }
    }
}
Just apply this MonoBehaviour to a object with a valid renderer and change the parameter so that the object will get rendered before the under water curtain.

Underwater mask

If you wish to cut out visuals with a mask, it’s getting a bit more complicated since this technique makes use of the stencil buffer. First you need to add this part into the UnderwaterCurtain.shader SubShader brackets:

Stencil {
	Ref 1
	Comp NotEqual
	Pass keep
}
Then create a new shader UnderWaterMask.shader:
Shader "Crest/Mask/Underwater Mask"
{
	SubShader{
		   Tags { "RenderType" = "Transparent" "ForceNoShadowCasting" = "True" }

		   Lighting Off

		   Stencil {
			   Ref 1
			   Comp always
			   Pass replace
		   }

		   CGPROGRAM
		   #pragma surface surf Lambert alpha nofog

		   struct Input {
			   fixed3 Albedo;
		   };

		   void surf(Input IN, inout SurfaceOutput o) {
			   o.Albedo = fixed3(1, 1, 1);
			   o.Alpha = 0;
		   }
		   ENDCG
	}
		FallBack "Diffuse"
}
Create a material with the new shader. Now any object with that material will cut out its own geometry from the underwater curtain and render the stuff that is behind it.
example