Unity3D Shader 透明、裁剪与混合
Unity3D Shader 透明、裁剪与混合
Unity3D Shader 透明、裁剪与混合
前言
在 Unity Shader 里,很多人第一次接触“透明”时都会有点困惑:
- 为什么我把 Alpha 改成 0.5,物体还是不透明?
- 为什么树叶这种效果不是半透明,而是直接“挖空”?
- 为什么有些特效越叠越亮?
这些问题,背后其实对应了三种完全不同的处理方式:
- 不透明(Opaque)
- 透明裁剪(Cutout / Alpha Test)
- 透明混合(Transparent / Blend)
如果再加上特效里常见的加法混合,这一块基本就是很多游戏 Shader 的核心基础。
结论:这三种不是一回事
1 不透明(Opaque)
特点:
- 不是透明
- 不需要混合
- 正常写深度
适合:
- 墙体
- 地面
- 角色本体
2 透明裁剪(Cutout)
特点:
- 不是“半透明”
- 要么显示,要么完全丢弃
- 常用于镂空效果
适合:
- 树叶
- 栅栏
- 草
- 纸片模型边缘裁切
3 透明混合(Transparent)
特点:
- 根据 Alpha 和背景颜色进行混合
- 可以出现真正的半透明
- 通常要关闭深度写入
适合:
- 玻璃
- 水晶
- UI 半透明
- 烟雾
不透明为什么最快、最稳定
最常见的不透明设置通常是:
1 | |
特点是:
- 正常参与深度写入
- 遮挡关系稳定
- 不需要做颜色混合
所以不透明物体通常:
- 性能更好
- 排序更简单
- 效果更稳定
这也是为什么能不用透明时,尽量不要用透明。
透明裁剪是什么
透明裁剪的核心思想不是“把像素变半透明”,而是:
满足条件就保留,不满足条件就直接丢掉。
在 Shader 中最常见的写法是:
1 | |
它的含义是:
- 如果
alpha - _Cutoff < 0 - 当前像素直接被丢弃,不参与后续输出
所以裁剪效果只有两种状态:
- 显示
- 不显示
并不存在 0.3、0.5 这种半透明过程。
一个最基础的裁剪 Shader
1 | |
代码关键点
1 | |
如果贴图透明通道低于 _Cutoff,这个像素就会被直接裁掉。
所以这种 Shader 特别适合:
- 叶片边缘
- 镂空网格
- 头发卡片
为什么 Cutout 常常比半透明更适合树叶
因为树叶通常不是玻璃那种“半透明”,
而是边缘需要被干净裁掉。
如果用真正半透明:
- 视觉会发灰
- 排序更麻烦
- 性能也可能更差
透明混合是什么
透明混合才是大家平常理解的“半透明”。
它的核心不是丢弃像素,而是:
把当前颜色和屏幕已有颜色按一定规则混合。
最常见的普通透明写法:
1 | |
这就是标准 Alpha 混合。
一个最基础的透明 Shader
1 | |
为什么这里一定要 ZWrite Off
因为半透明物体通常不能像不透明物体那样稳定写深度。
如果透明物体把深度写进去,很容易出现:
- 后面的透明物体被错误挡住
- 透明叠加顺序异常
所以标准半透明通常都会:
1 | |
但注意:
它虽然不写深度,通常还是会做深度测试。
为什么把 Alpha 设成 0.5 还不透明
这是最常见的新手问题之一。
比如你写:
1 | |
如果没有设置:
1 | |
它并不会自动半透明。
因为 Alpha 只是颜色的一个分量,
只有开启混合后,它才会真正参与屏幕颜色合成。
加法混合
除了普通透明外,特效里还非常常见一种方式:
1 | |
这叫:
加法混合(Additive Blend)
它的特点是:
- 没有正常意义上的“遮挡变暗”
- 多层叠加会越来越亮
- 很适合做发光特效
常用于:
- 火焰
- 魔法弹
- 能量轨迹
- 激光
如果你想更容易控制亮度,也经常用:
1 | |
三种方式的直观区别
| 方式 | 核心行为 | 是否半透明 | 常见用途 |
|---|---|---|---|
| Opaque | 直接绘制 | 否 | 墙体、角色、地面 |
| Cutout | 不满足条件就丢弃 | 否 | 树叶、草、栅栏 |
| Transparent | 与背景混合 | 是 | 玻璃、烟雾、水晶 |
| Additive | 与背景做加法 | 类似发光叠加 | 火焰、光效、能量 |
透明物体为什么总是容易出问题
因为透明物体通常会同时带来两个麻烦:
1 排序问题
透明通常要按从远到近的顺序渲染,
但真实模型不是一个简单平面,
所以复杂形体容易出现排序瑕疵。
2 不写深度
透明一般 ZWrite Off,
这虽然避免了一些错误遮挡,
但也让透明和透明之间更依赖绘制顺序。
所以:
透明永远比不透明更难处理。
什么时候优先选 Cutout,什么时候选 Transparent
可以用一个简单标准判断:
如果你的需求是“边缘挖空”
优先考虑:
1 | |
比如:
- 树叶
- 草
- 铁丝网
如果你的需求是“看起来透过去”
优先考虑:
1 | |
比如:
- 玻璃
- 烟
- 水晶
如果你的需求是“叠加发光”
优先考虑:
1 | |
比如:
- 技能特效
- 光束
- 魔法轨迹
常见坑
1 半透明没开 Blend
写了 Alpha,结果还是不透明。
2 裁剪物体用了 Transparent 队列
很多 Cutout 物体其实更适合放在:
1 | |
而不是 Transparent。
3 透明物体错误写深度
最常见结果就是透明相互遮挡不正常。
4 想要树叶效果却用了真正半透明
结果边缘发灰、效果发虚。
总结
裁剪是“不要这个像素”,混合是“这个像素和背景怎么合成”。
最核心的三套配置如下:
不透明
1 | |
裁剪
1 | |
半透明
1 | |
后面你做:
- 溶解
- 玻璃
- 树叶
- 粒子特效
这些效果时,几乎都要先想清楚:
到底要的是裁剪,还是混合?