Depth of Field blurs foreground hair as if in the background.
From a quick look through graphics captures it appears that this was introduced with the changes to support Single Layer Water (SLW) for Hair Grooms in 5.8. There is a comment in “AddHairVisibilityComposeSamplePass()” immediately prior to disabling depth write to the effect of “don’t write depth on the second pass because SLW has already written the depth”. SLW *does* appear to output the correct depth, but at a later point in DeferredShadingRenderer.cpp we override SceneTexture Depth to point at the SLW DepthPrepass Texture instead of the Main Scene Depth. We do this so water is added to depth scene, but it means our hair depth is no longer in the “main” depth. When DoF uses this new texture, it doesn’t know about the hair.
I’ve found a few work arounds, none of which is an ideal fix:
- r.HairStrands.ComposeAfterTranslucency=2
- This pushes the composite of hair later in the frame, which resolves the issue since it is now after water entirely, and the single path writes depth.
- This approach has risks of knock ons for compositing hair with other translucents
- in AddHairVisibilityComposeSamplePass, if you re-enable the depth write from the main hair pass things work properly as well
- this writes hair depth to the new SLWDepthPrepass texture
- this is a redundant depth write, which is not ideal for performance
- In DeferredShadingRenderer.cpp if we remove the logic updating SceneTextures.Depth to point at SLWDepthPrepass then DoF works correctly
- This means SLW is no longer in the depth buffer which seems likely to cause knock-ons
- We can invert the depth writes, so we dont write hair depth in the SLW pass, but we do in the main Groom pass
- This seems to work, but means hair depth is not being written in the SLW depth, which may have impacts on SLW interaction for grooms
- We can pass the DepthPrepass texture into the RenderHairCompositionForSLW which does the initial depth write.
- This ensures proper depth is used for DoF
- Hair gets desaturated for some reason
- means that hair is not output to FSceneWithoutWaterTextures which is used by a great number of passes so very likely knockons
From what I can tell there is no nice solution here. The most correct solution seems to be to just write depth a second time.
[Attachment Removed]