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

本文介绍了如何通过Unity Shader实现建筑结构透视效果,结合毛玻璃特效和贴近显示功能,使得近处建筑更透明,防止阻挡视线。作者分享了具体的Shader代码,包括结构透视、毛玻璃效果和距离衰减的实现方法,帮助读者理解并应用到自己的项目中。
摘要由CSDN通过智能技术生成
前言

公司需要做个建筑结构演示。看了产品经理的方案感觉实在太low,真的看不下去了。于是我就极不情愿的修改了方案做了这个玩意。

效果:
透视显示建筑结构
离镜头越近的地方越透明,防止阻挡视线

  • 先贴出最终笑狗图~
    在这里插入图片描述
实现思路

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

  1. 建筑结构透视
  2. 毛玻璃特效
  3. 贴近显示
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
        }
    }
}

请留下你的赞再走~~~

  • 26
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千年奇葩

从来没受过打赏,这玩意好吃吗?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值