Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity Silhouette Shader

Does anybody know of a free Unity/ShaderLAB that is just the default sprite shader but when you walk behind something and can no longer see the player, or just a part of it, it displays a completely opaque, one color silhouette that draws over everything.

It should look something like this: https://i.sstatic.net/iByV7.png (From Titan Souls)

like image 576
Duphus Avatar asked Dec 02 '25 13:12

Duphus


1 Answers

You can apply this shader to your player object. It will mark the stencil flag with a 1, for each pixel it draws.

Shader "Custom/StencilHole" { //also used for silhouetted objects
Properties {}
SubShader {
    // Write the value 1 to the stencil buffer
    Stencil
    {
        Ref 1
        Comp Always
        Pass Replace
    }
    Tags { "Queue" = "Geometry-1" }  // Write to the stencil buffer before drawing any geometry to the screen
    ColorMask 0 // Don't write to any colour channels
    ZWrite Off // Don't write to the Depth buffer
    Pass {}
} 
FallBack "Diffuse"
}

Then you can use the below shader on the "tinted glass". It checks the stencil value for each pixel: if equal to 1 is uses the silhouette color(black in your sample), otherwise a combination of the main color(grey in your sample) and a texture (none in your sample). Note: only objects that have the ABOVE shader applied to them will be silhouetted - so you could choose to make the glass color transparent and allow, say.. the ground flowers, to show through.

Shader "GUI/silhouetteStencil" 
{

    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _silhouetteColor ("silhouette Color", Color) = (0,1,0,1)
    }

    SubShader {
        Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" }
        Lighting On Cull back ZWrite Off Fog { Mode Off }
        Blend SrcAlpha OneMinusSrcAlpha

        Pass 
        {
            // Only render texture & color into pixels when value in the stencil buffer is not equal to 1.
            Stencil 
            {
                Ref 1
                Comp NotEqual
            }
            ColorMaterial AmbientAndDiffuse
            SetTexture [_MainTex] 
            {
                constantColor [_Color]
                combine texture * constant
            }
        }

        Pass
        {
            // pixels whose value in the stencil buffer equals 1 should be drawn as _silhouetteColor
            Stencil {
              Ref 1
              Comp Equal
            }
            SetTexture [_MainTex] 
            {
                constantColor [_silhouetteColor]
                combine constant
            }

        }
    }
}
like image 172
Glurth Avatar answered Dec 05 '25 15:12

Glurth