DepthMask
Danielbrauer (Talk | contribs) m (Removed comma from URL) |
m (Text replace - "<csharp>" to "<syntaxhighlight lang="csharp">") |
||
Line 47: | Line 47: | ||
==C# - SetRenderQueue.cs== | ==C# - SetRenderQueue.cs== | ||
− | <csharp> | + | <syntaxhighlight lang="csharp"> |
/* | /* | ||
SetRenderQueue.cs | SetRenderQueue.cs |
Revision as of 20:43, 10 January 2012
Author: Neil Carter (NCarter) and Daniel Brauer (Danielbrauer)
Contents |
Description
This shader draws faces which are invisible, but which still appear in the depth buffer. This allows you to prevent objects from being drawn where they are occluded by the mask.
To understand how this technique works, you should know about the depth buffer and render queues before reading further.
Usage
The example package shows how to use the shader to prevent the water from appearing inside a boat's hull. The setup requires two things:
- A mask object using the Depth Mask shader. This object will be drawn just after regular opaque objects, and will prevent subsequent objects from being drawn behind it.
- Objects you wish to be masked must have the SetRenderQueue script attached to them. In the Inspector, change their queue from 3000 (regular geometry) to 3020 (just after the mask shader)
Alternate Use
In most common scenarios, you will only need a few objects to be masked. If, however, you find that you have more objects that need to be masked than objects that do not, you might find it useful to attach the SetRenderQueue script to the masks themselves, and set their queues to 2090 (just before regular geometry). Objects that you don't want masked should have their queues set to 2080 (just before the mask shader).
Example
Unity 3.4.1 package: 111KB
ShaderLab - DepthMask.shader
<shaderlab> Shader "Masked/Mask" {
SubShader { // Render the mask after regular geometry, but before masked geometry and // transparent things.
Tags {"Queue" = "Geometry+10" }
// Don't draw in the RGBA channels; just the depth buffer
ColorMask 0 ZWrite On
// Do nothing specific in the pass:
Pass {} } } </shaderlab>
C# - SetRenderQueue.cs
/* SetRenderQueue.cs Sets the RenderQueue of an object's materials on Awake. This will instance the materials, so the script won't interfere with other renderers that reference the same materials. */ using UnityEngine; [AddComponentMenu("Rendering/SetRenderQueue")] public class SetRenderQueue : MonoBehaviour { [SerializeField] protected int[] m_queues = new int[]{3000}; protected void Awake() { Material[] materials = renderer.materials; for (int i = 0; i < materials.Length && i < m_queues.Length; ++i) { materials[i].renderQueue = m_queues[i]; } } } </csharp>