当前 DreamShader 导出的 Saved/DreamShader/Bridge/settings.json 中,mappings只包含 UDreamShaderSettings里手动注册的默认项。虽然可以在编辑器中设置,但使其完全自动构建是更好的方法。
以下是DreamShaderSettings.cpp建议的代码:
#include "DreamShaderSettings.h"
#include "DreamShaderModule.h"
#include "DreamShaderVersionCompat.h"
namespace UE::DreamShader::Private
{
template<typename EnumType>
static bool IsValidAlias(const FString& Alias)
{
return !Alias.TrimStartAndEnd().IsEmpty();
}
template<typename EnumType>
static void AddDefaultEnumMapping(
TMap<FString, TEnumAsByte<EnumType>>& InMappings,
const FString& Alias,
const EnumType Value)
{
if (IsValidAlias<EnumType>(Alias) && !InMappings.Contains(Alias))
{
InMappings.Add(Alias, Value);
}
}
template<typename EnumType>
static void AddDefaultEnumMapping(
TMap<FString, TEnumAsByte<EnumType>>& InMappings,
const TCHAR* Alias,
const EnumType Value)
{
AddDefaultEnumMapping(InMappings, FString(Alias), Value);
}
static FString BuildAliasFromEnumName(const FString& EnumName, const TCHAR* Prefix)
{
FString Alias = EnumName;
int32 ScopeIndex = INDEX_NONE;
if (Alias.FindLastChar(TEXT(':'), ScopeIndex))
{
Alias = Alias.Mid(ScopeIndex + 1);
}
Alias.RemoveFromStart(Prefix);
return Alias;
}
template<typename EnumType>
static void AddReflectedEnumMappings(
TMap<FString, TEnumAsByte<EnumType>>& InMappings,
const UEnum* Enum,
const TCHAR* Prefix,
TFunctionRef<bool(int64, const FString&)> ShouldSkip)
{
if (!Enum)
{
return;
}
for (int32 Index = 0; Index < Enum->NumEnums(); ++Index)
{
if (Enum->HasMetaData(TEXT("Hidden"), Index))
{
continue;
}
const int64 Value = Enum->GetValueByIndex(Index);
const FString Name = Enum->GetNameStringByIndex(Index);
if (ShouldSkip(Value, Name))
{
continue;
}
AddDefaultEnumMapping(
InMappings,
BuildAliasFromEnumName(Name, Prefix),
static_cast<EnumType>(Value));
}
}
static void AddDefaultShadingModelMappings(TMap<FString, TEnumAsByte<EMaterialShadingModel>>& InMappings)
{
AddReflectedEnumMappings<EMaterialShadingModel>(
InMappings,
StaticEnum<EMaterialShadingModel>(),
TEXT("MSM_"),
[](const int64 Value, const FString& Name)
{
return Name == TEXT("MSM_NUM")
|| Name == TEXT("MSM_MAX")
|| Name == TEXT("MSM_FromMaterialExpression")
|| Value == static_cast<int64>(MSM_NUM)
|| Value == static_cast<int64>(MSM_MAX)
|| Value == static_cast<int64>(MSM_FromMaterialExpression);
});
AddDefaultEnumMapping(InMappings, TEXT("Default Lit"), MSM_DefaultLit);
AddDefaultEnumMapping(InMappings, TEXT("Lit"), MSM_DefaultLit);
AddDefaultEnumMapping(InMappings, TEXT("Preintegrated Skin"), MSM_PreintegratedSkin);
AddDefaultEnumMapping(InMappings, TEXT("Clear Coat"), MSM_ClearCoat);
AddDefaultEnumMapping(InMappings, TEXT("Subsurface Profile"), MSM_SubsurfaceProfile);
AddDefaultEnumMapping(InMappings, TEXT("Two Sided Foliage"), MSM_TwoSidedFoliage);
AddDefaultEnumMapping(InMappings, TEXT("Single Layer Water"), MSM_SingleLayerWater);
AddDefaultEnumMapping(InMappings, TEXT("Thin Translucent"), MSM_ThinTranslucent);
#if DREAMSHADER_WITH_SUBSTRATE_BUILTINS
AddDefaultEnumMapping(InMappings, TEXT("Substrate"), MSM_Strata);
AddDefaultEnumMapping(InMappings, TEXT("Strata"), MSM_Strata);
#endif
}
static void AddDefaultBlendModeMappings(TMap<FString, TEnumAsByte<EBlendMode>>& InMappings)
{
AddReflectedEnumMappings<EBlendMode>(
InMappings,
StaticEnum<EBlendMode>(),
TEXT("BLEND_"),
[](const int64 Value, const FString& Name)
{
return Name == TEXT("BLEND_MAX")
|| Value == static_cast<int64>(BLEND_MAX);
});
AddDefaultEnumMapping(InMappings, TEXT("Cutout"), BLEND_Masked);
AddDefaultEnumMapping(InMappings, TEXT("Transparent"), BLEND_Translucent);
AddDefaultEnumMapping(InMappings, TEXT("PremultipliedAlpha"), BLEND_AlphaComposite);
AddDefaultEnumMapping(InMappings, TEXT("Premultiplied"), BLEND_AlphaComposite);
}
static void AddDefaultMaterialDomainMappings(TMap<FString, TEnumAsByte<EMaterialDomain>>& InMappings)
{
AddReflectedEnumMappings<EMaterialDomain>(
InMappings,
StaticEnum<EMaterialDomain>(),
TEXT("MD_"),
[](const int64 Value, const FString& Name)
{
return Name == TEXT("MD_MAX")
|| Value == static_cast<int64>(MD_MAX);
});
AddDefaultEnumMapping(InMappings, TEXT("DeferredDecal"), MD_DeferredDecal);
AddDefaultEnumMapping(InMappings, TEXT("Decal"), MD_DeferredDecal);
AddDefaultEnumMapping(InMappings, TEXT("Light Function"), MD_LightFunction);
AddDefaultEnumMapping(InMappings, TEXT("Post Process"), MD_PostProcess);
AddDefaultEnumMapping(InMappings, TEXT("UserInterface"), MD_UI);
AddDefaultEnumMapping(InMappings, TEXT("User Interface"), MD_UI);
AddDefaultEnumMapping(InMappings, TEXT("Runtime Virtual Texture"), MD_RuntimeVirtualTexture);
AddDefaultEnumMapping(InMappings, TEXT("VirtualTexture"), MD_RuntimeVirtualTexture);
AddDefaultEnumMapping(InMappings, TEXT("Virtual Texture"), MD_RuntimeVirtualTexture);
}
}
UDreamShaderSettings::UDreamShaderSettings()
{
using namespace UE::DreamShader::Private;
SourceDirectory.Path = TEXT("DShader");
GeneratedShaderDirectory.Path = TEXT("Intermediate/DreamShader/GeneratedShaders");
AddDefaultShadingModelMappings(ShadingModelMappings);
AddDefaultBlendModeMappings(BlendModeMappings);
AddDefaultMaterialDomainMappings(MaterialDomainMappings);
}
...
material-expressions.json,substrate-builtins.json,diagnostics.json在承载大量数据时表现不佳,建议引入数据库实现(引擎已有内部模块:FSQLiteCore),关于数据库的实现,如果你允许的话我将会创建PR
settings.json 的自动化构建
当前 DreamShader 导出的 Saved/DreamShader/Bridge/settings.json 中,mappings只包含 UDreamShaderSettings里手动注册的默认项。虽然可以在编辑器中设置,但使其完全自动构建是更好的方法。
以下是DreamShaderSettings.cpp建议的代码:
json文本的序列化/反序列化性能热点
material-expressions.json,substrate-builtins.json,diagnostics.json在承载大量数据时表现不佳,建议引入数据库实现(引擎已有内部模块:FSQLiteCore),关于数据库的实现,如果你允许的话我将会创建PR