# 【Shader练习-全息投影】

全屏显示

Markdown 图片

Shader "Examples/Holographic/Shaders/Holographic" {
    Properties {
        [HDR] _BaseColor("颜色",Color) = (1,1,1,1)
        _MainTex ("全息条纹",2d) = "gray"{}
        _RollSpeed ("滚动速度",Range(0.0,1.0)) = 0.1
        _FresnelPow("菲涅尔次幂",Range(0.0,10.0)) = 2
        [HDR]_FresnelColor("菲涅尔颜色",Color) = (1,0,0,1)
    }
    SubShader {
        Tags {
            "Queue" = "Transparent"                     // 调整渲染排序
            "RenderType" = "Transparent"                // 修改为透明模式
            "ForceNoShadowCasting" = "True"             // 不捕获阴影
            "IgnoreProjector"= "True"                   // 不响应投射器
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            Blend One One  //  修改混合方式

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
            uniform float _RollSpeed;
            uniform float _FresnelPow;
            uniform float3 _BaseColor;
            uniform float3 _FresnelColor;

            struct VertexInput {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv0 :TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos :SV_POSITION;
                float4 posWorld : TEXCOORD0;// 世界坐标位置
                float2 uv0 :TEXCOORD1;
                float2 scenepos :TEXCOORD2;
                float4 projPos : TEXCOORD3;
                float3 normalDir : TEXCOORD4;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.normalDir = UnityObjectToWorldNormal(v.normal);
                o.pos = UnityObjectToClipPos( v.vertex );
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                o.uv0 = TRANSFORM_TEX(v.uv0,_MainTex);

                // 获取屏幕坐标核心代码
                o.scenepos = ComputeScreenPos(o.pos);
                o.projPos = ComputeScreenPos(o.pos);
                COMPUTE_EYEDEPTH(o.projPos.z);

                // 使UV在Y轴上进行滚动
                float val = frac(_Time.y * _RollSpeed);// val 在 0~1之间
                o.scenepos = o.scenepos + float2(0,val);
                
                return o;
            }

            float4 frag(VertexOutput i) : COLOR {
                // 屏幕坐标
                float2 screenPos = i.scenepos * i.projPos;
                // 提取贴图
                float3 var_MainTex = tex2D(_MainTex,screenPos);

                // 菲涅尔反射
                float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float3 nDirWS = i.normalDir;
                float fresnel = 1.0-(dot(vDirWS,nDirWS)*0.5+0.5);
                fresnel = pow(fresnel,_FresnelPow);
                float4 resultCol = float4(_BaseColor * var_MainTex.x,1) + float4((_FresnelColor * fresnel),1);

                // 动画闪烁
                float flash = (cos( _Time.y*4)+3)/8.0;
                resultCol = resultCol * flash;

                // 抖动
                float val = frac(_Time.y * 5);// val 在 0~1之间
                if(val < 0.15)
                {
                    return float4(resultCol.rgb*0.8,0.8);
                }
                return resultCol;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

若需要不显示自身遮挡的部分,可以新增一个PASS即可解决。

原理是预先写入深度信息,不写入颜色信息。

        Pass{
            Cull Off
            ZWrite On
            ColorMask 0
            CGPROGRAM
            float4 _Color;
            #pragma vertex vert
            #pragma fragment frag

            float4 vert(float4 vertexPos : POSITION) : SV_POSITION
            {
                return UnityObjectToClipPos( vertexPos );
            }

            float4 frag(void) : COLOR
            {
                return _Color;
            }
            ENDCG
        }

度盘:https://pan.baidu.com/s/1sJ4zAN5S7vxTuacGLjg8OA?pwd=66a1 (opens new window)