diff --git a/Source/glTFRuntime/Private/glTFRuntimeParserMaterials.cpp b/Source/glTFRuntime/Private/glTFRuntimeParserMaterials.cpp index e255ff1..965b7cb 100644 --- a/Source/glTFRuntime/Private/glTFRuntimeParserMaterials.cpp +++ b/Source/glTFRuntime/Private/glTFRuntimeParserMaterials.cpp @@ -329,6 +329,37 @@ UMaterialInterface* FglTFRuntimeParser::LoadMaterial_Internal(const int32 Index, GetMaterialTexture(JsonMaterialSheen->ToSharedRef(), "sheenRoughnessTexture", false, RuntimeMaterial.SheenRoughnessTextureCache, RuntimeMaterial.SheenRoughnessTextureMips, RuntimeMaterial.SheenRoughnessTextureTransform, RuntimeMaterial.SheenRoughnessTextureSampler, false); RuntimeMaterial.bKHR_materials_sheen = true; } + + // KHR_materials_iridescence + const TSharedPtr* JsonMaterialIridescence; + if ((*JsonExtensions)->TryGetObjectField(TEXT("KHR_materials_iridescence"), JsonMaterialIridescence)) + { + if (!(*JsonMaterialIridescence)->TryGetNumberField(TEXT("iridescenceFactor"), RuntimeMaterial.IridescenceFactor)) + { + RuntimeMaterial.IridescenceFactor = 0; + } + + if (!(*JsonMaterialIridescence)->TryGetNumberField(TEXT("iridescenceIor"), RuntimeMaterial.IridescenceIor)) + { + RuntimeMaterial.IridescenceIor = 1.3; + } + + if (!(*JsonMaterialIridescence)->TryGetNumberField(TEXT("iridescenceThicknessMinimum"), RuntimeMaterial.IridescenceThicknessMinimum)) + { + RuntimeMaterial.IridescenceThicknessMinimum = 100; + } + + if (!(*JsonMaterialIridescence)->TryGetNumberField(TEXT("iridescenceThicknessMaximum"), RuntimeMaterial.IridescenceThicknessMaximum)) + { + RuntimeMaterial.IridescenceThicknessMaximum = 400; + } + + GetMaterialTexture(JsonMaterialIridescence->ToSharedRef(), "iridescenceTexture", false, RuntimeMaterial.IridescenceTextureCache, RuntimeMaterial.IridescenceTextureMips, RuntimeMaterial.IridescenceTextureTransform, RuntimeMaterial.IridescenceTextureSampler, false); + GetMaterialTexture(JsonMaterialIridescence->ToSharedRef(), "iridescenceThicknessTexture", false, RuntimeMaterial.IridescenceThicknessTextureCache, RuntimeMaterial.IridescenceThicknessTextureMips, RuntimeMaterial.IridescenceThicknessTextureTransform, RuntimeMaterial.IridescenceThicknessTextureSampler, false); + + RuntimeMaterial.bKHR_materials_iridescence = true; + } + } if (IsInGameThread()) @@ -649,18 +680,33 @@ UMaterialInterface* FglTFRuntimeParser::BuildMaterial(const int32 Index, const F { if (MaterialsConfig.bUseSubstrateMaterials && !RuntimeMaterial.bKHR_materials_unlit && !RuntimeMaterial.bKHR_materials_pbrSpecularGlossiness) { - EglTFRuntimeSubstrateMaterialType SubstrateMaterialType = RuntimeMaterial.bTwoSided ? EglTFRuntimeSubstrateMaterialType::OpaqueTwoSided : EglTFRuntimeSubstrateMaterialType::Opaque; + bool bIsSimpleSlab = true; + if (RuntimeMaterial.bKHR_materials_clearcoat || RuntimeMaterial.bKHR_materials_iridescence || RuntimeMaterial.bKHR_materials_sheen || RuntimeMaterial.bKHR_materials_volume) + { + bIsSimpleSlab = false; + } + + EglTFRuntimeSubstrateMaterialType SubstrateMaterialType = RuntimeMaterial.bTwoSided ? + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleOpaqueTwoSided : EglTFRuntimeSubstrateMaterialType::OpaqueTwoSided) : + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleOpaque : EglTFRuntimeSubstrateMaterialType::Opaque); + if (RuntimeMaterial.bKHR_materials_transmission) { - SubstrateMaterialType = RuntimeMaterial.bTwoSided ? EglTFRuntimeSubstrateMaterialType::TransmittanceTwoSided : EglTFRuntimeSubstrateMaterialType::Transmittance; + SubstrateMaterialType = RuntimeMaterial.bTwoSided ? + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleTransmittanceTwoSided : EglTFRuntimeSubstrateMaterialType::TransmittanceTwoSided) : + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleTransmittance : EglTFRuntimeSubstrateMaterialType::Transmittance); } else if (RuntimeMaterial.bTranslucent) { - SubstrateMaterialType = RuntimeMaterial.bTwoSided ? EglTFRuntimeSubstrateMaterialType::AlphaCompositeTwoSided : EglTFRuntimeSubstrateMaterialType::AlphaComposite; + SubstrateMaterialType = RuntimeMaterial.bTwoSided ? + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleAlphaCompositeTwoSided : EglTFRuntimeSubstrateMaterialType::AlphaCompositeTwoSided) : + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleAlphaComposite : EglTFRuntimeSubstrateMaterialType::AlphaComposite); } else if (RuntimeMaterial.bMasked) { - SubstrateMaterialType = RuntimeMaterial.bTwoSided ? EglTFRuntimeSubstrateMaterialType::MaskedTwoSided : EglTFRuntimeSubstrateMaterialType::Masked; + SubstrateMaterialType = RuntimeMaterial.bTwoSided ? + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleMaskedTwoSided : EglTFRuntimeSubstrateMaterialType::MaskedTwoSided) : + (bIsSimpleSlab ? EglTFRuntimeSubstrateMaterialType::SimpleMasked : EglTFRuntimeSubstrateMaterialType::Masked); } if (MaterialsConfig.SubstrateMaterials.Contains(SubstrateMaterialType)) @@ -956,6 +1002,23 @@ UMaterialInterface* FglTFRuntimeParser::BuildMaterial(const int32 Index, const F TextureCompressionSettings::TC_Default, false); } + ApplyMaterialFloatFactor(RuntimeMaterial.bKHR_materials_iridescence, "iridescenceFactor", RuntimeMaterial.IridescenceFactor); + ApplyMaterialFloatFactor(RuntimeMaterial.bKHR_materials_iridescence, "iridescenceIor", RuntimeMaterial.IridescenceIor); + ApplyMaterialFloatFactor(RuntimeMaterial.bKHR_materials_iridescence, "iridescenceThicknessMaximum", RuntimeMaterial.IridescenceThicknessMaximum); + ApplyMaterialFloatFactor(RuntimeMaterial.bKHR_materials_iridescence, "iridescenceThicknessMinimum", RuntimeMaterial.IridescenceThicknessMinimum); + if (RuntimeMaterial.bKHR_materials_iridescence) + { + ApplyMaterialTexture("iridescenceTexture", RuntimeMaterial.IridescenceTextureCache, RuntimeMaterial.IridescenceTextureMips, + RuntimeMaterial.IridescenceTextureSampler, + "iridescence", RuntimeMaterial.IridescenceTextureTransform, + TextureCompressionSettings::TC_Default, true); + + ApplyMaterialTexture("iridescenceThicknessTexture", RuntimeMaterial.IridescenceThicknessTextureCache, RuntimeMaterial.IridescenceThicknessTextureMips, + RuntimeMaterial.IridescenceThicknessTextureSampler, + "iridescenceThickness", RuntimeMaterial.IridescenceThicknessTextureTransform, + TextureCompressionSettings::TC_Default, true); + } + ApplyMaterialFloatFactor(RuntimeMaterial.bKHR_materials_emissive_strength, "emissiveStrength", RuntimeMaterial.EmissiveStrength); for (const TPair& Pair : MaterialsConfig.ScalarParamsOverrides) diff --git a/Source/glTFRuntime/Public/glTFRuntimeParser.h b/Source/glTFRuntime/Public/glTFRuntimeParser.h index 63aa891..dcb8f1c 100644 --- a/Source/glTFRuntime/Public/glTFRuntimeParser.h +++ b/Source/glTFRuntime/Public/glTFRuntimeParser.h @@ -437,6 +437,14 @@ enum class EglTFRuntimeMaterialType : uint8 UENUM() enum class EglTFRuntimeSubstrateMaterialType : uint8 { + SimpleOpaque, + SimpleOpaqueTwoSided, + SimpleTransmittance, + SimpleTransmittanceTwoSided, + SimpleAlphaComposite, + SimpleAlphaCompositeTwoSided, + SimpleMasked, + SimpleMaskedTwoSided, Opaque, OpaqueTwoSided, Transmittance, @@ -2202,6 +2210,19 @@ struct FglTFRuntimeMaterial FglTFRuntimeTextureTransform SheenRoughnessTextureTransform; FglTFRuntimeTextureSampler SheenRoughnessTextureSampler; + bool bKHR_materials_iridescence; + double IridescenceFactor; + double IridescenceIor; + double IridescenceThicknessMaximum; + double IridescenceThicknessMinimum; + UTexture2D* IridescenceTextureCache; + TArray IridescenceTextureMips; + FglTFRuntimeTextureSampler IridescenceTextureSampler; + FglTFRuntimeTextureTransform IridescenceTextureTransform; + UTexture2D* IridescenceThicknessTextureCache; + TArray IridescenceThicknessTextureMips; + FglTFRuntimeTextureSampler IridescenceThicknessTextureSampler; + FglTFRuntimeTextureTransform IridescenceThicknessTextureTransform; FglTFRuntimeMaterial() { @@ -2253,6 +2274,13 @@ struct FglTFRuntimeMaterial SheenRoughnessFactor = 0; SheenColorTextureCache = nullptr; SheenRoughnessTextureCache = nullptr; + bKHR_materials_iridescence = false; + IridescenceFactor = 0; + IridescenceIor = 1.3; + IridescenceThicknessMaximum = 400; + IridescenceThicknessMinimum = 100; + IridescenceTextureCache = nullptr; + IridescenceThicknessTextureCache = nullptr; } };