[UE 5.8] Static mesh "fast build" path caches uninitialized bounds and vertices in the DDC (non-deterministic render data, sometimes "found NaN in Bounds")

Summary

A UStaticMesh created with BuildFromMeshDescriptions(…, Params.bFastBuild = true) keeps bDoFastBuild = true. When its render data is later re-cached (any DDC miss), FStaticMeshRenderData::Cache takes the fast-build branch, which never assigns FStaticMeshRenderData::Bounds (only MeshBuilderModule.BuildMesh and BuildFromMeshDescriptions do). TBoxSphereBounds() = default leaves it uninitialized, and the record written to the DDC carries whatever was in memory. UStaticMesh::BuildFromMeshDescription also sizes its build-vertex array with VertexInstances().GetArraySize() but fills only valid IDs, so a sparse mesh description uploads uninitialized vertices.

What Type of Bug are you experiencing?

Rendering (Graphics / Niagara)

Steps to Reproduce

  1. Create a UStaticMesh with BuildFromMeshDescriptions and Params.bFastBuild = true (a sparse mesh description, with deleted vertex instances, shows the vertex half as well).
  2. Save it, then build it twice into an empty DDC (clear the local DDC between the two builds).
  3. Compare the two cached render-data records.

Expected Result

The two records are byte-identical, and Bounds is always set from the mesh description.

Observed Result

The cached records differ byte for byte between the two builds. Occasionally loading one logs “FStaticMeshRenderData::Serialize found NaN in Bounds”, and the mesh then has NaN bounds (culled or never drawn). Seen in 5.8.3 on three meshes out of 74 built this way.

Affects Versions

5.8

Platform(s)

Linux
Windows

Additional Notes

Affects 5.8.3. Platforms: Windows and Linux (the code path is platform-independent).

Engine/Source/Runtime/Engine/Private/StaticMesh.cpp. Suggested fix: in the fast-build branch of FStaticMeshRenderData::Cache set Bounds = Owner->GetMeshDescription(0)->GetBounds() (as BuildFromMeshDescriptions does); in UStaticMesh::BuildFromMeshDescription zero-initialize the build vertices (SetNumZeroed) or compact the mesh description first; and add bDoFastBuild to the DDC key so stale records re-derive.

Video / callstack: none.