结果图
以上效果用shadergraph同样也可以实现,因为这个渲染里面只存在一个pass。
全息投影技术重点在于模型要产生不依赖与模型uv的纹理效果。
计算顶点在屏幕中的位置是个不错的选择。
使用ComputeScreenPos(i.vertex);函数可以获得顶点在屏幕中的坐标,以这个坐标来采样,产生的效果就相当于当前的屏幕盖了一张纹理图。同时,如果想要产生随视角变化的纹理,可以考虑使用模型在世界空间中的坐标的两个值来做uv坐标,这同样是脱离模型uv的。
为了让效果更加生动,采用了_Time来进行uv平移,注意这里的_Time使用,要用原来的值加上_Time的某一维,而不能直接用_Time否则每个顶点的y坐标采样会是一样的。
以下为shader代码:其中我们用了一张贴图来产生纹理,还有张噪波贴图用来模拟随机数,产生全息不稳定 的效果。
Shader "Unlit/ghost"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_LightTex("动画纹理",2D)="white"{}
_NoiseTex("噪波",2D)="white"{}
[HDR]_BorderColor("边缘色",Color)=(1,1,1,1)
_Alpha("透明度",Range(0,1))=0
_Speed("速度",Range(0,15))=1
_FresnelPower("菲涅尔POWER",Range(0,8))=5
_Cutout("裁剪阈值",Range(0,1.1))=0.1
}
SubShader
{
Tags{"Rendertype"="transparent" "ignoreprojector"="true" "queue"="transparent"}
pass{
ZWrite on
ColorMask 0
}
pass{
Blend srcalpha oneminussrcalpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _NoiseTex;
float4 _NoiseTex_ST;
float4 _BorderColor;
float _Alpha;
float4 _MainTex_ST;
float _Cutout;
float _Speed;
float _FresnelPower;
sampler2D _LightTex;
float4 _LightTex_ST;
struct appdata
{
float4 vertex : POSITION;
float3 normal:NORMAL;
float2 uv:TEXCOORD0;
};
struct v2f
{
float2 uv:TEXCOORD0;
float4 vertex : POSITION;
float3 viewDir:TEXCOORD2;
float3 worldNormal:TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.uv=TRANSFORM_TEX(v.uv,_MainTex);
o.worldNormal=normalize(UnityObjectToWorldNormal(v.normal));
o.viewDir=ObjSpaceViewDir(v.vertex);
o.vertex=UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float2 srcpos=ComputeScreenPos(i.vertex);
i.viewDir=normalize(i.viewDir);
srcpos.y+=_Time.w*_Speed;
srcpos=TRANSFORM_TEX(srcpos,_LightTex);
float random=tex2D(_NoiseTex,fixed2(_Time.w,_Time.w));
float4 scrcol=tex2D(_LightTex,srcpos);
float fresnel=pow(saturate(1-dot(i.viewDir,i.worldNormal)),_FresnelPower);
float4 col=tex2D(_MainTex,i.uv);
clip(scrcol-_Cutout);
return fixed4(col.xyz*random*(scrcol),_Alpha*random)+fixed4(fresnel*_BorderColor.xyz,0);
}
ENDCG
}
}
Fallback "Specular"
}