I watched an interesting effect while I was playing Super Mario Odyssey: when Mario or another character was behind an obstacle (walls, etc), a tiny gray silhouette mesh appears.

I tried to build something similar using an amplify shader with Unity but I could not achieve it.

How could I write this?

Here is an example from the game: enter image description here


1 Answer 1


In Amplify forum I found this shader:

We've performed some changes to the XRay sample in order to allow for the effect that you've requested.

Here's a package that contains updated shaders, together with materials and >sample scene:



you can easily make this effect by using ZTEST Operators:

render first pass by unlit gray color and ZTEST Greater ,ZWrite Off.

enter image description here

as you can see when mario is behind of something it will be gray:

enter image description here

then render second pass Albedo by ZTest Default(ZTEST LEqual):

enter image description here

to making dots effect you can sample your texture by screen space-mapped texture sample or dithering.

enter image description here

I wrote this shader without Amplify:

Shader "Custom/Mario/DotsBehindWall" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Dots("Dots",2D) = "white"{}
        _Size("Size",Vector) = (1,1,1,1)
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0

    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200


        ZWrite Off
        ZTest Greater

            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;

            struct v2f
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 grabPos : TEXCOORD1;

            sampler2D _MainTex,_Dots;
            float4 _MainTex_ST;
            float4 _Size;

            v2f vert (appdata v)
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;

            fixed4 frag (v2f i) : SV_Target
                float2 screen = i.vertex.xy/_ScreenParams.xy;
                float4 tex = tex2D(_Dots, screen /_Size);
                return tex;
        ZWrite On
        ZTest LEqual 

        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
    FallBack "Diffuse"

another way to make this effect is using stencil buffer that I explained In this post

  • \$\begingroup\$ Sorry for the late reply, I was a bit busy, I test what you wrote, it works fine, but what I want is that tiny dots, another thing is I'm using "fade" on the render mode from standard shaders for hair materials and this shader you wrote doesn't work on this mode, either way you other post is interesting as well, thanks. \$\endgroup\$ Commented Oct 8, 2018 at 19:15
  • \$\begingroup\$ @LobsangWhite ok I will update my answer.for tiny dots you can use dithering or using dots texture that mapped by this method \$\endgroup\$ Commented Oct 8, 2018 at 20:35
  • \$\begingroup\$ Nice, like a glove, dithering is an interesting option as well. Thanks. \$\endgroup\$ Commented Oct 11, 2018 at 18:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .