- 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]
The refactor to get rid of the FSceneTextures and FSceneTexturesConfig global singletons has also been preserved. The FViewFamilyInfo is used to hold those structures, so client facing API functions that lack a scene renderer reference can still pull the FSceneTextures[Config] from the view family pointer. All other scene renderer state has been moved from FViewFamilyInfo back into FSceneRenderer.
#jira none
#rnx
#rb ola.olsson krzysztof.narkowicz zach.bethel
#preflight 629f770e233ae0a8f8fb7f2e
[CL 20540730 by jason hoerner in ue5-main branch]
- since r.DistanceFields.TwoSidedSurfaceBiasExpand was lowered from 4 to 1 in CL 18850862.
#rb none
#jira UE-155648
#fyi daniel.wright
#preflight none
[CL 20517764 by tiago costa in ue5-main branch]
- Calculate bias applied to two sided meshes proportional to voxel size (r.DFShadow.TwoSidedMeshDistanceBiasScale can be used to adjust bias)
- Scale bias based on DF mip used.
#rb daniel.wright
#preflight 6297b96700746d43a2c89aaf
#ROBOMERGE-OWNER: tiago.costa
#ROBOMERGE-AUTHOR: tiago.costa
#ROBOMERGE-SOURCE: CL 20458023 via CL 20458331 via CL 20458771
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v952-20449836)
[CL 20461867 by tiago costa in ue5-main branch]
- ShadingFurnaceTest MainPS() OutColor was returning float3, need to return float4 when RGBA texture is bound on Metal otherwise we get validation errors.
- DistanceFieldShadowing; Fetch VS not PS.
- MetalRenderTargetTexture Cube resolve; cube copy to array seems to work as intended, remove asserts to allow this area to be more fully tested.
#jira UE-120222, UE-149106
#review-20181522 @will.damon, @Sebastien.Hillaire, @Charles.deRousiers
#rb will.damon, Sebastien.Hillaire,
#preflight https://horde.devtools.epicgames.com/job/627e6f609650a277337ac706
#rnx
[CL 20221500 by Richard Wallis in ue5-main branch]
- Replaced FRW{Structured, ByteAddress}Buffer with TRefCountPtr<FRDGPooledBuffer>
- Replaced ResizeResourceIfNeeded with Resize{Structured, ByteAddress}BufferIfNeeded.
- Replaced FScatterUploadBuffer with FRDGScatterUploadBuffer.
- Removed awkward copy of page table buffers now that scatters are on the RDG timeline.
- Reduced number of uniform buffers created by consolidating within FLumenSceneFrameTemporaries.
- Fixed up const-correctness of FLumenSceneFrameTemporaries to sanity check that resources were not being mutated later in the frame.
- Reduced explicit view creations somewhat.
- Distance fields needs an FDistanceFieldSceneFrameTemporaries to cache RDG resources, but I held off on this due to the number of files it would touch.
#rb krzyzstof.narkowicz, daniel.wright
#ROBOMERGE-AUTHOR: zach.bethel
#ROBOMERGE-SOURCE: CL 19921040 via CL 19922067 via CL 19922607
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v943-19904690)
[CL 19925590 by zach bethel in ue5-main branch]
- Shaders sampling mesh distance fields must define OFFSET_DATA_STRUCT according to r.DFShadowOffsetDataStructure.
- Also renamed cvar r.DFShadowOffsetDataStructure to r.DistanceFields.OffsetDataStructure since it applies to all techniques sampling mesh distance fields.
#preflight 626661771a71643e8b8b07df
#rb Krzysztof.Narkowicz
#jira none
[CL 19900311 by tiago costa in ue5-main branch]
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
* Added "BeginRenderingViewFamilies" render interface call that accepts multiple view families. Original "BeginRenderingViewFamily" falls through to this.
* FSceneRenderer modified to include an array of view families, plus an active view family and the Views for that family.
* Swap ViewFamily to ActiveViewFamily.
* Swap Views array from TArray<FViewInfo> to TArrayView<FViewInfo>, including where the Views array is passed to functions.
* FSceneRenderer iterates over the view families, rendering each one at a time, as separate render graph executions.
* Some frame setup and cleanup logic outside the render graph runs once.
* Moved stateful FSceneRenderer members to FViewFamilyInfo, to preserve existing one-at-a-time view family rendering behavior.
* Display Cluster (Virtual Production) uses new API.
Next step will push everything into one render graph, which requires handling per-family external resources and cleaning up singletons (like FSceneTextures and FSceneTexturesConfig). Once that's done, we'll be in a position to further interleave rendering, properly handle once per frame work, and solve artifacts in various systems.
#jira none
#rnx
#rb zach.bethel
#preflight 625df821b21bb49791d377c9
[CL 19813996 by jason hoerner in ue5-main branch]
- Point/Spot lights use the same FProjectedShadowInfo for all views. RayTracedShadowsTexture was only generated for the first view. Other views also sampled first view data.
- Store RayTracedShadowsTexture per view in DistanceFieldShadowViewGPUData to avoid using the cached result of a different view.
#rb Sebastien.Hillaire, Jian.Ru
#preflight 624ef87e3603402d600744e1
[CL 19669626 by tiago costa in ue5-main branch]
Storing water in gbuffer and runnign extra lighting pass would be too expenssiv. So instead, when in deferred, single layer water always output the main dir light luminance into a separate 111110 texture.
DF shadow is applied on that texture. DFShadow culling step is cached the first time for a given view in order to be able to reapply DFShadow later with a depth buffer containing water. This save 0.4ms on a base console.
DFShadow is naturaly skipped if the directional light does not have that feature enabled.
When DFShadow is executed, it is basically 0.24ms extra on a base console @ 1080p.
The separated light buffer is an extra 8MB allocated when in deferred.
This only works with deferred for now (forward does not run the reflection/composite pass).
Render target slot assignement is a bit fuzzy but this is a mostly static setup so should be fine. And could change with Strata down the line.
r.Water.SingleLayer.ShaderSupportDistanceFieldShadow is to enabled dfshadow on water for the shaders. Defaults to 1 and will only be enalbed when using deferred and when distance fields are enabled.
r.Water.SingleLayer.DistanceFieldShadow is a runtime toggle of the feature (if enabled the shaders still output to the separate light render target, but that is simply discarded).
Follow up: tile upsample, tile traceshadow, make it work with strata.
Tested shooter and console.
#rb Tiago.Costa, Kevin.Ortegren
#preflight https://horde.devtools.epicgames.com/job/62457ad79f404234145cd424
[CL 19613312 by Sebastien Hillaire in ue5-main branch]
- Translate culling planes from translated-shadow-space to translated-world-space.
#rb none
#preflight 62225fa5335298c31465dd24
#jira none
[CL 19271421 by tiago costa in ue5-main branch]
This avoids to define STRATA_ENABLED as 'env. define' for all global shaders needing a Strata specific path.
#rb none
#jira none
#fyi sebastien.hillaire
#preflight 62151b25797dbbeb472ae2eb
[CL 19074999 by Charles deRousiers in ue5-main branch]
#jira UE-122078
#rb Andrew.Davidson, Colin.McGinley
#preflight standard build
#ROBOMERGE-AUTHOR: fred.kimberley
#ROBOMERGE-SOURCE: CL 18817999 in //UE5/Release-5.0/... via CL 18818012 via CL 18822871
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042)
[CL 18824721 by fred kimberley in ue5-main branch]
Submitted on behalf of fred.kimberley
#rb andy.davidson
#preflight 61f8700e41414fb013dd4002
#ROBOMERGE-AUTHOR: andrew.davidson
#ROBOMERGE-SOURCE: CL 18801433 in //UE5/Release-5.0/... via CL 18802090 via CL 18821511
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v908-18788545)
[CL 18821594 by andrew davidson in ue5-main branch]
* Removed culled DF object copies during culling. Instead now only indices to culled objects are stored
* Refactored DF heightfield object loads into FHeightfieldObjectBounds and FHeightfieldObjectData
This is a step towards optimizing DF culling and reusing this code for Lumen Landscape culling
Perf Reverb on 2080:
* CullMeshSDFObjectsToFrustum 0.04ms->0.03ms (removed DF object copies)
* Other passes didn't change
#preflight 61f5a7b7694910780bd91918
#rb Tiago.Costa
#ROBOMERGE-AUTHOR: krzysztof.narkowicz
#ROBOMERGE-SOURCE: CL 18789232 in //UE5/Release-5.0/... via CL 18789258 via CL 18789368
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v908-18788545)
[CL 18789821 by krzysztof narkowicz in ue5-main branch]
- Add r.Shadow.DetectVertexShaderLayerAtRuntime to make it possible to force (for DX11/12/SM5/Vulkan) compilation of vslayer despite RHISupportsVertexShaderLayer being false.
- Set r.Shadow.DetectVertexShaderLayerAtRuntime in WindowsEngine.ini,WinGDKEngine.ini & LinuxEngine.ini.
- Add DoesRuntimeSupportOnePassPointLightShadows to determine support at runtime.
- Fix bug excluding Nanite meshes from DF shadows for local lights if VSM is enabled (now only affects directional lights).
- Add OnGetOnScreenMessages to enable modular generation of on-screen messages in the scene renderer (aimed at transient rendering processes).
#rb arciel.rekman,andrew.lauritzen
#jira UE-138933
#preflight 61f3c967da54035207f6e560
#ROBOMERGE-AUTHOR: ola.olsson
#ROBOMERGE-SOURCE: CL 18769670 in //UE5/Release-5.0/... via CL 18769671 via CL 18769765
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v903-18687472)
[CL 18769767 by ola olsson in ue5-main branch]