Unity Shader幽灵效果

发表于2018-10-18
评论0 4.3k浏览
想在游戏中做一个比较酷炫的效果,比如说将人物模型变成鬼片中的幽灵效果,那么该如何去实现呢,下面就给大家分享下用shader实现幽灵的代码实现。

效果如上图所示,代码如下:
Shader "Custom/MyGhostShader" {
    Properties {
        _MainTex ("Main Tex", 2D) = "white" {}  //主纹理
        _BumpMap("Bump Map",2D)= "bump" {}  //法线纹理
        _RimColor("Rim Color",Color) = (0.46,0.0,1.0,0.0) //模型边缘颜色
        _RimPower("Rim Power",Range(0.2,2.0)) = 0.5   //边缘强度放大的倍数
        _Brightness("Brightness",Range(0.0,3.0)) = 1.0 //光强
    }
    SubShader {
        Tags{
            "RenderType"="Transparent"
            "Queue"="Transparent"
            "IgnoreProject"="True"
            }
       //绘制深度缓存区通道
       //科普下:
       //首先,unity先将渲染队列中较前的进行渲染,然后再执行ZWrite,ZTest
       //ZWrite可以取的值为:On/Off,默认值为On,代表是否要将像素的深度写入深度缓存中(同时还要看ZTest是否通过)。
       //ZTest可以取的值为:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off,默认值为LEqual,
       //代表通过比较深度来更改颜色缓存的值。例如当取默认值的情况下,如果将要绘制的新像素的z值小于等于深度缓存中的值,
       //则将用新像素的颜色值更新深度缓存中对应像素的颜色值。需要注意的是,当ZTest取值为Off时,表示的是关闭深度测试,
       //等价于取值为Always,而不是Never!Always指的是直接将当前像素颜色(不是深度)写进颜色缓冲区中;
       //而Never指的是不要将当前像素颜色写进颜色缓冲区中,相当于消失。
     //  1.当ZWrite为On时,ZTest通过时,该像素的深度才能成功写入深度缓存,同时因为ZTest通过了,该像素的颜色值也会写入颜色缓存。
     //  2.当ZWrite为On时,ZTest不通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest不通过,该像素的颜色值不会写入颜色缓存。
     //  3.当ZWrite为Off时,ZTest通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest通过了,该像素的颜色值会写入颜色缓存。
     //   4.当ZWrite为Off时,ZTest不通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest不通过,该像素的颜色值不会写入颜色缓存。
     //可以看到,像素的深度能否成功写入深度缓存,条件是ZWrite为On,ZTest通过;
        Pass{
           ZWrite On  // 写入深度缓存的作用就是为ZTest的比较做准备
           ColorMask 0
        }
        CGPROGRAM 
        #pragma surface surf Lambert alpha noambient nodirlightmap novertexlights
        struct Input{
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 viewDir;//当前视角方向
        };
        sampler2D _MainTex;
        sampler2D _BumpMap;
        float4 _RimColor;
        float _RimPower;
        float _Brightness;
        void surf(Input IN,inout SurfaceOutput o)
        {
          half4 basecol=tex2D(_MainTex,IN.uv_MainTex);
          //RGB 转为灰度值的心理学公式 Gray = 0.30 * R + 0.59 * G + 0.11 * B 
          half3 graycol=dot(basecol.rgb,float3(0.3,0.59,0.11));
          o.Albedo=graycol;
          o.Normal=UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
          //点积即为cosA的值(其中A是viewDir和Normal的夹角),值域为1-0
           //那么1-cosA的值域就变成0-1了,当A角度达到90,正好模拟边缘光的强度
          half rim=1.0-saturate(dot(normalize(IN.viewDir),o.Normal));                                
          //把边缘光放大_RimPower倍,使边缘光更清楚
          o.Emission=_RimColor.rbg*pow(rim,_RimPower)*_Brightness;
          o.Alpha=(o.Emission.r+o.Emission.g+o.Emission.b) / 3.0;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
具体的讲解可以参考代码中的注释。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引