# 【Shader练习-全息投影】
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)