Skip to content

关于Bridge的优化建议 #11

@tsdaer

Description

@tsdaer

settings.json 的自动化构建

当前 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);
}
...

json文本的序列化/反序列化性能热点

material-expressions.json,substrate-builtins.json,diagnostics.json在承载大量数据时表现不佳,建议引入数据库实现(引擎已有内部模块:FSQLiteCore),关于数据库的实现,如果你允许的话我将会创建PR

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions