Unity-Shader – 2D Sprite Shadow

foreword

Today we will implement a relatively simple and practical shader effect – 2D Sprite shadow effect

final effect:

Preparation:

Open unity to create a new 2D scene, import a 2D character picture and a transparent picture (used to receive shadows), modify the picture Texture Type to Sprite type,

Drag the 2D character sprite map to the scene, then drag the transparent map to the character sprite map node, name it shadow, use it to receive the shadow and then create a new material ball, drag it to the shadow node, shader select the shadow we will create. shader.

The scene is as follows:

Implementation idea:

In fact, it is very simple, just pass the texture of the character to the shadow shader, and change the rgb of the pixel whose alpha value is greater than 0 to black.

Shaders:

<pre>
    
     
     // ---------------------------【2D Sprite Shadow】---------------- -----------
     
     
Shader
     
     "lcl/shader2D/playerShadow"
     
     

     
     {<!-- -->
     
     
    
     
     // ---------------------------【Subshader】---------------- -----------
     
     
    SubShader
    
     
     {<!-- -->
     
     
        
     
     // No culling or depth
     
     
        Cull Off ZWrite Off ZTest Always
        
     
     // turn on transparency
     
     
        Blend SrcAlpha OneMinusSrcAlpha
        
     
     // set up the render queue
     
     
        Tags
     
     {<!-- -->
     
      
     
     "Queue"
     
     =
     
     "Transparent"
     
      
     
     "RenderType"
     
     =
     
     "Opaque"
     
      
     
     }
     
     

        
     
     // --------------------------【Channel 1】----------------- ----------
     
     
        pass
        
     
     {<!-- -->
     
     
            CGPROGRAM
            
     
     #
     
     pragma
     
      vertex vert
     
     
            
     
     #
     
     pragma
     
      fragment frag
     
     

            
     
     #include
     
     "UnityCG.cginc"
     
     

            
     
     structure
     
      
     
     appdata
     
     
            
     
     {<!-- -->
     
     
                
     
     float4
     
      vertex
     
     :
     
      POSITION
     
     ;
     
     
                
     
     float2
     
      uv
     
     :
     
      TEXCOORD0
     
     ;
     
     
            
     
     }
     
     ;
     
     

            
     
     structure
     
      
     
     v2f
     
     
            
     
     {<!-- -->
     
     
                
     
     float2
     
      uv
     
     :
     
      TEXCOORD0
     
     ;
     
     
                
     
     float4
     
      vertex
     
     :
     
      SV_POSITION
     
     ;
     
     
            
     
     }
     
     ;
     
     
            
     
     // get vertex shader
     
     
            
     
     v2f
     
      vert
     
     (
     
     appdata
     
      v
     
     )
     
     
            
     
     {<!-- -->
     
     
                
     
     v2f
     
      o
     
     ;
     
     
                o
     
     .
     
     vertex
     
     =
     
      
     
     UnityObjectToClipPos
     
     (
     
     v
     
     .
     
     vertex
     
     )
     
     ;
     
     
                o
     
     .
     
     uv
     
     =
     
      v
     
     .
     
     uv
     
     ;
     
     
                o
     
     .
     
     uv
     
     .
     
     the y
     
     =
     
      
     
     1
     
      
     
     -
     
      o
     
     .
     
     uv
     
     .
     
     the y
     
     ;
     
     
                
     
     return
     
      o
     
     ;
     
     
            
     
     }
     
     

            
     
     //Get the character texture and pass it through c#
     
     
            
     
     sampler2D
     
      _PlayerTex
     
     ;
     
     

            
     
     // Fragment shader acquisition
     
     
            
     
     fixed4
     
      frag
     
     (
     
     v2f
     
      i
     
     )
     
      
     
     :
     
      SV_Target
            
     
     {<!-- -->
     
     
                
     
     // Sample the passed texture
     
     
                
     
     fixed4
     
      col
     
     =
     
      
     
     tex2D
     
     (
     
     _PlayerTex
     
     ,
     
      i
     
     .
     
     uv
     
     )
     
     ;
     
     
                
     
     // Here use step instead of if
     
     
                
     
     // When the transparency value is greater than 1, it will appear black (ie shadow)
     
     
                col
     
     .
     
     rgb
     
     =
     
      
     
     1
     
      
     
     -
     
      
     
     step
     
     (
     
     0
     
     ,
     
     col
     
     .
     
     a
     
     )
     
     ;
     
     
                
     
     return
     
      col
     
     ;
     
     
            
     
     }
     
     
            ENDCG
        
     
     }
     
     
    
     
     }
     
     

     
     }
    
    

C#:

<pre>
    
     
     using
     
      
     
     UnityEngine
     
     ;
     
     

     
     public
     
      
     
     class
     
      
     
     playerShadow
     
      
     
     :
     
      
     
     Mono Behavior
     
      
     
     {<!-- -->
     
     
    
     
     public
     
      
     
     GameObject
     
      shadow
     
     ;
     
     
    
     
     void
     
      start
     
     (
     
     )
     
      
     
     {<!-- -->
     
     
        
     
     if
     
      
     
     (
     
     !
     
     shadow
     
     )
     
      
     
     {<!-- -->
     
     
            
     
     return
     
     ;
     
     
        
     
     }
     
     
        
     
     // Get the texture and pass it to the shader
     
     
        
     
     var
     
      shadowMat
     
     =
     
      shadow
     
     .
     
     GetComponent
     
     <
     
     SpriteRenderer
     
     >
     
      
     
     (
     
     )
     
     .
     
     material
     
     ;
     
     
        
     
     var
     
      playerTex
     
     =
     
      
     
     GetComponent
     
     <
     
     SpriteRenderer
     
     >
     
      
     
     (
     
     )
     
     .
     
     sprites
     
     .
     
     texture
     
     ;
     
     
        shadowMat
     
     .
     
     SetTexture
     
     (
     
     "_PlayerTex"
     
     ,
     
      playerTex
     
     )
     
     ;
     
     
    
     
     }
     
     

     
     }
    
    

Finally, drag the c# script to the character node, drag the shadow to the shadow variable, and click to run

final effect:

at last

Finally welcome to my
GitHub
Star, thank you! There are some special effect demos that I usually realize in the process of learning unity shader.