半透明与排序
自动关联目录:半透明与排序
覆盖说明:官方文档里半透明的内容分散在 TSR、材质、后处理等多篇中,没有单一对应页;本篇按引擎实际模块组织,以源码与已核实的官方片段为依据。其中与 TSR 相关的部分见 TSR 时域超分。
1. 定位
半透明是渲染里唯一"必须按正确顺序画才对"的一类材质——不透明物体靠深度缓冲自然解决遮挡,半透明不行,因为它默认不写深度。
一句话定位:半透明的三大问题分别是排序、overdraw、以及与时域/后处理的交互。绝大多数"半透明看起来不对"都落在第一类。
2. 结构:半透明在管线里的位置
BasePass(不透明,写深度) ← 深度缓冲在这里建立
│
├─ Before DOF 半透明
├─ 景深
├─ After DOF 半透明 ← 材质默认在这里
├─ 【TSR】 ← 见 TSR 篇
└─ After Motion Blur 半透明材质里通过 Translucency → Translucency Pass 选择:
| Pass | 位置 | 说明 |
|---|---|---|
| Before DOF | 景深之前 | 会被景深模糊 |
| After DOF(默认) | 景深之后 | TSR 对它单独加了一层模糊卷积(因为它不画速度) |
| After Motion Blur | 运动模糊之后 | 完全不被时域处理影响 |
官方明确建议:只在确定知道自己要什么时才改这个设置,默认 After DOF 就好。
3. 排序机制
排序的粒度是"逐物体",不是"逐三角形"
排序单位 = Primitive Component(按到相机的距离)
↓
同一个物体内部的三角形顺序 = 由网格索引顺序决定,不参与排序这直接解释了两类经典现象:
| 现象 | 原因 |
|---|---|
| 两个半透明物体交错时前后翻转 | 逐物体排序,物体中心距离随相机移动变化 → 排序结果跳变 |
| 单个复杂物体自身穿插错乱 | 排序根本不管它内部的三角形 |
可调项
| 手段 | 位置 | 适用 |
|---|---|---|
| Translucency Sort Priority | 每个 primitive 的 Details | 手动指定优先级,解决"这两个必须谁在前" |
| Translucent Sort Policy | 项目设置 | 按距离排序 / 沿某轴排序(r.TranslucentSortPolicy、r.TranslucentSortAxis) |
| Order Independent Transparency (OIT) | 项目设置 Rendering > Translucency | 三角形级(Sort Triangles)或像素级(Sort Pixels)排序,成本依次升高 |
| Custom Depth | 材质里采样 SceneDepth/CustomDepth 手动丢弃 | 解决自穿插 |
| 改成 Masked | 材质 Blend Mode | 用抖动(DitherTemporalAA)模拟半透,能写深度、无排序问题 |
OIT 的具体选项名与开销随版本有变化,以目标版本的 Project Settings 实际条目为准。
Separate Translucency
r.SeparateTranslucency(TSR 开启时由 r.TSR.ForceSeparateTranslucency 强制):让半透明渲染到单独的 RT,再合成回场景色。好处是半透明不受景深与部分后处理影响,也便于 TSR 单独处理。
4. 参数与控制台变量
| CVar / 设置 | 作用 |
|---|---|
r.TranslucentSortPolicy | 排序策略(按距离 / 沿轴) |
r.TranslucentSortAxis | 沿轴排序时的轴 |
r.SeparateTranslucency | 半透明独立 RT |
r.Translucency.AutoBeforeDOF | 自动把焦点距离之后的半透明画到 Before DOF(0=1x 焦距,0.5=2x,1=100x),默认开启 |
r.Translucency.Velocity | 设为 0 可快速验证"鬼影是不是半透明覆写速度造成的"(排查用) |
Opacity Mask Clip Value | 材质 Material > Advanced,默认 0.333。半透明写深度/速度时用它比较不透明度 |
Output Depth and Velocity | 材质 Translucency 分类下,勾选后让半透明写运动向量 |
r.TranslucencyLighting.* | 半透明光照相关 |
5. 代价与权衡
| 设计 | 收益 | 代价 | 什么时候不该用 |
|---|---|---|---|
| 不写深度 | 正确的混合 | 无法被深度剔除、overdraw 直接变成填充率消耗 | 大面积半透明(烟雾、爆炸)是填充率杀手 |
| 逐物体排序 | 便宜 | 复杂物体自穿插必错 | 自穿插严重的物体要换方案 |
| OIT(三角形级) | 解决大部分自穿插 | 额外内存与排序成本 | 简单物体不必开 |
| OIT(像素级) | 质量最高 | 最贵 | 只在关键物体上用 |
| 改 Masked + 抖动 | 能写深度、能被时域抗锯齿平滑、无排序问题 | 视觉上是网点,依赖 TAA/TSR 收敛;静止时可能看到抖动图案 | 需要柔和连续的透明度时不可用 |
| Separate Translucency | 不受 DOF 影响、便于时域处理 | 额外一张 RT 的带宽 | 移动端要权衡 |
6. 踩坑与排查
| 坑 | 现象 | 怎么验证 |
|---|---|---|
| 自穿插错乱 | 物体内部面片前后乱 | 排序不管三角形 → 用 OIT 或改 Masked |
| 两个物体前后跳变 | 相机移动时翻转 | 用 Translucency Sort Priority 固定 |
| 半透明很卡 | 帧率掉 | 看 Quad Overdraw 视图;大面积半透明的 overdraw 直接吃填充率 |
| 半透明边缘糊/鬼影 | TSR 相关 | 见 TSR 篇:勾 Output Depth and Velocity、调 Opacity Mask Clip Value |
| 半透明被景深糊了 | 位置不对 | 检查 Translucency Pass 是不是 Before DOF |
| 改了 Translucency Pass 后变慢 | 有未预见的性能代价 | 官方明确警告过这点,改回 After DOF 对比 |
| VFX 写速度后穿帮 | 背后的不透明几何重投影出错 | 提高 Opacity Mask Clip Value,只为最不透明处写速度 |
| 用了 Separate Translucency 但没生效 | 被 TSR 强制覆写 | r.TSR.ForceSeparateTranslucency 默认开启 |
7. 排查顺序
1. 是排序问题还是性能问题?
├─ 顺序错 → 逐物体排序是根因 → Sort Priority / OIT / 改 Masked
└─ 卡 → Quad Overdraw 视图看填充率
2. 与相机移动相关? → 排序跳变
3. 涉及 TSR? → 走 TSR 篇的半透明一节
4. 涉及 Lumen 反射? → High Quality Translucency Reflections(见 Lumen 篇)参考
许可协议:CC BY
作者:Davids
本文链接:https://hustjjd.github.io/09ff7b61.html
更新于:2026年10月10日