Unity Shader Graph
UV通道
在 Shader 中,UV0 到 UV7 是 8 个独立的纹理坐标通道(或者叫坐标槽位)。
它们的作用是告诉渲染器:如何把 2D 的贴图(纹理)正确地包裹、贴在 3D 模型的表面上。
它们最常见的用途分类:
- UV0(最常用): 基础纹理通道。用来映射模型的主贴图,比如角色的皮肤、衣服颜色、基础材质(Albedo/Base Color)。
- UV1(次常用): 烘焙光照通道。在 3D 游戏中,通常用来存储烘焙的阴影和光照信息(Lightmap)。它的展开方式通常和 UV0 不同,确保模型每个面都不会重叠。
- UV2 - UV7(高级/特效通道): 备用通道。通常用于复杂的视觉特效或高级材质,例如:
- 多层纹理混合: 比如给地面加上一层苔藓(苔藓用 UV2 缩放,地面基础砖块用 UV0)。
- 顶点动画/特效: 比如让某些特效贴图单独沿着另一个方向平移。
- 存储额外数据: 技术美术(TA)有时会把模型的特定几何数据(如高度、动态风吹的权重)塞进 UV3-UV7 里当作数据读取。
简单来说,它们就像是 8 个不同的“涂鸦图层坐标”,最常用的第一层(UV0)贴主图,第二层(UV1)贴影子,剩下的备用图层用来做各种酷炫的特效。
气流效果
参考图片

Unity 粒子系统:Start Color 与 Color over Lifetime 的关系
1. 概念
| 参数 | 作用 | 特点 |
|---|---|---|
| Start Color | 粒子出生时的初始颜色 | 固定值或随机区间;不开启其他模块则全程不变 |
| Color over Lifetime | 粒子生命周期内的颜色渐变 | 渐变条(Gradient),左端(0%)为出生,右端(100%)为死亡 |
2. 核心数学关系
最终颜色=Start Color×Color over Lifetime(当前时间点的颜色)最终颜色=Start Color×Color over Lifetime(当前时间点的颜色)
- 相乘关系 → Color over Lifetime 相当于“滤镜”,Start Color 相当于“底色”
- 每个通道(R, G, B, A)独立相乘
示例:
- Start Color = 红色
(1, 0, 0, 1) - Color over Lifetime = 白色(0%) → 灰色(50%) → 黑色(100%)
- 出生时:红 × 白 = 红
- 50%:红 × 灰 = 暗红
- 死亡时:红 × 黑 = 黑(消失)
3. 常见误区(为什么粒子变黑/隐形?)
| 错误 | 原因 | 结果 |
|---|---|---|
Start Color 为黑色 (0,0,0) | 0 × 任何颜色 = 0 | 粒子始终黑色 |
| Start Color 的 Alpha = 0 | 透明度为0,乘积永远为0 | 粒子完全透明(不可见) |
| Color over Lifetime 某通道为0 | 该通道被乘零 | 对应颜色通道消失 |
4. 最佳实践
若希望完全由 Color over Lifetime 控制颜色:将 Start Color 设为 纯白色
(1, 1, 1, 1),相当于数学中的“1”,不会干扰渐变条的任何颜色。
5. 快速检查清单
- Start Color 不是黑色
- Start Color 的 Alpha = 255(不透明)
- 如需渐变完全生效,Start Color = 白色
- 确认 Color over Lifetime 渐变条各点的 Alpha 值非零(如需要可见)
Unity 粒子系统 Scaling Mode(缩放模式)
三种模式
1. Local
- 自身缩放:影响粒子大小和发射形状
- 父物体缩放:不影响
- 粒子大小:随自身缩放改变
- 场景:独立特效预制体(如火把火焰)
2. Shape
- 自身缩放:影响发射形状/区域
- 父物体缩放:影响发射形状/区域
- 粒子大小:绝对不变
- 场景:天气效果(雨雪)、范围光环、迷雾
3. Hierarchy
- 自身缩放:影响(范围、大小、速度等比缩放)
- 父物体缩放:影响
- 粒子大小:随整体层级改变
- 场景:角色技能、载具尾气(随模型缩放)
对比表
| 模式 | 受自身缩放影响 | 受父物体缩放影响 | 粒子本身大小变化 | 适用场景 |
|---|---|---|---|---|
| Local | 是 | 否 | 随自身缩放改变 | 独立特效 |
| Shape | 是(仅形状) | 是(仅形状) | 绝对不变 | 天气、范围效果 |
| Hierarchy | 是 | 是 | 随整体层级改变 | 角色/载具绑定特效 |
Unity 粒子系统 — Emitter Velocity Mode: Transform
核心原理
通过计算当前帧与上一帧之间 GameObject 的 Transform 位置和旋转变化量 得出发射器移动速度。
计算公式
Velocity=ΔPositionΔTimeVelocity=ΔTimeΔPosition
优点
- 物体移动(Transform.Translate、动画、路径移动)即可计算速度
- 无需 Rigidbody 组件
- 适用于动画控制的飞弹、脚本移动的飞镖、UI 跟随特效
缺点 / 问题
- 物理驱动物体(Rigidbody.AddForce)速度不平滑(FixedUpdate 与 Update 帧差异导致)
- 瞬移(直接设置 position)会产生极大瞬时速度 → Rate over Distance 瞬间喷发大量粒子 / Inherit Velocity 粒子飞射速度异常
对比:Rigidbody 模式
| 项目 | Transform | Rigidbody |
|---|---|---|
| 速度来源 | 每帧坐标差 | 直接读取 Rigidbody.velocity |
| 适用对象 | 动画/脚本移动 | 物理驱动(赛车、抛接物体) |
| 瞬移影响 | 会爆粒子/速度异常 | 无影响(物理速度未突变) |
物体是靠脚本写坐标、播动画移动的(如魔法子弹、特效): 选 Transform 模式。
物体是靠物理引擎(重力、加力、刚体速度)移动的(如赛车、碎石): 选 Rigidbody 模式。



常数节点

时间节点

颜色节点
有默认和hdr两种模式

布尔节点

Wrap Mode

纹理包裹模式(Wrap Mode)详解
核心作用:决定当 UV 坐标超出 [0, 1] 范围(即超出纹理边界)时,贴图如何填充与显示。
1. Repeat(重复)
- 行为:纹理在水平/垂直方向无限平铺,UV 超过 1 时回绕到 0 重新计算(如 1.1 等同于 0.1)。
- 用途:无缝纹理,如墙面、地面、草地、砖块等大面积重复贴图。
2. Clamp(夹紧/拉伸)
- 行为:不重复,UV 超出 [0, 1] 时固定拉伸边缘像素。
- 用途:UI 图标、遮罩贴图、粒子特效等避免边缘重复的场景。
3. Mirror(镜像)
- 行为:重复时每块进行翻转镜像(正→反→正…),消除拼接接缝。
- 用途:需要重复但减少视觉重复感或接缝明显的纹理。
4. Mirror Once(镜像一次)
- 行为:仅在 [-1, 0] 范围镜像一次,超出后转为 Clamp(拉伸边缘)。
- 用途:单一对称轴且边缘需拉伸的特殊材质或特效。
5. Per-axis(按轴独立设置)
- 行为:展开详细选项,允许 U 轴(水平)和 V 轴(垂直)分别设置不同包裹模式。
- 用途:传送带、河流、滚动背景等 U/V 方向需求不同的纹理。
💡 快速选择指南
| 场景 | 推荐模式 |
|---|---|
| 地形、建筑、重复纹理 | Repeat(默认) |
| UI、技能图标、独立贴图 | Clamp(避免边缘重复像素) |
| 需重复但减少接缝 | Mirror |
| 特殊对称/边缘拉伸需求 | Mirror Once 或 Per-axis |
🔧 技术原理补充
- UV 坐标范围 [0, 1]:代表纹理的完整范围,0 是起点,1 是终点。
- 当 UV 值 > 1 或 < 0 时,Wrap Mode 接管决定超出部分的填充逻辑。
- 该设置通常在纹理导入面板(Texture Import Settings)中调整。

Tilling And Offset实现贴图平铺和偏移

SampleTexture2D

UV节点

uv遮罩
只影响部分mesh的


https://www.bilibili.com/video/BV1EzpezPEgy/
https://www.bilibili.com/video/BV1vT411G7UR
模型顶点信息



视角空间,也称为摄像机空间

UV 分量分离后显示为灰阶的原理
核心规律:当任意单一数值(标量) 作为颜色输出时,系统自动以灰度(Grayscale) 显示:0 = 纯黑,1 = 纯白。
1. UV 的彩色从何而来?
- UV 输出为 二维向量(U, V),映射到颜色通道:
- U → 红色通道(R),对应水平方向(X)
- V → 绿色通道(G),对应垂直方向(Y)
- 彩色预览中:
- 左下 (0,0) = 黑;右下 (1,0) = 红;左上 (0,1) = 绿;右上 (1,1) = 黄
2. Split 分离后为何变灰阶?
Split节点提取单一分量(如 G(1)),本质是从二维向量中剥离出单一标量(仅 V 轴数值)。- 单一数字无法用 RGB 表达,系统自动用**亮度(灰度)**表示:
- V=0(底部)→ 无亮度 → 纯黑
- V=1(顶部)→ 最高亮度 → 纯白
- V=0.5 → 中间亮度 → 灰色
3. 延伸思考
- 若提取 R(1) 通道 → 水平方向 U 值 0→1 变化 → 得到从左到右的黑白渐变。
- 该原理适用于所有单通道标量数据(如噪声、高度图、法线单轴等)的灰度预览。

Shader Graph 中放射状渐变(Radial Gradient)的生成原理
核心逻辑:使用 Polar Coordinates(极坐标)节点将 UV 从直角坐标转为极坐标,再通过 Swizzle(通道重组)节点提取距离信息,生成从中心向外的圆形渐变。
1. Polar Coordinates(极坐标节点)
- 功能:将笛卡尔坐标 (X, Y) 转换为极坐标 (R, θ),输出 Vector2。
- R / X 通道(红色) → 距离(Radius):从中心向外,数值从 0 到 1 递增(中心黑 → 外围亮)。
- G / Y 通道(绿色) → 角度(Angle / Theta):绕中心旋转一周,数值从 0 到 1 循环(表现为环状色带)。
2. Swizzle(通道重组节点)
- 功能:从输入向量中提取指定通道。
- 本次设置:Mask 设为
X(红通道)→ 仅提取距离(Radius)信息,丢弃角度。
3. 最终效果
- 提取纯距离值后,预览呈现 从中心(0=黑)向外(1=白)的圆形/放射状渐变。
💡 应用场景
- 能量罩、魔法阵、圆形进度条、光晕、粒子特效等需要中心向外衰减的效果。

Shader Graph 生成反向循环递减信号(-1 ~ 0 循环)
核心目标:利用时间节点生成一个从 0 到 -1 往复循环的递减线性信号(范围 [-1, 0])。
节点拆解
- Time(时间节点)
- 输出游戏运行以来的实时秒数,数值持续线性增加(如 0.1 → 0.5 → 1.5 → 2.3...)。
- Fraction(取小数节点)
- 公式:输出 = 输入值的小数部分(即
x - floor(x))。 - 效果:将无限递增的时间钳制在 [0, 1] 区间循环,形成锯齿波:
- 0.3 → 0.3,0.9 → 0.9,1.0 → 0.0,1.4 → 0.4。
- Subtract(减法节点)
- 计算公式:
输出 = Fraction值 - 1。 - 转换逻辑:
- Fraction = 0 → 输出 -1
- Fraction = 0.5 → 输出 -0.5
- Fraction = 1 → 输出 0
- 结果:信号范围从原来的 [0, 1] 整体下移 1 个单位,变为 [-1, 0] 循环。
最终效果
- 生成一个**从 -1 上升到 0(或从 0 下降到 -1)**的线性锯齿波,常用于驱动需要负数偏移或特定节奏的着色器动画(如呼吸光效、纹理偏移等)。

Saturate(饱和/截断)节点
核心功能
- 作用:将输入值强制锁定在 [0, 1] 区间内(包含端点)。
- 数学等价:完全等同于
Clamp(In, 0, 1)。
为什么连接在 Add(加法)节点之后?
- 防止数据溢出:两个信号相加(如光晕叠加、亮度叠加)极易产生 >1(如 1.5)或 <0 的数值。
- 保障渲染正确:非 HDR 下颜色上限为 1,超过 1 的数值会导致后续计算中的“爆白”或色彩失真。
- 处理逻辑:
- 输入 0.5 → 输出 0.5(不变)
- 输入 1.3 → 输出 1.0(削顶截断)
- 输入 -0.2 → 输出 0.0(底部截断)
🛠️ 常见应用与优势
- 保护后续计算:作为“保险丝”,确保光照、渐变、溶解(Dissolve)、透明度(Alpha)等数据严格合规。
- 性能优化:在 GPU 中是一条硬件级指令,执行速度远快于通用
Clamp节点。凡是需要限制 0~1 的场景,优先使用 Saturate。

Shader Graph 中的 Twirl(旋转扭曲 / 漩涡)节点
核心作用
对输入的坐标(通常是 UV)进行螺旋状扭曲变形,形成类似水流漩涡或黑洞的扭曲效果。
工作原理
- 基于距离的自适应旋转:
- 距中心点越近 → 旋转角度越大(绞得越紧)。
- 距中心点越远 → 旋转角度越小(逐渐归零,不扭曲)。
- 最终效果:将原本平直的纹理或渐变强行扭曲为螺旋图案。
核心参数
| 参数 | 含义与作用 |
|---|---|
| UV | 需要扭曲的坐标输入(纹理坐标或渐变信号) |
| Center(中心点) | 漩涡中心位置(默认通常为 0.5, 0.5) |
| Strength(强度) | 控制扭曲圈数,数值越大旋转圈数越多;正负值控制旋转方向(顺/逆时针) |
| Offset(偏移量) | 控制基础旋转角度。经典用法:连接 Time(时间)节点,使漩涡持续动态旋转,制造流动感(水流、能量场等)。 |

遮罩层
矩形遮罩(Rect Mask2D):遮罩层添加Rect Mask2D组件,需要遮罩的元素作为子元素


自定义形状遮罩(Mask组件):根据图片的透明度,透明的地方不显示


着色器中主材质与遮罩混合时“相乘(Multiply)”的必要性
核心结论
- 直接连接遮罩到 Alpha 输出 = 强制忽略主材质的透明度,仅在遮罩完全位于主材质不透明区域时才“看似正确”,遇到透明边缘必然产生**生硬切断(硬切)**的渲染错误。
- 正确做法:必须将主材质的 Alpha 与遮罩的 Alpha 通过 Multiply(相乘) 节点组合后,再输出给最终 Alpha。
场景分析:为什么不乘会出错?
| 场景 | 主材质 Alpha | 遮罩 Alpha | 直接连遮罩的结果 | 问题 |
|---|---|---|---|---|
| 遮罩落在不透明区域 | 1(不透明) | 1(白色) | 显示遮罩图案 | ✅ 视觉上勉强正常 |
| 遮罩落在透明边缘 | 0(透明) | 1(白色) | 渲染器强制听从遮罩(=1),将主材质底色/拉伸像素强行显示 | ❌ 边缘被生硬直线切断,出现穿帮 |
原理:当遮罩的 Alpha 为 1(白色)时,材质球会忽略主材质原有的透明属性,强制渲染该位置的像素,导致原本应该透明的区域露出主材质的边界缺陷。
为什么“相乘(Multiply)”不可省略?
- 数学含义:
输出 = 主Alpha × 遮罩Alpha - 逻辑含义(AND 门):只有当“主材质有内容(不透明)”且“遮罩允许显示”时,该像素才会被渲染。
- 优势:无论主材质如何缩放、位移或贴图边缘如何变化,都不会露馅,保证边缘始终平滑可控。
💡 着色器开发铁律:只要两个输入源都带有透明通道,在组合输出到 Alpha 之前,必须使用 Multiply 进行“交集”运算。

- UV通道
- 它们最常见的用途分类:
- 气流效果
- Unity 粒子系统:Start Color 与 Color over Lifetime 的关系
- 1. 概念
- 2. 核心数学关系
- 3. 常见误区(为什么粒子变黑/隐形?)
- 4. 最佳实践
- 5. 快速检查清单
- Unity 粒子系统 Scaling Mode(缩放模式)
- 三种模式
- 对比表
- Unity 粒子系统 — Emitter Velocity Mode: Transform
- 核心原理
- 计算公式
- 优点
- 缺点 / 问题
- 对比:Rigidbody 模式
- 常数节点
- 时间节点
- 颜色节点
- 布尔节点
- Wrap Mode
- 纹理包裹模式(Wrap Mode)详解
- SampleTexture2D
- UV节点
- uv遮罩
- 模型顶点信息
- UV 分量分离后显示为灰阶的原理
- Shader Graph 中放射状渐变(Radial Gradient)的生成原理
- Shader Graph 生成反向循环递减信号(-1 ~ 0 循环)
- Saturate(饱和/截断)节点
- Shader Graph 中的 Twirl(旋转扭曲 / 漩涡)节点
- 遮罩层
- 着色器中主材质与遮罩混合时“相乘(Multiply)”的必要性