Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/DistanceFieldObjectManagement.cpp
tiago costa 1e44dca468 Improved HeightField object management.
- this fixes a number of crashes and issue with heightfields missing from global distance field when heightfield shadows are enabled.

- Context:
  - Heightfields are used by two techniques using different approaches:
    - Global Distance Field (r.AOGlobalDistanceField.Heightfield) - heightfields are composed one by one into Global SDF so there's no need for bindless resources or atlas.
    - Height Field Shadows (r.HeightFieldShadowing) - since all heightfields data must be accessible in the same dispatch, heightfields descriptiors are stored in structured buffers (HeightFieldObjectBuffers) and textures are copied to an atlas (GHeightFieldTextureAtlas/GHFVisibilityTextureAtlas).
  - FDistanceFieldSceneData::HeightfieldPrimitives is an array of relevant heighfield primitives.
  - For each primitive, DistanceFieldInstanceIndices contains the index of the corresponding entry in HeightfieldPrimitives array.
    - The same DistanceFieldInstanceIndices is also used to manage distance fields (there's an assumption that a primitive can have a distance field or a height field, but not both).
  - The codepath to manage the HeightFieldObjectBuffers and GHeightFieldTextureAtlas/GHFVisibilityTextureAtlas is only enabled when ShouldPrepareHeightFieldScene() returns true.
  - There's limited space in the atlas so it's not guaranteed that every loaded heightfield fits in the atlas.

- Issues with existing approach:
  - When the codepath to manage HeightFieldObjectBuffers/Atlases is enabled, only the heighfields that fit in the atlas are added to FDistanceFieldSceneData::HeightfieldPrimitives.
    - this means that in some cases not every loaded heighfield will be composed into the global distance field (since only primitives in HeightfieldPrimitives are included).
    - there are also a few bugs with the code that can result in crashes.
  - Heighfields that fail the inital allocation are not added to HeightfieldPrimitives even after space becomes available in the atlas.
    - the atlas itself correctly retries to fit failed allocations when space becomes available, however the higher level managment code doesn't handle this.

- Changes:
  - all heightfield primitives are added to FDistanceFieldSceneData::HeightfieldPrimitives regardless of whether they fit in atlas or not.
    - this way all heightfields will be included in global distance field
  - added a new field, bInAtlas, to entries in HeightFieldObjectBuffers.
  - during Height Field Shadows culling pass, heightfields not present in atlas are skipped.
  - significantly refactored relevant codepaths to simplify logic.

#rb Krzysztof.Narkowicz, Jian.Ru
#preflight 6372c0ef953c19d4353ad211

[CL 23131399 by tiago costa in ue5-main branch]
2022-11-14 20:42:26 -05:00

44 KiB