简介
今天来研究几个效果,最近比较忙,所以来弄几个比较简单的效果玩一下。不过也是游戏中常用的一些效果,流光效果,按照方向的溶解效果。其实这几个效果主要运用的就是世界空间坐标或者模型空间坐标用于采样的一个方法,总之就是有些非主流的纹理采样方式。不多说,下面进入正题。
流光效果
首先来看一下流光效果。流光效果是一个非常常见的效果,不仅仅是游戏,一些广告之类的也都会有这种效果。流光的原理还是比较简单的:首先就是需要一张流光图,这张流光图的大部分都是黑色,然后有一条亮线,然后我们在采样的时候,最终输出叠加上这张图的采样值,并根据时间调整采样的UV就可以有流光的效果啦。下面是一个比较简单的流光效果实现:
//流光效果
//by:puppet_master
//2017.7.29
Shader "ApcShader/FlashEffect"
{
Properties
{
_MainTex("MainTex(RGB)", 2D) = "white" {}
_FlashTex("FlashTex", 2D) = "black" {}
_FlashColor("FlashColor",Color) = (1,1,1,1)
_FlashSpeedX("FlashSpeedX", Range(-5, 5)) = 0
_FlashSpeedY("FlashSpeedY", Range(-5, 5)) = 0.5
_FlashFactor ("FlashFactor", Range(0, 5)) = 1
}
CGINCLUDE
#include "Lighting.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform sampler2D _FlashTex;
uniform fixed4 _FlashColor;
uniform fixed _FlashSpeedX;
uniform fixed _FlashSpeedY;
uniform fixed _FlashFactor;
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : NORMAL;
float2 uv : TEXCOORD0;
float3 worldLight : TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldLight = UnityObjectToWorldDir(_WorldSpaceLightPos0.xyz);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
half3 normal = normalize(i.worldNormal);
half3 light = normalize(i.worldLight);
fixed diff = max(0, dot(normal, light));
fixed4 albedo = tex2D(_MainTex, i.uv);
//通过时间将采样flash的uv进行偏移
half2 flashuv = i.uv + half2(_FlashSpeedX, _FlashSpeedY) * _Time.y;
fixed4 flash = tex2D(_FlashTex, flashuv) * _FlashColor * _FlashFactor;
fixed4 c;
//将flash图与原图叠加
c.rgb = diff * albedo + flash.rgb;
c.a = 1;
return c;
}
ENDCG
SubShader
{
Pass
{
Tags{ "RenderType" = "Opaque" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
FallBack "Diffuse"
}
shader比较简单,flashuv是随着时间逐渐增大的,这个值肯定会大于1,而正常纹理的范围是0-1,所以,要想让贴图在采样时大于0-1也有效果,我们就必须要把贴图的WrapMode设置为Repeat,否则当这个值大于1之后,边缘就被截断了,我们也就不会看到流光效果了。注意,流光的贴图是一个方向,采样uv偏移是另一个方向,比如我的流光图是水平方向的,那么流光运动的方向就是竖直方向,效果如下面动图所示: