unity-shader 2D - Sprite 影子

前言

今天我们来实现一个比较简单实用的shader特效 - 2D Sprite影子效果

最终效果:

unity-shader 2D - Sprite 影子_第1张图片

准备工作:

打开unity新建一个2D场景,导入一张2D人物图片和一张透明的图片(用来接收影子),修改图片Texture Type为 Sprite 类型,
unity-shader 2D - Sprite 影子_第2张图片
拖入2D人物精灵图到场景,然后拖拽透明图到人物精灵图节点下,命名为shadow,用来接收影子

然后新建一个材质球,拖拽到 shadow 节点上,shader选择我们将要新建的shadow.shader。
场景如下:
unity-shader 2D - Sprite 影子_第3张图片

实现思路:

其实很简单,就是把人物的纹理传递给shadow shader, 把alpha值大于0的像素的rgb变为黑色即可。

shader:

// ---------------------------【2D Sprite 影子】---------------------------
Shader "lcl/shader2D/playerShadow"
{
    // ---------------------------【子着色器】---------------------------
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always
        // 开启透明度
        Blend SrcAlpha OneMinusSrcAlpha
        // 设置渲染队列
        Tags { "Queue"="Transparent" "RenderType"="Opaque" }

        // ---------------------------【通道一】---------------------------
        Pass
        {
            CGPROGRAM
            #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;
            };
            // 顶点着色获取
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.uv.y = 1 - o.uv.y;
                return o;
            }

            //通过c#获取到人物纹理传递过来
            sampler2D _PlayerTex;

            // 片元着色获取
            fixed4 frag (v2f i) : SV_Target
            {
                // 采样传过来的纹理
                fixed4 col = tex2D(_PlayerTex, i.uv);
                // 这里用step代替if
                // 当 透明度值大于1时, 就呈现黑色(即影子)
                col.rgb = 1 - step(0,col.a);
                return col;
            }
            ENDCG
        }
    }
}

c#:

using UnityEngine;
public class playerShadow : MonoBehaviour {
    public GameObject shadow;
    void Start () {
        if (!shadow) {
            return;
        }
        // 获取纹理并传递到shader
        var shadowMat = shadow.GetComponent<SpriteRenderer> ().material;
        var playerTex = GetComponent<SpriteRenderer> ().sprite.texture;
        shadowMat.SetTexture ("_PlayerTex", playerTex);
    }
}

最后把c#脚本拖拽到人物节点上,把shadow拖拽到shadow变量上,点击运行即可
在这里插入图片描述

最终效果:
unity-shader 2D - Sprite 影子_第4张图片

你可能感兴趣的:(Unity,Shader)