在 Unity Shader 中,时间通常用于实现动画、周期性变化或随时间演进的效果。Unity 提供了几种内置方式来表示时间,


1. 内置时间变量

Unity 在 UnityCG.cginc 中定义了几个全局时间变量:

_Time

四维向量,包含不同时间尺度:

float4 _Time;  // (t/20, t, t*2, t*3)
// t = 自游戏开始的时间(秒)
  • _Time.xt/20(缓慢变化)
  • _Time.yt(常用,直接表示时间)
  • _Time.zt*2(两倍速)
  • _Time.wt*3(三倍速)

应用场景:基础动画、周期性变化。

_SinTime_CosTime

预计算的正弦和余弦时间值:

float4 _SinTime;  // (sin(t/8), sin(t/4), sin(t/2), sin(t))
float4 _CosTime;  // (cos(t/8), cos(t/4), cos(t/2), cos(t))

应用场景:无需手动计算三角函数的平滑动画。

2. 使用示例

2.1 纹理滚动(流动效果)

fixed4 frag (v2f i) : SV_Target {
    // 随时间水平滚动纹理
    float2 scrolledUV = i.uv + float2(_Time.y * 0.5, 0);
    fixed4 col = tex2D(_MainTex, scrolledUV);
    return col;
}

2.2 颜色脉动效果

fixed4 frag (v2f i) : SV_Target {
    // 使用 _SinTime.w 实现颜色周期性变化(范围:-1 到 1)
    float pulse = (_SinTime.w + 1) * 0.5;  // 转换为 0 到 1
    fixed4 baseCol = tex2D(_MainTex, i.uv);
    return baseCol * pulse;  // 颜色强度随时间脉动
}

2.3 波纹效果

fixed4 frag (v2f i) : SV_Target {
    // 计算到中心的距离
    float2 center = float2(0.5, 0.5);
    float dist = distance(i.uv, center);
    
    // 随时间变化的波纹
    float wave = sin(dist * 20 - _Time.y * 5);
    wave = saturate(wave * 0.5 + 0.5);  // 转换为 0 到 1
    
    fixed4 col = tex2D(_MainTex, i.uv);
    return col * wave;  // 应用波纹效果
}

3. 自定义时间变量

若需要更精确的控制(如独立于游戏时间的效果),可通过 C# 脚本向 Shader 传递时间值:

3.1 Shader 代码

// 在 Shader 中声明属性
uniform float _CustomTime;

fixed4 frag (v2f i) : SV_Target {
    float animProgress = frac(_CustomTime);  // 0~1 循环
    // 使用 animProgress 控制动画...
}

3.2 C# 脚本

using UnityEngine;

public class TimeController : MonoBehaviour {
    public Material targetMaterial;
    private float customTime = 0f;

    void Update() {
        customTime += Time.deltaTime;
        targetMaterial.SetFloat("_CustomTime", customTime);
    }
}

4. 注意事项

  1. 时间精度

    • _Time 基于游戏时间,受暂停、减速等影响。
    • 若需要不受游戏控制的时间,可使用 Time.realtimeSinceStartup 通过脚本传递。
  2. 性能优化

    • 避免在片元着色器中频繁计算三角函数,优先使用 _SinTime_CosTime
  3. 多 Pass 一致性

    • 在多 Pass Shader 中,不同 Pass 的时间可能略有差异,如需一致性可手动缓存时间值。

总结

方法 优点 适用场景
_Time.y 简单易用,内置支持 基础动画、周期性变化
_SinTime 预计算三角函数,性能优 平滑波动效果
脚本传递时间 精确控制,独立于游戏时间 特殊效果(如 UI 动画)

通过合理使用时间变量,你可以实现纹理动画、颜色变化、物理模拟等多种动态效果。