unity特效之 建筑结构科技透视效果 贴近消失远离显示FadeInOut.shader

在这里插入图片描述

实现思路
其实不少科幻或动作电影中都有类似特效,实现起来并不复杂,只需要将三个小特效结合起来就能实现:

建筑结构透视
毛玻璃特效
贴近显示
1 结构透视的shader
其实就是半透明嘛,根据需求调整cull的面。这个过于初级我就不贴了。

2 毛玻璃
毛玻璃是根据法线做颜色变化
之前我有写过相关的文章,请无情的点击这里https://blog.csdn.net/lengyoumo/article/details/105343400

3 贴近显示
像素远近是根据像素和摄像机的距离来做适当变化。
废话不多说直接上shader,各处都有详细注释

Shader "Custom/FadeDistance" {
    Properties{
        _Inverse("Inverse", int) = 0  /// 如果不等于0 就使用相反的效果
        _MainTex("Texture", 2D) = "white" { }  // 贴图
        _MainColor("MainColor", Color) = (1,1,1,1)  //主颜色
        _FadeNear("fade near distance", float) = 10  //贴近显示的最近距离
        _FadeFar("fade far", float) = 20 // 贴近显示的最远距离
        _FadeRate("Fade Rate", Range(0.001, 2)) = 0.1  // 整体受影响比例
    }
    SubShader
    {
    	// 设置显示类型和队列,由于需要使用像素透明度的fade 所以需要在transparent队列
        Tags { "Queue" = "Transparent" "RenderType" = "Transparent"}
        // 设置剔除面。至少在我这个例子中,cull back的效果好一点,cull off 显得有点杂。
        Cull back
        // 透明混合方式。  最普通的处理方式,不用多说
        Blend SrcAlpha OneMinusSrcAlpha
        pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            struct v2f {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
                float fade : TEXCOORD1;
            };
            int _Inverse;
            float4 _MainColor;
            float _FadeRate;
            float _FadeNear;
            float _FadeFar;
            // 顶点着色器
            v2f vert(appdata_base v)
            {
                v2f o;
                // 将顶点从模型空间转换到裁剪空间
                o.pos = UnityObjectToClipPos(v.vertex);
                // 获取正确的uv坐标
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                // 将坐标转换到观察空间
                float4 posView = mul(UNITY_MATRIX_MV,v.vertex);
                // 物体与镜头距离
                float distance = length(posView);
                // 是否翻转fade方向
                if(_Inverse==0){
                    // 靠近消失
                    o.fade = saturate((distance - _FadeNear) / (_FadeFar - _FadeNear)) * _FadeRate;
                    }else{
                    // 远离消失
                    o.fade = 1 - saturate((distance + _FadeNear) / (_FadeFar + _FadeNear));
                }
                return o;
            }
            // 片元着色器
            float4 frag(v2f i) : COLOR
            {
            	// 合并贴图、主颜色、uv取得像素的颜色信息
                float4 col = tex2D(_MainTex,i.uv) * _MainColor;
                // 计算镜头fade 获取最终像素颜色透明度
                return float4(col.rgb, col.a * i.fade);
            }
            ENDCG
        }
    }

结合1,2,3得到最终的shader代码

Shader "Custom/FadeInOut" {
    Properties{
        _Inverse("Inverse", int) = 0
        _MainTex("Texture", 2D) = "white" { }
        _MainColor("MainColor", Color) = (1,1,1,1)
        _FadeNear("fade near distance", float) = 10
        _FadeFar("fade far", float) = 20
        _FadeRate("Fade Rate", Range(0.001, 2)) = 0.1
        _AlphaValue("_AlphaValue",Range(0.01,1)) = 1
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" "RenderType" = "Transparent"}
        Cull back
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
        pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            struct v2f {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
                float fade : TEXCOORD1;
                float3 viewDir:TEXCOORD2;
                float3 worldNormal:NORMAL;  
            };
            float _AlphaValue;
            int _Inverse;
            float4 _MainColor;
            float _FadeRate;
            float _FadeNear;
            float _FadeFar;
            v2f vert(appdata_base v)
            {
                v2f o;
                o.worldNormal =  UnityObjectToWorldNormal(v.normal);
                float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                float4 posView = mul(UNITY_MATRIX_MV,v.vertex);
                float distance = length(posView);
                if(_Inverse==0){
                    o.fade = saturate((distance - _FadeNear) / (_FadeFar - _FadeNear)) * _FadeRate;
                    }else{
                    o.fade = 1 - saturate((distance + _FadeNear) / (_FadeFar + _FadeNear));
                }
                return o;
            }
            float4 frag(v2f i) : COLOR
            {
                float4 col = tex2D(_MainTex,i.uv)* _MainColor;
                half normalAngle = 1 - abs(dot(i.worldNormal, i.viewDir));
                return float4(col.rgb, col.a * i.fade)  * normalAngle;
            }
            ENDCG
        }
    }
}


————————————————
版权声明:本文为CSDN博主「千年奇葩」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lengyoumo/article/details/110056402

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值