Unity - Shader - 内置

内置变量

_Time

_Time 是 Unity 自动传递给 Shader 的时间变量,它是一个 float4 类型(包含 4 个浮点数)。

_Time 的 4 个分量

分量 公式 用途 举例值(运行 5 秒后)
_Time.x t / 20) 慢速动画 0.25
_Time.y t 最常用,正常速度 5.0
_Time.z t * 2 2 倍速动画 10.0
_Time.w t * 3 3 倍速动画 15.0

为什么最常用_Time.y

因为它就是原始时间(秒),最直观!

内置方法

length()

length() 是 Shader 内置函数,用来计算向量的长度(也叫模或距离)。

数学原理

1
2
3
4
5
6
7
8
9
float2 v = float2(3, 4);
float len = length(v);

// 内部计算:
// len = √(x² + y²)
// len = √(3² + 4²)
// len = √(9 + 16)
// len = √25
// len = 5

为什么中心是(0, 0)而不是(0.5, 0.5)?
关键:坐标系变换!
回顾代码:

float2 centered = i.uv - 0.5;
这行代码改变了坐标系的原点!

📐 坐标系变换详解
原始 UV 坐标系(左下角是原点)

i.uv 的范围:

1
2
3
4
5
6
7
8
(0,1) ┌────────┬────────┐ (1,1)
│ │ │
│ │ │
├────────┼────────┤
│ │ │
│ │ │
(0,0) └────────┴────────┘ (1,0)

原点在左下角

屏幕中心的坐标:i.uv = (0.5, 0.5)
减去 0.5 后(centered 坐标系,中心是原点)

1
2
3
4
5
6
7
8
9
10
centered = i.uv - 0.5;

(-0.5,0.5) ┌────────┬────────┐ (0.5,0.5)
│ │ │
│ │ │
(-0.5,0) ├────────┼────────┤ (0.5,0)
│ │ (0,0) │
│ │ ↑ │
(-0.5,-0.5)└────────┴────────┘ (0.5,-0.5)
原点在中心!

屏幕中心的坐标:centered = (0, 0)

🧮 具体例子计算

例子 1:屏幕中心点

1
2
3
4
5
6
7
8
9
10
11
12
13
// 原始UV坐标
i.uv = (0.5, 0.5)

// 减去0.5
centered = (0.5 - 0.5, 0.5 - 0.5)
= (0, 0)

// 计算距离
dist = length(centered)
= length((0, 0))
= √(0² + 0²)
= √0
= 0

所以中心点的距离是 0! ✅
例子 2:屏幕右边中点

1
2
3
4
5
6
7
8
9
10
11
12
13
// 原始 UV 坐标(屏幕右边中点)
i.uv = (1.0, 0.5)

// 减去 0.5
centered = (1.0 - 0.5, 0.5 - 0.5)
= (0.5, 0)

// 计算距离
dist = length((0.5, 0))
= √(0.5² + 0²)
= √0.25
= 0.5

屏幕边缘距离中心 0.5 单位
例子 3:屏幕右上角

1
2
3
4
5
6
7
8
9
10
11
12
13
// 原始 UV 坐标(右上角)
i.uv = (1.0, 1.0)

// 减去 0.5
centered = (1.0 - 0.5, 1.0 - 0.5)
= (0.5, 0.5)

// 计算距离
dist = length((0.5, 0.5))
= √(0.5² + 0.5²)
= √(0.25 + 0.25)
= √0.5
≈ 0.707

屏幕角落距离中心最远,约 0.707
📊 距离分布图

屏幕各个位置到中心的距离:

1
2
3
4
5
6
0.707 ┌──────0.5──────┐ 0.707
│ │
0.50.00.5
│ ● │ ← 中心距离=0
│ │
0.707 └──────0.5──────┘ 0.707

距离越亮,颜色越白:

1
2
3
4
█████ ← 角落(0.707,最亮)
████ ← 边缘(0.5)
██ ← 靠近中心(0.2)
▓ ← 中心(0,黑色)

step()

step() 函数详解

1
2
3
step(edge, x)
// 如果 x < edge → 返回 0
// 如果 x >= edge → 返回 1

例子:

1
2
3
4
5
6
7
8
9
step(0.5, 0.3)  // 0.3 < 0.5  → 返回 0
step(0.5, 0.5) // 0.5 >= 0.5 → 返回 1
step(0.5, 0.8) // 0.8 >= 0.5 → 返回 1
注意参数顺序:

step(0.3, dist) // dist >= 0.3 时返回1(圆外)
step(dist, 0.3) // dist < 0.3 时返回1(圆内)
↑ ↑
阈值 被比较的值

smoothstep()

函数原型

smoothstep(min, max, x)
返回值

x <= min → 返回 0
x >= max → 返回 1
min < x < max → 平滑插值(S 曲线)

实际例子

1
2
3
smoothstep(0.2, 0.3, 0.1)   // 0.1 < 0.2  → 返回 0
smoothstep(0.2, 0.3, 0.25) // 0.2-0.3之间 → 返回 0.5
smoothstep(0.2, 0.3, 0.35) // 0.35 > 0.3 → 返回 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
float2 centered = i.uv - 0.5;
float dist = length(centered);

// smoothstep(min, max, x)
// x < min → 返回 0
// x > max → 返回 1
// min < x < max → 平滑过渡(0到1)
float mask = smoothstep(0.3, 0.25, dist);
// ↑ ↑
// 外边界 内边界

fixed4 colorInside = fixed4(1, 0, 0, 1);
fixed4 colorOutside = fixed4(0, 0, 1, 1);

return lerp(colorOutside, colorInside, mask);
效果对比:

step(硬边缘): smoothstep(软边缘):
████████ ████████
████████ ███▓▓▓██ ← 有渐变过渡
████████ ██▓▓▓▓▓█
边缘锐利 边缘柔和

lerp()

Lerp = Linear Interpolation(线性插值) 简单说:在两个值之间按比例混合。
📐 函数原型

lerp(a, b, t)
参数

  • a:起始值
  • b:结束值
  • t:插值系数(通常 0-1 之间)
    返回值
1
2
3
result = a + (b - a) _ t
// 或者写成:
result = a _ (1 - t) + b \* t

🧮 数学原理

公式推导

1
2
3
4
5
6
7
8
9
10
11
12
13
当 t = 0
result = a * (1 - 0) + b * 0
= a * 1 + b * 0
= a ← 返回起始值

当 t = 1
result = a * (1 - 1) + b * 1
= a * 0 + b * 1
= b ← 返回结束值

当 t = 0.5
result = a * 0.5 + b * 0.5
= (a + b) / 2 ← 返回中间值

Unity - Shader - 内置
http://example.com/2026/01/07/Unity-Shader-内置/
作者
dsaco
发布于
2026年1月7日
许可协议