US4L1——流光效果

流光效果

在 Unity Shader 中的流光效果是一种动态的视觉效果,通常用于给材质增加一种闪光或光线移动的效果,使物体表面看起来像是有光在流动。
这种效果常用于武器光效、能量护盾、传送门等等,可以让物体看起来更加生动富有科技感

imageimage

流光效果的基本原理

实现流光效果的原理非常简单:就是利用 Unity 内置的时间变量 _Time​,让UV坐标沿着一个固定的方向持续递增,
然后用偏移后的UV坐标对纹理贴图进行采样,就可以得到流动的效果了。

相关知识详见:US3S9——动态效果

知识回顾:_Time​ 中的 4 个分量分别是 (t/20, t, 2t, 3t)​,t​ 代表该游戏场景从加载开始经过的时间

流光贴图美术相关注意事项

  1. UV 需要均匀的展开,如果 UV 展开不均匀或者出现拉伸,流光的移动会出现扭曲和不自然,需要确保模型的UV展开尽量均匀和平滑
  2. UV 的比例要一致,模型上不同部分的 UV 比例需要保持一致,确保流光效果的移动速度在整个模型上是一致的。
    如果某些区域的 UV 比例过大或过小,流光在这些区域的移动速度会不同
  3. 贴图需要无缝衔接(首尾或上下相连),避免流光效果再边界处出现断裂或跳跃

等等等

imageimage

具体实现

以下面的匕首为例,假设要在其环绕的面片上实现流光效果:

image

我们可以使用 _Time​ 来偏移 UV 坐标,实现流光效果,具体做法可参考:US3S9L3——滚动的背景

  1. 新建 Shader MovingLight

    删除无用代码

  2. 属性声明 属性映射

    • 主纹理
    • 叠加颜色
    • 移动速度
    1
    2
    3
    4
    5
    6
    Properties
    {
    _MainTex("Texture", 2D) = "white"{}
    _Color("Color", Color) = (1,1,1,1) // 光叠加的颜色
    _Speed("Speed", Float) = 1 // 流光移动的速度
    }
  3. 透明相关设置

    • 渲染标签设置——渲染类型,渲染队列
    • 混合模式 用 Blend One One​ 直接叠加颜色 让其效果更亮 更有流光的感觉
    • 关闭剔除 两面都渲染
    1
    2
    3
    4
    5
    6
    7
    8
    SubShader
    {
    Tags { "RenderType"="Transparent" "Queue"="Transparent" }
    Blend One One // 使用直接叠加颜色的方式进行混合,使其更亮,更具有流光的效果
    Cull Off

    Pass { /*...*/ }
    }
  4. 顶点着色器

    坐标转换,纹理缩放偏移

    1
    2
    3
    4
    5
    6
    7
    v2f vert (appdata_base v)
    {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    return o;
    }
  5. 片元着色器

    _Time​ 进行 U 轴方向的偏移采样,返回采样颜色 * 叠加颜色

    1
    2
    3
    4
    5
    6
    fixed4 frag (v2f i) : SV_Target
    {
    // 根据时间对UV坐标进行偏移,这样x(U轴)方向上就可以看到移动的效果了
    i.uv = float2(i.uv.x + _Time.x * _Speed, i.uv.y);
    return tex2D(_MainTex, i.uv) * _Color;
    }

完整 Shader 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Shader "TeachShader/MovingLight"
{
Properties
{
_MainTex("Texture", 2D) = "white"{}
_Color("Color", Color) = (1,1,1,1) // 光叠加的颜色
_Speed("Speed", Float) = 1 // 流光移动的速度
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
Blend One One // 使用直接叠加颜色的方式进行混合,使其更亮,更具有流光的效果
Cull Off

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
float _Speed;

v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// 根据时间对UV坐标进行偏移,这样x(U轴)方向上就可以看到移动的效果了
i.uv = float2(i.uv.x + _Time.x * _Speed, i.uv.y);
return tex2D(_MainTex, i.uv) * _Color;
}
ENDCG
}
}
}

显示效果(对贴图在X轴方向上缩放10,颜色设置为淡蓝色):

image