Base-透明渲染
实时透明渲染需要决定覆盖、光照、排序和合成。Alpha 混合是常见表面合成方法,但透明材质还可能涉及折射、吸收与散射,不能把透明统一解释为一种 Blend 状态。
本文沿 2019 年 7 月 31 日的透明笔记整理,并合入 2023 年 2 月 23 日的 Weighted Blended OIT 记录。代码强调合成关系,不是可直接替换任何管线的完整 Renderer Feature。
1. Alpha Blend 与预乘 Alpha
对于未预乘的源颜色 Cs 和不透明背景 Cd,常见关系是 Cout=Cs*As+Cd*(1-As),对应:
1 | |
若源 RGB 已经乘过 Alpha,则使用 Blend One OneMinusSrcAlpha。源表示与混合状态必须一致,否则会出现边缘发暗或重复乘 Alpha。
Alpha 输出本身还有独立的合成公式,离屏目标需要继续参与合成时,应分别配置 RGB 与 Alpha 因子,而不是只看当前显示颜色。
加法 Blend One One 适合某些发光近似,但没有普通遮挡式透明的覆盖意义。它不能代表所有特效的“标准透明”。
2. 深度与排序
透明通常保留深度测试以避开不透明遮挡,并关闭深度写入,按远到近绘制。若提前把半透明表面写进深度,会阻止其后本来应该可见的层参与合成。
对象中心排序无法正确解决交叉网格、自交和环状遮挡。双 Pass 先背面后正面只对部分形状有帮助,不是通用排序算法。
Unity 中 Transparent 队列通常从 3000 开始,但具体天空盒、复制颜色和后处理顺序由管线决定。透明不一定必须采用唯一的前向方案,只是很多延迟管线将它单独放到前向路径处理。

原笔记配图:半透明盒子的前后表面需要正确的排序和深度写入策略。
3. Alpha Clip 与覆盖率
Alpha Clip 根据阈值丢弃片元,其余按不透明覆盖处理,通常可以写深度。边缘不连续会走样,需要 MSAA 的 Alpha-to-Coverage、覆盖率保持、时域方法或更多几何等策略。
Dither 加 TAA 可以模拟平均覆盖,却会带来噪声、拖影和对历史积累的依赖。它不能完全替代折射玻璃等真正多层透明。
4. OIT 是一类方法
Order-Independent Transparency(顺序无关透明,OIT)包含不同精度和成本的方案。Depth Peeling、多片元存储与加权混合并不等价。
Weighted Blended OIT 用可交换的累积近似多层合成,避免对象排序,但一般不能准确恢复所有颜色层的前后关系。高不透明度、强烈颜色差异或复杂折射仍可能暴露近似。
5. 累积与 Revealage
清空 Accum 为 0,Revealage 为 1。对每个片元,以非负权重 w 累积:
1 | |
Accum 使用加法混合;Revealage 存的是透过比例,不是最上层 Alpha。权重需要结合线性深度/设备深度定义与目标范围设计,原记录里的 pow(z,-2.5) 在 z 为零、反向深度或不同近远范围时并不安全。
如果用单通道 R 目标且 Shader 输出 Alpha 到红色,可使用对应的源颜色因子乘法表达透过率;若输出 Alpha 在 A 通道,又是另一种配置。附件通道、片元输出与 Blend 因子必须成套,不能复制两段独立代码就认为一致。

原笔记配图:旧笔记中 z 的负幂权重曲线。它只说明深度权重变化,实际实现要限定有效深度并避免零点奇异。
6. 最终合成与稳定性
1 | |
若没有透明片元,Accum 为 0,Revealage 为 1,结果就是背景。实现还要考虑累积格式溢出、权重范围、MSAA、独立附件混合支持与线性颜色计算。
额外 RT 的写读和合成 Pass 也有成本。OIT 可以解决某类排序问题,不代表一定比简单透明更快。应分别测试普通粒子、密集叠层和高 Alpha 极端情况。
总结
先确定颜色是否预乘、深度是否写入、层间顺序怎样处理,再选择合成算法。Weighted Blended OIT 用可交换累积换取排序便利,同时保留近似与带宽代价,不能当作完全无误差的透明替代品。