Unity3D-实现炉石卡牌特效
相信有些人已经玩过了炉石,想必对炉中的石金币特效记忆深刻吧,其特效做的这么出色是如何实现的呢,下面就给大家介绍下使用Unity3D实现炉石卡牌特效的方法,一起来看看吧。
一、前言
本文旨在与大家一起探讨学习新知识,如有疏漏或者谬误,请大家不吝指出。
二、概述
相信很多人都玩过炉石,炉石中的金卡特效做的非常的棒。这篇文章就来讲一讲炉石里面金卡用到的一些特效的写法。
先来两张炉石的金卡特效,我们来分析一下。
上述两张金卡用到的特效有:uv动画以及扭曲。其中uv动画又可以分为移动、缩放和旋转。我们通过不断地叠加图层来实现丰富的特效,当然,这里考虑性能的消耗,最大的叠加图层设置为4比较好。而之所以是4,是因为每个图层其实都需要一个蒙板来参与混合计算,一张贴图最多有RGBA四个通道,这样我们就可以用一张贴图来存储四个蒙板。
然后来看下我们最终的实现效果:(没有合适的卡牌原画只能随便截图一张了)
接下来我们来分别实现上述功能。
三、实现
l UV缩放
UV缩放是最简单的一个功能,我们可以通过下面的顶点着色器代码来实现:
o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
TRANSFORM_TEX其实就是一个语法糖,具体实现可以在”UnityCG.cginc”中参看,这里略过不讲。通过上述代码,我们通过Tiling和Offset参数来调整uv的大小和偏移。
l UV移动动画
UV移动动画也是比较简单的,根据时间_Time.y来修改uv以实现移动动画:
half2 DoMove(half2 uv, half4 param){
return uv+param.xy*half2(_Time.y, _Time.y);
}
其中param.xy存储的是uv移动的方向和速度,对param.xy做normalize后,即是uv的移动方向,而param.xy的长度即是移动的速度。
l UV旋转动画
由于我们其实是在2D上做的旋转,所以这里我们需要一个2D的旋转矩阵:
这是一个逆时针旋转弧度的旋转矩阵。然后我们考虑用它来对uv进行旋转变换:
half2 DoRotate(half2 uv, half4 param){
float cosx = cos(param.z+param.w*_Time.y);
float sinx = sin(param.z+param.w*_Time.y);
float2x2 m2 = float2x2(cosx, -sinx, sinx, cosx);
//
return mul(m2, uv.xy-param.xy)+param.xy;
}
有几点需要注意,首先,如果我们对uv同时进行了旋转、缩放和平移的变换,那么一般来说,我们是先进行旋转变换,再进行其余两个变换。其次,param.xy是旋转的中心位置,我们应该先将uv平移-param.xy再进行旋转,最后平移param.xy。
l 扭曲
扭曲的一种最简单实现是利用法线贴图来扰动uv,这样用受到扰动的uv去取贴图上的像素时就有了扭曲的效果。
half4 DoDistort(sampler2D src, half2 uv, half mask, sampler2D distTex, half2 uv2, half param)
{
half4 distColor = tex2D(distTex, uv2);
half2 offsetUV = mask*UnpackNormal(distColor)*param;
half4 result = tex2D(src, uv+offsetUV);
return result;
}
最后,取mask贴图的RGBA四个通道,然后将四个图层和原图混合,就基本实现了炉石的金卡特效了:
col.xyz += effect.xyz * mask.r;
(effect是图层的像素值,col则是我们最终得到的结果。)
PS:uv动画还可以通过flow map来实现,灵活度更高,能做出更多的效果。