分析基于 UE5.3,DefferredDecal 的默认渲染流程

贴花具体使用请参考 [虚幻引擎中的贴花材质]

UE5和UE4区别


UE5默认启用DBuffer贴花,贴花混合模式不可选,按照材质的设置自动选择贴花混合模式

控制台变量 r.DBuffer 为只读字段

以下是此变量的描述

1
2
3
4
5
6
7
8
9
static TAutoConsoleVariable<int32> CVarDBuffer(
TEXT("r.DBuffer"),
1,
TEXT("Enables DBuffer decal material blend modes.\n"
"DBuffer decals are rendered before the base pass, allowing them to affect static lighting and skylighting correctly. \n"
"When enabled, a full prepass will be forced which adds CPU / GPU cost. Several texture lookups will be done in the base pass to fetch the decal properties, which adds pixel work.\n"
" 0: off\n"
" 1: on (default)"),
ECVF_RenderThreadSafe | ECVF_ReadOnly);

贴花基本效果


如下图所示,一个 Decal Actor 的例子

贴花材质设定:

  • 延迟贴花

  • 半透明

  • 自发光颜色 绿色 (0.0f, 1.0f, 0.0f)

  • 基础颜色 红色 (1.0f, 0.0f, 0.0f)

  • 金属度、高光、粗糙度都为0.8

最终混合后呈现黄色

圆锥体关闭了贴花接收

图片

BeforeBasePass


这一阶段,主要实现两个过程

  • 贴花的”投影“

  • 存储贴花材质到DBuffer

“投影”

贴花表现出来的行为是正交投影

UE引擎采用的是由 Stencil Test 模板测试来模拟这种类似正交投影的效果,

这也是为什么在渲染延迟贴花一个步骤的时候往往需要2个 DrawIndexedInstanced 和贴花的控件为什么是一个box(box双面测试)

图片
更多细节可参考 UE4贴花及DBuffer总结 - 知乎 (zhihu.com)

DBuffer

通过”投影“,现在就知道了应该往哪里写入材质数据了

图片
DBufferA :BaseColor

DBufferB :Normal

DBufferC :金属度、高光、粗糙度

BasePass


  • DBuffer写入GBuffer,为延迟渲染做准备

  • 判断物体是否开启贴花接收

输入输出如下

图片
立方体和球体的Stencil为 0x84 ,圆锥体的Stencil为 0x04

从GBuffer的输出可以也可以看出,关闭贴花接收的物体不受DBuffer的影响,而开启的物体其材质被贴花材质覆盖

PreLighting


  • 贴花自发光的处理

第一个Draw,模板测试排除不接收贴花的物体,如下图

图片
圆锥的 Stencil 是 0x05 , 其他物体是0x85


第二个Draw,写入自发光信息,如下

图片

Lighting


此时,已经准备好了渲染贴花的所有数据,后续就可以利用GBuffer执行任意的光照效果

这里贴一个DirectLight Pass后的效果

图片

一些问题可能的原因


延迟贴花效果不符合预期的主要原因可能如下

  • Base Color 受光的影响,如上面的例子,阴影处不受光相当于 Base Color 是(0,0,0)只显示了 Emissive Color

  • 材质的不透明度同时影响 Emissive Color 和 Base Color

  • 蓝图使用 ApplyDBuffer 时,即使此时材质的基础颜色没有连接,也会存在Base Color黑色,Stencil Test 通过

参考

[1] 虚幻引擎中的贴花材质 | 虚幻引擎 5.4 文档 | Epic Developer Community

[2] UE4贴花及DBuffer总结 - 知乎 (zhihu.com)