Unity3D教程:利用Shader实现死亡特效
游戏人物死亡都会做一些死亡特效,那么这些死亡特效是如何实现的呢,这就需要使用到shader来帮助实现,下面就给大家介绍下Unity3D中利用Shader实现死亡特效的方法。
1、概述
首先来看下我们要实现的效果:
我们的关注点不在角色动画上,而是死亡后角色逐渐消失的效果动画。
2、原理
片段着色器中有这么一个操作:discard,意为抛弃,就是说我不要当前正在处理的这个像素值了,我不写入到帧缓存中,后续的计算也不进行了。如果说我们可以通过一个Mesh Renderer组件来控制是否渲染一个网格的话,那么这里我们就可以通过discard操作来控制是否绘制一个像素了。
说完了discard,再来说说clip(x)函数,这个函数的说明是这样滴:Discards the current pixel, if any component of x is less than zero。翻译过来大意是说:抛弃当前的像素,如果x的任意分量的值小于0.比如说,x是一个float3的类型值,其中只要x、y或者z任意一个的值小于0,那我就执行discard操作。这个函数是对discard操作的一个封装,让我们省去了写条件语句的步骤。
有了上述方法后,我们来思考,如何来实现一个逐渐过渡的消失动画。我们考虑使用一张noise贴图来随机执行discard操作,如果当前取到的noise贴图上的颜色值小于某个阀值,那就执行discard操作。当我动态调整阀值,那就产生了一个逐渐消失的动画,如下图:
到这里就基本有了我们想要的效果,然后我们考虑对边缘做一些处理。我们想要的效果是消失的地方能否有一些黑色的过渡,以此表示烧焦的痕迹。通过对颜色进行亮度调整,我们可以很容易实现这个效果,黑色的地方我们对最终的颜色乘以系数0,然后将系数逐渐过渡到1恢复正常颜色值。以下是实现后的效果:
注意边缘部分的黑色效果。
3、实现
最后给出shader的实现代码:(以下是片段着色器部分的代码,完整代码见附件)
1 2 3 4 5 6 7 8 9 10 11 12 | fixed4 frag (v2f i) : SV_Target { float4 noise = tex2D(_NoiseTex, i.uv2); float dis = noise.r - _Cutoff; clip(dis); dis = clamp(dis*_FadeOut, 0, 1); // sample the texture fixed4 col = tex2D(_MainTex, i.uv)*dis; // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } |
clamp函数是将dis*_FadeOut的计算结果钳位在0和1之间。另外有个saturate函数也可以实现此效果。
_FadeOut参数是一个[1, 100]的范围值,控制边缘黑色过渡的区域。
_Cutoff参数通过脚本来传入:
1 2 3 4 5 6 7 8 | for ( int i = 0; i < m_renders.Length; i++) { for ( int j = 0; j < m_renders[i].materials.Length; j++) { float t = (Time.time - m_startTime)/DeadTime; m_renders[i].materials[j].SetFloat (ParamName, t); } } |
_NoiseTex是噪点图,这里我是使用Photoshop生成的,具体是使用滤镜->云渲染操作。这样就可以得到下面这张图:
如果觉得效果有点单调,可以让美术做个黑色烟雾的粒子效果叠加在角色上面。
下面是完整的示例程序: