Skip to content

Commit 2edaf43

Browse files
authored
Merge pull request #1681 from CesiumGS/look-for-cesium-material-data
Fix handling of Dynamic Material Instances when creating tile meshes
2 parents 57f672d + 70949c7 commit 2edaf43

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Add a missing include for `GEngine` when packaging from source, introduced in *v2.16.0*.
1313
- Fixed a bug in `UCesiumFeaturesMetadataComponent` where multiple references to same feature ID set would cause improper encoding of its feature IDs.
1414
- Fixed a crash that would occur when duplicating an `ACesiumGeoreference`.
15+
- Fixed a bug that caused tilesets to render incorrectly when Dynamic Material Instances were used for their material settings.
1516
- Removed an unnecessary copy operation that happened while constructing tile meshes.
1617

1718
### v2.16.0 - 2025-05-01

Source/CesiumRuntime/Private/CesiumGltfComponent.cpp

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3165,8 +3165,21 @@ static void loadPrimitiveGameThreadPart(
31653165
{
31663166
TRACE_CPUPROFILER_EVENT_SCOPE(Cesium::SetupMaterial)
31673167

3168+
UMaterialInstanceDynamic* pBaseAsMaterialInstanceDynamic =
3169+
Cast<UMaterialInstanceDynamic>(pBaseMaterial);
3170+
UMaterialInstance* pParentMaterialInstance =
3171+
Cast<UMaterialInstance>(pBaseMaterial);
3172+
3173+
// If the base material is a UMaterialInstanceDynamic, Create() will
3174+
// reject it as a valid instance parent. Defer to its non-dynamic parent
3175+
// instead.
3176+
if (pBaseAsMaterialInstanceDynamic) {
3177+
pParentMaterialInstance =
3178+
Cast<UMaterialInstance>(pParentMaterialInstance->Parent.Get());
3179+
}
3180+
31683181
pMaterial = UMaterialInstanceDynamic::Create(
3169-
pBaseMaterial,
3182+
pParentMaterialInstance,
31703183
nullptr,
31713184
ImportedSlotName);
31723185

@@ -3187,37 +3200,45 @@ static void loadPrimitiveGameThreadPart(
31873200
EMaterialParameterAssociation::GlobalParameter,
31883201
INDEX_NONE);
31893202

3190-
UMaterialInstance* pBaseAsMaterialInstance =
3191-
Cast<UMaterialInstance>(pBaseMaterial);
31923203
UCesiumMaterialUserData* pCesiumData =
3193-
pBaseAsMaterialInstance
3194-
? pBaseAsMaterialInstance
3204+
pParentMaterialInstance
3205+
? pParentMaterialInstance
31953206
->GetAssetUserData<UCesiumMaterialUserData>()
31963207
: nullptr;
31973208

31983209
// If possible and necessary, attach the CesiumMaterialUserData now.
31993210
#if WITH_EDITORONLY_DATA
3200-
if (pBaseAsMaterialInstance && !pCesiumData) {
3211+
if (pParentMaterialInstance && !pCesiumData) {
32013212
const FStaticParameterSet& parameters =
3202-
pBaseAsMaterialInstance->GetStaticParameters();
3213+
pParentMaterialInstance->GetStaticParameters();
32033214

32043215
bool hasLayers = parameters.bHasMaterialLayers;
32053216
if (hasLayers) {
32063217
#if WITH_EDITOR
32073218
FScopedTransaction transaction(
32083219
FText::FromString("Add Cesium User Data to Material"));
3209-
pBaseAsMaterialInstance->Modify();
3220+
pParentMaterialInstance->Modify();
32103221
#endif
32113222
pCesiumData = NewObject<UCesiumMaterialUserData>(
3212-
pBaseAsMaterialInstance,
3223+
pParentMaterialInstance,
32133224
NAME_None,
32143225
RF_Transactional);
3215-
pBaseAsMaterialInstance->AddAssetUserData(pCesiumData);
3226+
pParentMaterialInstance->AddAssetUserData(pCesiumData);
32163227
pCesiumData->PostEditChangeOwner();
32173228
}
32183229
}
32193230
#endif
32203231

3232+
// If CesiumMaterialUserData was not attached (e.g., material was
3233+
// dynamically created at runtime), then walk the parent chain of the
3234+
// material to find it.
3235+
while (pParentMaterialInstance && !pCesiumData) {
3236+
pParentMaterialInstance =
3237+
Cast<UMaterialInstance>(pParentMaterialInstance->Parent.Get());
3238+
pCesiumData =
3239+
pParentMaterialInstance->GetAssetUserData<UCesiumMaterialUserData>();
3240+
}
3241+
32213242
if (pCesiumData) {
32223243
SetGltfParameterValues(
32233244
model,
@@ -3279,6 +3300,42 @@ static void loadPrimitiveGameThreadPart(
32793300
metadataIndex);
32803301
}
32813302
}
3303+
3304+
if (pBaseAsMaterialInstanceDynamic) {
3305+
// Ensure any parameters on the original UMaterialInstanceDynamic are
3306+
// transferred to the copy.
3307+
for (auto& it : pBaseAsMaterialInstanceDynamic->ScalarParameterValues) {
3308+
pMaterial->SetScalarParameterValueByInfo(
3309+
it.ParameterInfo,
3310+
it.ParameterValue);
3311+
}
3312+
3313+
for (auto& it : pBaseAsMaterialInstanceDynamic->VectorParameterValues) {
3314+
pMaterial->SetVectorParameterValueByInfo(
3315+
it.ParameterInfo,
3316+
it.ParameterValue);
3317+
}
3318+
3319+
for (auto& it :
3320+
pBaseAsMaterialInstanceDynamic->DoubleVectorParameterValues) {
3321+
pMaterial->SetVectorParameterValueByInfo(
3322+
it.ParameterInfo,
3323+
it.ParameterValue);
3324+
}
3325+
3326+
for (auto& it : pBaseAsMaterialInstanceDynamic->TextureParameterValues) {
3327+
pMaterial->SetTextureParameterValueByInfo(
3328+
it.ParameterInfo,
3329+
it.ParameterValue);
3330+
}
3331+
3332+
for (auto& it : pBaseAsMaterialInstanceDynamic->FontParameterValues) {
3333+
pMaterial->SetFontParameterValue(
3334+
it.ParameterInfo,
3335+
it.FontValue,
3336+
it.FontPage);
3337+
}
3338+
}
32823339
}
32833340

32843341
primData.Features = std::move(loadResult.Features);

0 commit comments

Comments
 (0)