• Evan Nave

Pipeline-Independent Stenciling shaders


This was a tedious adventure into making single mesh prefabs that create the illusion of cutting through an opaque surface. The trick uses several shaders to properly layer meshes together for a 3D hole effect in any location!

The effect works by using the stencil buffer in Unity to selectively allow/prevent things from rendering. The effect in total uses 3 Shaders and 3 Materials. These can be applied all on a singular object/mesh for easy import and use.


This specific implementation is pipeline-independent and can be used for interesting visual effects or environmental changes that don't require physical changes to geometry.

//[_StencilRef] is used in the shader by having this shader property:
[IntRange] _StencilRef ("Stencil Ref", Range(0,255)) = 1

- Stencil-Reveal

This pass must be rendered first to write to the stencil buffer with the value of _StencilRef. This pass acts as the final mask to show the effect.

Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+1"} //First Rendered
        Cull back
        ZTest LEqual //Normal Depth

        Stencil{
            Ref [_StencilRef]
            Comp always
            Pass replace
        }

- Depth Cutout:

This shader must come after the 'Stencil-Reveal' stage and before 'Internal Meshes' stage.

Tags { "RenderType"="Opaque" "Queue" = "Geometry+2"}
        ZTest Always //Renders ontop of all meshes.
        
        Stencil{
            Ref [_StencilRef]
            Comp Equal //Only Render if Stencil Value is == _StencilRef
        }

- Internal Shader:

This pass must be separate from the Depth-cutout pass due to how Unity will handle depth between meshes. Forcing this pass to render after the depth-cutout pass will allow correct sorting.

Tags { "RenderType"="Opaque" "Queue" = "Geometry+3"} //Last to be Rendered
        Cull back
        ZTest LEqual //Normal Depth Testing

        Stencil{
            Ref [_StencilRef]
            Comp Equal //Only Render if Stencil Value is == _StencilRef
        }

Notes:

-This effect can be combined into a single Mesh-data object like so:

-The Stencil-Reveal and Depth-Cutout shaders do not need passes. However having the Depth-cutout pass render the same as the internal-shader may reduce artifacts on concave meshes. Otherwise this method works for both convex and concave geometry.


-An important note is that this effect does have artifacts when the depth-cutout material is in front of another stencil-reveal shader of the same reference value. This is unlikely to happen in the use cases I've described but can happen if this is used in a non-occluded space ie. hovering in the air.


Combined together with Sebastian Lagues Path-Creator codebase it can be used as a footprint generator with depth! I created an additional generator that casts a ray above the path and places prefabs along the curve equidistant apart. Perfect for footprints!


#Unity #3D #Shaders