
護(hù)盾/能量場(chǎng)效果
GitHub項(xiàng)目地址
實(shí)現(xiàn)原理:
1、邊緣發(fā)光
2、相交高亮,主要指能量場(chǎng)和別的物體相交的地方是高亮顯示
3、扭曲效果,指物體被能量場(chǎng)包圍出現(xiàn)的扭曲
1、邊緣發(fā)光
邊緣發(fā)光效果,在我前面的文章中有介紹。
//vert
float3 worldNormal = UnityObjectToWorldNormal(v.normal);
float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
float3 worldView = normalize(UnityWorldSpaceViewDir(worldPos));
o.rimLight = 1 - abs(dot(worldNormal, worldView));
//frag
float rim = pow(i.rimLight, _RimPower);
fixed3 rimColor = _RimColor.rgb * rim;
2、相交高亮
相交高亮,需要獲取深度圖和能量場(chǎng)的深度。
(1)獲取深度圖
//C#通知攝像機(jī),獲取深度圖
Camera.main.depthTextureMode |= DepthTextureMode.Depth;
//shader獲取深度圖
sampler2D _CameraDepthTexture;
//vert計(jì)算屏幕坐標(biāo),范圍[0, w],未齊次除法
o.screenPos = ComputeScreenPos(o.vertex);
//frag計(jì)算觀察空間的深度值
float depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos));
float sceneZ = LinearEyeDepth(depth);
(2)求能量場(chǎng)的深度值
o.vertex = UnityObjectToClipPos(v.vertex);
//計(jì)算觀察空間的深度值z(mì),并儲(chǔ)存到o.screenPos.z
COMPUTE_EYEDEPTH(o.screenPos.z);
得到這兩個(gè)深度值后,就可以計(jì)算相交
float partZ = i.screenPos.z;
float diff = sceneZ - partZ;
float intersect = pow(1 - diff, _IntersectPower);
float rim = pow(i.rimLight, _RimPower);
float glow = max(intersect, rim);
fixed3 rimColor = _RimColor.rgb * glow;
2、扭曲效果
扭曲效果的實(shí)現(xiàn),我們需要抓取屏幕圖像,有兩種方式:
(1)渲染紋理RenderTexture+額外攝像機(jī)(效率更高)
(2)GrabPass(實(shí)現(xiàn)簡(jiǎn)單)
這里我使用GrabPass的方式,GrabPass通常用于渲染透明物體,需要把物體的渲染隊(duì)列設(shè)置成透明隊(duì)列(即"Queue"="Transparent")。這樣才可以保證當(dāng)渲染該物體時(shí),所有的不透明物體都已經(jīng)被繪制在屏幕上,從而獲取正確的屏幕圖像。
//獲取屏幕圖像
GrabPass
{
"_GrabTempTex"
}
sampler2D _GrabTempTex;
o.grabPos = ComputeGrabScreenPos(o.vertex);
fixed4 color = tex2Dproj(_GrabTempTex, i.grabPos);
能量球范圍內(nèi)的屏幕圖像,隨時(shí)間調(diào)整uv的偏移來(lái)模擬扭曲的效果。
//frag
float4 offset = tex2D(_NoiseTex, i.uv - Time.xy) * _DistortTimeFactor;
i.grabPos.xy -= offset.xy * _DistortStrength;
fixed4 color = tex2Dproj(_GrabTempTex, i.grabPos);

扭曲效果
注意事項(xiàng):

使用兩個(gè)Pass渲染
上圖中,左邊的效果使用了一個(gè)Pass渲染,右邊的效果使用了兩個(gè)Pass渲染。
造成這樣的區(qū)別,是因?yàn)槭褂靡粋€(gè)Pass渲染,深度測(cè)試ZTest會(huì)把背后的顏色值覆蓋掉。