UMG渲染时,若使用世界空间,则将使用Plane或Cylinder在场景中形成mesh的方式来处理。这样一来所有的Widget如同场景中的普通mesh,会出现在渲染管线中处理普通半透明物体的pass。此Pass位于所有后期pass之前。这样一来包括motion blur, tonemapping, TAA等均会影响Widget的显示

最为明显的症状是在相机移动时POI Widget上面的字出现严重模糊。Widget面板的颜色偏黄(Tonemapping)等

使用屏幕空间渲染则会被UE4以特殊的pass来handle(出现在后期之后,无法用renderDoc捕获),不会出现此问题

思路

让渲染3D Widget的pass出现在后期pass之后

做法

把Widget pass放到单独一个RT上

创建一个Render Target。注意将分辨率设置为与最终主相机输出的分辨率一致

使用sceneCapture2D component,与主相机同步。设置ShowOnlyComponet限制为只渲染场景中的3D Widget,并将结果输出到某个RT。注意bConsiderUnrenderedOpaquePixelAsFullyTranslucent需要为True

1571969089808.png

准备用于输出RT的pp

创建一个post processing类型的材质球。将blend location设置为After tonemapping。给此材质球设置一个Texture parameter

1571969746372.png

将给hack用的bp再增加一个单独的post processing component。用上一步创建的材质球初始化一份Dynamic Material Instance并喂给后期设置

1571969855165.png

1571969883633.png

让3D Widget材质使用User Interface 与 Trancelucent Blend的时候也能输出深度信息

这里可能涉及个trick

当Blend Mode为Trancelucent的时候,Widget Component开启Render CustomDepth Pass并不会生效(v4.23)。似乎需要在所用材质球中开启Allow Custom Depth Writes

但当材质球类型为User Interface的时候,其选项中是没有Allow Custom Depth Writes的。将材质球切换为surface后,该选项出现并勾选,再切换回User Interface,配合Widget Component上的选项,就能正常输出CustomDepth了

最后让Widget Component使用这个定制的材质球

更新sceneCapture2D的Transform和传递RT

1571971224113.png

后期材质球

思路是让Widget深度信息起效,处理遮挡

然后让传入的RT与常规pass做blend出最终结果

1571971031070.png

调整BP的更新时机

让Tick的更新时机处于物理更新后。否则RT会与主Pass结果差一帧,导致相机在快速移动时能看到明显的重影

1571971357444.png

最终结果

1571971537542.png