UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
NaniteResourcesHelper.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "NaniteSceneProxy.h"
6#include "MaterialShared.h"
9#include "MaterialDomain.h"
10#include "MaterialCachedData.h"
11#include "MaterialShaderType.h"
12#include "MeshUVChannelInfo.h"
13#include "Engine/StaticMesh.h"
14#include "UObject/Package.h"
15#include "EngineLogs.h"
16
20
21namespace Nanite
22{
23 struct FMaterialAudit;
24
27 {
28 public:
29 template<class T>
30 static bool HasValidNaniteData(const T& Component);
31
32 template<class T>
34
35 template<class T>
37
38 template<class T>
40 };
41
42 namespace Private
43 {
50
51 template<class T>
52 FString GetMaterialMeshName(const T& Object)
53 {
54 return Object.GetStaticMesh()->GetName();
55 }
56
57 template<class T>
59 {
60 return false;
61 }
62
63 template<class T>
65 {
67
68 if (UStaticMesh* StaticMesh = Object.GetStaticMesh())
69 {
70 TArray<FStaticMaterial>& StaticMaterials = StaticMesh->GetStaticMaterials();
71
72 uint32 Index = 0;
74 {
75 Infos.Add({ Object.GetNaniteAuditMaterial(Index), Material.MaterialSlotName, Material.UVChannelData });
76 Index++;
77 }
78 }
79
80 return Infos;
81 }
82
83 template<>
85
86 template<>
88
89 template<>
91
92 template<>
94
95 template<>
97
98 template<>
100
101 template<>
103
104 template<>
106
107 template<>
109 }
110
111 template<class T>
113 {
114 // Whether or not to allow Nanite for this component
115#if WITH_EDITORONLY_DATA
116 const bool bForceFallback = Component.IsDisplayNaniteFallbackMesh();
117#else
118 const bool bForceFallback = false;
119#endif
120
121 if (bForceFallback || Component.IsDisallowNanite() || Component.IsForceDisableNanite())
122 {
123 // Regardless of the static mesh asset supporting Nanite, this component does not want Nanite to be used
124 return false;
125 }
126
127 const EShaderPlatform ShaderPlatform = Component.GetScene() ? Component.GetScene()->GetShaderPlatform() : GMaxRHIShaderPlatform;
128
129 if (!UseNanite(ShaderPlatform) || !Component.HasValidNaniteData())
130 {
131 return false;
132 }
133
134 {
135 FMaterialAudit NaniteMaterials{};
136 AuditMaterials(&Component, NaniteMaterials, OutNaniteMaterials != nullptr);
137
138 const bool bIsMaskingAllowed = Nanite::IsMaskingAllowed(Component.GetWorld(), Component.IsForceNaniteForMasked());
139 if (!NaniteMaterials.IsValid(bIsMaskingAllowed))
140 {
141 return false;
142 }
143
145 {
146 *OutNaniteMaterials = MoveTemp(NaniteMaterials);
147 }
148 }
149
150 return true;
151 }
152
153 template<class T>
155 {
156 const FResources* NaniteResources = Component.GetNaniteResources();
157 return NaniteResources != nullptr ? NaniteResources->PageStreamingStates.Num() > 0 : false;
158 }
159
160 template<class T>
162 {
163 // Check for valid data on this SMC and support for Nanite material overrides
165 }
166
167 template<class T>
169 {
170 static const auto NaniteForceEnableMeshesCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Nanite.ForceEnableMeshes"));
172
173 static const auto CVarLumenDetectCardSharingCompatibility = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.LumenScene.SurfaceCache.DetectCardSharingCompatibility"));
175
176 Audit.bHasAnyError = false;
177 Audit.Entries.Reset();
178
179 if (Component != nullptr)
180 {
182
183 Audit.bCompatibleWithLumenCardSharing = Slots.Num() > 0;
184
185 uint32 Index = 0;
186 for (const Private::FAuditMaterialSlotInfo& SlotInfo : Slots)
187 {
188 FMaterialAuditEntry& Entry = Audit.Entries.AddDefaulted_GetRef();
189 Entry.MaterialSlotName = SlotInfo.SlotName;
190 Entry.MaterialIndex = Index;
191 Index++;
192 Entry.Material = SlotInfo.Material;
193 Entry.bHasNullMaterial = Entry.Material == nullptr;
195 SlotInfo.UVChannelData.LocalUVDensities[0],
196 SlotInfo.UVChannelData.LocalUVDensities[1],
197 SlotInfo.UVChannelData.LocalUVDensities[2],
198 SlotInfo.UVChannelData.LocalUVDensities[3]
199 );
200
201 if (Entry.bHasNullMaterial)
202 {
203 // Never allow null materials, assign default instead
205 }
206
208 check(Material != nullptr); // Should always be valid here
209
210 const EBlendMode BlendMode = Entry.Material->GetBlendMode();
211
212 bool bUsingCookedEditorData = false;
213#if WITH_EDITORONLY_DATA
214 bUsingCookedEditorData = Material->GetOutermost()->bIsCookedForEditor;
215#endif
216 bool bUsageSetSuccessfully = false;
217
218 const FMaterialCachedExpressionData& CachedMaterialData = Material->GetCachedExpressionData();
219 Entry.bHasVertexInterpolator = CachedMaterialData.bHasVertexInterpolator;
220 Entry.bHasPerInstanceRandomID = CachedMaterialData.bHasPerInstanceRandom;
221 Entry.bHasPerInstanceCustomData = CachedMaterialData.bHasPerInstanceCustomData;
222 Entry.bHasVertexUVs = CachedMaterialData.bHasCustomizedUVs;
223 Entry.bHasPixelDepthOffset = Material->HasPixelDepthOffsetConnected();
224 Entry.bHasWorldPositionOffset = Material->HasVertexPositionOffsetConnected();
225 Entry.bHasTessellationEnabled = Material->IsTessellationEnabled();
228 Entry.bHasInvalidUsage = (bUsingCookedEditorData || !bSetMaterialUsage) ? Material->NeedsSetMaterialUsage_Concurrent(bUsageSetSuccessfully, MATUSAGE_Nanite) : !Material->CheckMaterialUsage_Concurrent(MATUSAGE_Nanite);
229
231 {
232 Entry.bHasInvalidUsage |= (bUsingCookedEditorData || !bSetMaterialUsage) ? Material->NeedsSetMaterialUsage_Concurrent(bUsageSetSuccessfully, MATUSAGE_SkeletalMesh) : !Material->CheckMaterialUsage_Concurrent(MATUSAGE_SkeletalMesh);
233 }
234
235 if (BlendMode == BLEND_Masked)
236 {
237 Audit.bHasMasked = true;
238 }
239
240 if (Material->bIsSky)
241 {
242 // Sky material is a special case we want to skip
243 Audit.bHasSky = true;
244 }
245
246 auto IsCompatibleWithLumenCardSharing = [&]()
247 {
249 {
250 // Material is explicitly marked as compatible
251 return true;
252 }
253
255 && !CachedMaterialData.bHasPerInstanceRandom
256 && !CachedMaterialData.bHasPerInstanceCustomData
257 && !CachedMaterialData.bHasWorldPosition;
258 };
259
260 if (!IsCompatibleWithLumenCardSharing())
261 {
262 Audit.bCompatibleWithLumenCardSharing = false;
263 }
264
265 Entry.bHasAnyError =
268 Entry.bHasInvalidUsage;
269
270 if (!bUsingCookedEditorData && Entry.bHasAnyError && !Audit.bHasAnyError)
271 {
272 // Only populate on error for performance/memory reasons
275 }
276
277 Audit.bHasAnyError |= Entry.bHasAnyError;
278
279#if !(UE_BUILD_SHIPPING) || WITH_EDITOR
281 {
282 if (Entry.bHasUnsupportedBlendMode)
283 {
284 const FString BlendModeName = GetBlendModeString(Entry.Material->GetBlendMode());
286 {
287 UE_LOG
288 (
290 TEXT("Invalid material [%s] used on Nanite skeletal mesh [%s]. Only opaque or masked blend modes are currently supported, [%s] blend mode was specified."),
291 *Entry.Material->GetName(),
292 *Audit.AssetName,
294 );
295 }
296 else
297 {
298 UE_LOG
299 (
301 TEXT("Invalid material [%s] used on Nanite static mesh [%s]. Only opaque or masked blend modes are currently supported, [%s] blend mode was specified. (NOTE: \"Disallow Nanite\" on static mesh components can be used to suppress this warning and forcibly render the object as non-Nanite.)"),
302 *Entry.Material->GetName(),
303 *Audit.AssetName,
305 );
306 }
307 }
309 {
312 {
313 UE_LOG
314 (
316 TEXT("Invalid material [%s] used on Nanite skeletal mesh [%s]. The SingleLayerWater shading model is currently not supported, [%s] shading model was specified."),
317 *Entry.Material->GetName(),
318 *Audit.AssetName,
320 );
321 }
322 else
323 {
324 UE_LOG
325 (
327 TEXT("Invalid material [%s] used on Nanite static mesh [%s]. The SingleLayerWater shading model is currently not supported, [%s] shading model was specified. (NOTE: \"Disallow Nanite\" on static mesh components can be used to suppress this warning and forcibly render the object as non-Nanite.)"),
328 *Entry.Material->GetName(),
329 *Audit.AssetName,
331 );
332 }
333 }
334 }
335#endif
336 }
337 }
338
339 return Audit;
340 }
341}
#define check(expr)
Definition AssertionMacros.h:314
#define TEXT(x)
Definition Platform.h:1272
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
EBlendMode
Definition EngineTypes.h:245
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
@ MATUSAGE_SkeletalMesh
Definition MaterialInterface.h:74
@ MATUSAGE_Nanite
Definition MaterialInterface.h:92
FString GetShadingModelFieldString(FMaterialShadingModelField ShadingModels, const FShadingModelToStringDelegate &Delegate, const FString &Delimiter)
Definition MaterialShader.cpp:177
FString GetBlendModeString(EBlendMode BlendMode)
Definition MaterialShader.cpp:205
UE::Math::TVector4< float > FVector4f
Definition MathFwd.h:75
EShaderPlatform
Definition RHIShaderPlatform.h:11
EShaderPlatform GMaxRHIShaderPlatform
Definition RHI.cpp:1335
bool UseNanite(EShaderPlatform ShaderPlatform, bool bCheckForAtomicSupport, bool bCheckForProjectSetting)
Definition RenderUtils.cpp:1414
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition NameTypes.h:617
Definition NaniteResourcesHelper.h:27
static bool UseNaniteOverrideMaterials(const T &Component, bool bDoingMaterialAudit)
Definition NaniteResourcesHelper.h:161
static FMaterialAudit & AuditMaterials(const T *Component, FMaterialAudit &Audit, bool bSetMaterialUsage)
Definition NaniteResourcesHelper.h:168
static bool ShouldCreateNaniteProxy(const T &Component, FMaterialAudit *OutNaniteMaterials)
Definition NaniteResourcesHelper.h:112
static bool HasValidNaniteData(const T &Component)
Definition NaniteResourcesHelper.h:154
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
T GetValueOnAnyThread(bool bForceGameThread=false) const
Definition IConsoleManager.h:1753
Definition MaterialInterface.h:296
virtual ENGINE_API EBlendMode GetBlendMode() const
Definition MaterialInterface.cpp:1480
virtual ENGINE_API FMaterialShadingModelField GetShadingModels() const
Definition MaterialInterface.cpp:1600
virtual ENGINE_API bool IsCompatibleWithLumenCardSharing() const
Definition MaterialInterface.cpp:1670
virtual const class UMaterial * GetMaterial_Concurrent(TMicRecursionGuard RecursionGuard=TMicRecursionGuard()) const PURE_VIRTUAL(UMaterialInterface
Definition MaterialInterface.h:492
Definition Material.h:432
static ENGINE_API UMaterial * GetDefaultMaterial(EMaterialDomain Domain)
Definition Material.cpp:1071
UE_FORCEINLINE_HINT FString GetName() const
Definition UObjectBaseUtility.h:439
Definition SkinnedMeshComponent.h:258
Definition StaticMesh.h:593
FString GetMaterialMeshName< FSkinnedMeshSceneProxyDesc >(const FSkinnedMeshSceneProxyDesc &Object)
Definition NaniteResourcesHelper.cpp:20
TArray< FAuditMaterialSlotInfo, TInlineAllocator< 32 > > GetMaterialSlotInfos< FInstancedSkinnedMeshSceneProxyDesc >(const FInstancedSkinnedMeshSceneProxyDesc &Object)
Definition NaniteResourcesHelper.cpp:85
FString GetMaterialMeshName(const T &Object)
Definition NaniteResourcesHelper.h:52
bool IsMaterialSkeletalMesh< USkinnedMeshComponent >(const USkinnedMeshComponent &Object)
Definition NaniteResourcesHelper.cpp:32
bool IsMaterialSkeletalMesh< FSkinnedMeshSceneProxyDesc >(const FSkinnedMeshSceneProxyDesc &Object)
Definition NaniteResourcesHelper.cpp:38
TArray< FAuditMaterialSlotInfo, TInlineAllocator< 32 > > GetMaterialSlotInfos< FSkinnedMeshSceneProxyDesc >(const FSkinnedMeshSceneProxyDesc &Object)
Definition NaniteResourcesHelper.cpp:68
FString GetMaterialMeshName< USkinnedMeshComponent >(const USkinnedMeshComponent &Object)
Definition NaniteResourcesHelper.cpp:14
bool IsMaterialSkeletalMesh(const T &Object)
Definition NaniteResourcesHelper.h:58
bool IsMaterialSkeletalMesh< FInstancedSkinnedMeshSceneProxyDesc >(const FInstancedSkinnedMeshSceneProxyDesc &Object)
Definition NaniteResourcesHelper.cpp:44
FString GetMaterialMeshName< FInstancedSkinnedMeshSceneProxyDesc >(const FInstancedSkinnedMeshSceneProxyDesc &Object)
Definition NaniteResourcesHelper.cpp:26
TArray< FAuditMaterialSlotInfo, TInlineAllocator< 32 > > GetMaterialSlotInfos< USkinnedMeshComponent >(const USkinnedMeshComponent &Object)
Definition NaniteResourcesHelper.cpp:50
TArray< FAuditMaterialSlotInfo, TInlineAllocator< 32 > > GetMaterialSlotInfos(const T &Object)
Definition NaniteResourcesHelper.h:64
Definition SkinnedMeshComponent.h:50
bool IsSupportedShadingModel(FMaterialShadingModelField ShadingModelField)
Definition NaniteResources.cpp:3217
bool IsMaskingAllowed(UWorld *World, bool bForceNaniteForMasked)
Definition NaniteResources.cpp:3222
int32 GEnableNaniteMaterialOverrides
Definition StaticMeshSceneProxy.cpp:122
bool IsSupportedBlendMode(EBlendMode BlendMode)
Definition NaniteResources.cpp:3204
Definition OverriddenPropertySet.cpp:45
U16 Index
Definition radfft.cpp:71
Definition InstancedSkinnedMeshSceneProxyDesc.h:11
Definition MaterialCachedData.h:199
Definition MeshUVChannelInfo.h:13
Definition SkinnedMeshSceneProxyDesc.h:21
Definition StaticMesh.h:487
TConsoleVariableData< int32 > * FindTConsoleVariableDataInt(const TCHAR *Name) const
Definition IConsoleManager.h:1203
static IConsoleManager & Get()
Definition IConsoleManager.h:1270
Definition NaniteSceneProxy.h:43
FVector4f LocalUVDensities
Definition NaniteSceneProxy.h:62
uint8 bHasUnsupportedBlendMode
Definition NaniteSceneProxy.h:52
UMaterialInterface * Material
Definition NaniteSceneProxy.h:44
uint8 bHasInvalidUsage
Definition NaniteSceneProxy.h:60
uint8 bHasTessellationEnabled
Definition NaniteSceneProxy.h:55
FName MaterialSlotName
Definition NaniteSceneProxy.h:46
uint8 bHasVertexUVs
Definition NaniteSceneProxy.h:57
uint8 bHasUnsupportedShadingModel
Definition NaniteSceneProxy.h:53
uint8 bHasPerInstanceRandomID
Definition NaniteSceneProxy.h:58
uint8 bHasAnyError
Definition NaniteSceneProxy.h:49
uint8 bHasPixelDepthOffset
Definition NaniteSceneProxy.h:54
uint8 bHasNullMaterial
Definition NaniteSceneProxy.h:50
uint8 bHasPerInstanceCustomData
Definition NaniteSceneProxy.h:59
uint8 bHasWorldPositionOffset
Definition NaniteSceneProxy.h:51
int32 MaterialIndex
Definition NaniteSceneProxy.h:47
uint8 bHasVertexInterpolator
Definition NaniteSceneProxy.h:56
Definition NaniteSceneProxy.h:66
Definition NaniteResources.h:410
TArray< FPageStreamingState > PageStreamingStates
Definition NaniteResources.h:417
Definition NaniteResourcesHelper.h:45
UMaterialInterface * Material
Definition NaniteResourcesHelper.h:46
FName SlotName
Definition NaniteResourcesHelper.h:47
FMeshUVChannelInfo UVChannelData
Definition NaniteResourcesHelper.h:48