Formalize renderer material contracts and harden backpack import

This commit is contained in:
2026-04-08 04:27:21 +08:00
parent 7be3b2cc45
commit 6113ed92b0
18 changed files with 534 additions and 326 deletions

View File

@@ -99,7 +99,7 @@ public:
const Containers::String& GetLastErrorMessage() const { return m_lastErrorMessage; }
private:
static constexpr Core::uint32 kCurrentImporterVersion = 6;
static constexpr Core::uint32 kCurrentImporterVersion = 7;
void EnsureProjectLayout();
void LoadSourceAssetDB();

View File

@@ -13,11 +13,6 @@
namespace XCEngine {
namespace Rendering {
struct BuiltinForwardMaterialData {
Math::Vector4 baseColorFactor = Math::Vector4::One();
float alphaCutoff = 0.5f;
};
enum class BuiltinSkyboxTextureMode : Core::uint8 {
None = 0,
Panoramic = 1,
@@ -81,34 +76,7 @@ inline Math::Vector4 ResolveBuiltinBaseColorFactor(const Resources::Material* ma
}
}
static const char* kBaseColorPropertyNames[] = {
"baseColor",
"_BaseColor",
"color",
"_Color"
};
for (const char* propertyName : kBaseColorPropertyNames) {
if (material->HasProperty(Containers::String(propertyName))) {
return material->GetFloat4(Containers::String(propertyName));
}
}
Math::Vector4 baseColor = Math::Vector4::One();
static const char* kOpacityPropertyNames[] = {
"opacity",
"_Opacity",
"alpha",
"_Alpha"
};
for (const char* propertyName : kOpacityPropertyNames) {
if (material->HasProperty(Containers::String(propertyName))) {
baseColor.w = material->GetFloat(Containers::String(propertyName));
break;
}
}
return baseColor;
return Math::Vector4::One();
}
inline const Resources::Texture* ResolveBuiltinBaseColorTexture(const Resources::Material* material) {
@@ -123,23 +91,6 @@ inline const Resources::Texture* ResolveBuiltinBaseColorTexture(const Resources:
}
}
static const char* kTextureNames[] = {
"baseColorTexture",
"_BaseColorTexture",
"_MainTex",
"albedoTexture",
"mainTexture",
"texture"
};
for (const char* textureName : kTextureNames) {
const Resources::ResourceHandle<Resources::Texture> textureHandle =
material->GetTexture(Containers::String(textureName));
if (textureHandle.Get() != nullptr && textureHandle->IsValid()) {
return textureHandle.Get();
}
}
return nullptr;
}
@@ -156,29 +107,9 @@ inline float ResolveBuiltinAlphaCutoff(const Resources::Material* material) {
}
}
static const char* kCutoffPropertyNames[] = {
"_Cutoff",
"cutoff",
"_AlphaCutoff",
"alphaCutoff"
};
for (const char* propertyName : kCutoffPropertyNames) {
if (material->HasProperty(Containers::String(propertyName))) {
return material->GetFloat(Containers::String(propertyName));
}
}
return 0.5f;
}
inline BuiltinForwardMaterialData BuildBuiltinForwardMaterialData(const Resources::Material* material) {
BuiltinForwardMaterialData data = {};
data.baseColorFactor = ResolveBuiltinBaseColorFactor(material);
data.alphaCutoff = ResolveBuiltinAlphaCutoff(material);
return data;
}
inline bool IsCubemapSkyboxTextureType(Resources::TextureType type) {
return type == Resources::TextureType::TextureCube ||
type == Resources::TextureType::TextureCubeArray;
@@ -493,16 +424,6 @@ inline Core::int32 ResolveMaterialRenderQueue(const Resources::Material* materia
}
if (const Resources::Shader* shader = material->GetShader()) {
const Containers::String legacyExplicitPassName = material->GetLegacyShaderPassHint();
if (!NormalizeBuiltinPassMetadataValue(legacyExplicitPassName).Empty()) {
if (const Resources::ShaderPass* explicitPass = shader->FindPass(legacyExplicitPassName)) {
Core::int32 shaderQueue = defaultQueue;
if (TryResolveShaderPassRenderQueue(*explicitPass, shaderQueue)) {
return shaderQueue;
}
}
}
for (const Resources::ShaderPass& pass : shader->GetPasses()) {
Core::int32 shaderQueue = defaultQueue;
if (TryResolveShaderPassRenderQueue(pass, shaderQueue)) {
@@ -518,52 +439,6 @@ inline bool IsTransparentRenderQueue(Core::int32 renderQueue) {
return renderQueue >= static_cast<Core::int32>(Resources::MaterialRenderQueue::Transparent);
}
inline bool HasLegacyMaterialBuiltinPassHints(const Resources::Material* material) {
if (material == nullptr) {
return false;
}
return !NormalizeBuiltinPassMetadataValue(material->GetLegacyShaderPassHint()).Empty() ||
!NormalizeBuiltinPassMetadataValue(material->GetTag("LightMode")).Empty();
}
inline bool LegacyMaterialBuiltinPassHintsMatch(
const Resources::Material* material,
BuiltinMaterialPass pass) {
if (material == nullptr) {
return false;
}
const Containers::String shaderPass = material->GetLegacyShaderPassHint();
const Containers::String lightMode = material->GetTag("LightMode");
const bool hasMaterialShaderPass = !NormalizeBuiltinPassMetadataValue(shaderPass).Empty();
const bool hasMaterialLightMode = !NormalizeBuiltinPassMetadataValue(lightMode).Empty();
if (!hasMaterialShaderPass && !hasMaterialLightMode) {
return false;
}
if (hasMaterialShaderPass &&
!MatchesBuiltinPassName(shaderPass, pass)) {
return false;
}
if (hasMaterialLightMode &&
!MatchesBuiltinPassName(lightMode, pass)) {
return false;
}
return true;
}
inline bool CanUseLegacyMaterialPassFallback(const Resources::Material* material) {
if (material == nullptr) {
return true;
}
const Resources::Shader* shader = material->GetShader();
return shader == nullptr || !ShaderHasExplicitBuiltinMetadata(*shader);
}
inline bool MatchesBuiltinPass(const Resources::Material* material, BuiltinMaterialPass pass) {
if (material == nullptr) {
return pass == BuiltinMaterialPass::ForwardLit;
@@ -578,14 +453,10 @@ inline bool MatchesBuiltinPass(const Resources::Material* material, BuiltinMater
}
}
if (!CanUseLegacyMaterialPassFallback(material)) {
if (shader != nullptr && ShaderHasExplicitBuiltinMetadata(*shader)) {
return false;
}
if (HasLegacyMaterialBuiltinPassHints(material)) {
return LegacyMaterialBuiltinPassHintsMatch(material, pass);
}
return pass == BuiltinMaterialPass::ForwardLit;
}

View File

@@ -60,11 +60,6 @@ private:
RHI::RHIDescriptorSet* set = nullptr;
};
struct FallbackPerMaterialConstants {
Math::Vector4 baseColorFactor = Math::Vector4::One();
Math::Vector4 alphaCutoffParams = Math::Vector4(0.5f, 0.0f, 0.0f, 0.0f);
};
struct PassLayoutKey {
const Resources::Shader* shader = nullptr;
Containers::String passName;

View File

@@ -96,11 +96,6 @@ private:
Math::Vector4 shadowOptions = Math::Vector4::Zero();
};
struct FallbackPerMaterialConstants {
Math::Vector4 baseColorFactor = Math::Vector4::One();
Math::Vector4 alphaCutoffParams = Math::Vector4(0.5f, 0.0f, 0.0f, 0.0f);
};
struct SkyboxConstants {
Math::Vector4 topColor = Math::Vector4::Zero();
Math::Vector4 horizonColor = Math::Vector4::Zero();