I managed to make this work with URP. Here’s how:
Depthmask shader (this cuts a hole in the geometry):
Shader "Custom/DepthMask" {
SubShader {
Tags {"Queue" = "Geometry-1" }
ColorMask 0
ZWrite On
Pass {}
}
}
This writes to the Z buffer at Render Queue 1999. Regular geometry is drawn at Render Queue 2000, at which point they’ll avoid drawing pixels where your DepthMask shader has “drawn”.
Then for the geometry you want to render behind the hole you’ve cut out, it needs to have a Render Queue lower than 1999. Unfortunately, a lot of methods to achieve this are unavailable in URP. You can’t change it in the Shader Graph (at least from my attempts). You can view a material’s Render Queue in the inspector by clicking the 3 dots in the top right and entering Debug mode… However, you cannot change the number when you use URP.
Luckily, we can still use scripts to dynamically change the render queue at runtime!
I found this script in the comment section of a YouTube video:
using UnityEngine;
public class SetRenderQueue : MonoBehaviour
{
[SerializeField]
protected int[] m_queues = new int[] { 2000 };
protected void Awake()
{
SetVals();
}
private void OnValidate()
{
SetVals();
}
private void SetVals()
{
Material[] materials = GetComponent<Renderer>().sharedMaterials;
for (int i = 0; i < materials.Length && i < m_queues.Length; ++i)
{
materials[i].renderQueue = m_queues[i];
}
}
}
it does a great job as it also shows the results in the scene preview.
Result:
(the floor is flat, solid geometry. A cylinder with the DepthMask shader cuts a hole, and the model for the hole’s inside uses a regular lit shader, and uses the SetRenderQueue script with a value of 1998)
To summarize:
- Use the DepthMask shader to cut a hole in regular geometry
- Put the SetRenderQueue script on objects that you want to render behind the DepthMask.
- Set the value of the script in the inspector to 1998 or lower.
Known issues:
It does not render properly on mobile devices. I found this post saying that it can be fixed by setting the camera’s property Clear Flags to “Don’t Clear”… However for some reason this camera setting isn’t available for URP, so if anyone has any ideas how to fix the rendering on mobile, feel free to share them!