Unity3D教程:利用Shader实现死亡特效

发表于2016-05-16
评论2 4.9k浏览

       游戏人物死亡都会做一些死亡特效,那么这些死亡特效是如何实现的呢,这就需要使用到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生成的,具体是使用滤镜->云渲染操作。这样就可以得到下面这张图:



如果觉得效果有点单调,可以让美术做个黑色烟雾的粒子效果叠加在角色上面。

下面是完整的示例程序:

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引