UE4 3D Widget受后期影响问题的处理
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
准备用于输出RT的pp
创建一个post processing类型的材质球。将blend location设置为After tonemapping。给此材质球设置一个Texture parameter
将给hack用的bp再增加一个单独的post processing component。用上一步创建的材质球初始化一份Dynamic Material Instance并喂给后期设置
让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
后期材质球
思路是让Widget深度信息起效,处理遮挡
然后让传入的RT与常规pass做blend出最终结果
调整BP的更新时机
让Tick的更新时机处于物理更新后。否则RT会与主Pass结果差一帧,导致相机在快速移动时能看到明显的重影