Tighten material loader schema parsing

This commit is contained in:
2026-04-08 01:10:51 +08:00
parent 077a6b0a51
commit 6e6a98a022
2 changed files with 182 additions and 177 deletions

View File

@@ -217,7 +217,6 @@ TEST(MaterialLoader, LoadValidMaterialParsesRenderMetadata) {
materialFile << "{\n";
materialFile << " \"shader\": \"" << shaderPath.generic_string() << "\",\n";
materialFile << " \"renderQueue\": \"Transparent\",\n";
materialFile << " \"shaderPass\": \"ForwardLit\",\n";
materialFile << " \"tags\": {\n";
materialFile << " \"LightMode\": \"ForwardBase\",\n";
materialFile << " \"RenderType\": \"Transparent\"\n";
@@ -243,7 +242,6 @@ TEST(MaterialLoader, LoadValidMaterialParsesRenderMetadata) {
EXPECT_TRUE(material->IsValid());
EXPECT_NE(material->GetShader(), nullptr);
EXPECT_EQ(material->GetRenderQueue(), static_cast<XCEngine::Core::int32>(MaterialRenderQueue::Transparent));
EXPECT_TRUE(material->GetLegacyShaderPassHint().Empty());
EXPECT_EQ(material->GetTag("LightMode"), "ForwardBase");
EXPECT_EQ(material->GetTag("RenderType"), "Transparent");
EXPECT_EQ(material->GetRenderState().cullMode, MaterialCullMode::Back);
@@ -380,7 +378,6 @@ TEST(MaterialLoader, LoadMaterialWithAuthoringShaderResolvesShaderPass) {
ASSERT_TRUE(materialFile.is_open());
materialFile << "{\n";
materialFile << " \"shader\": \"" << shaderPath.generic_string() << "\",\n";
materialFile << " \"shaderPass\": \"ForwardLit\",\n";
materialFile << " \"renderQueue\": \"Geometry\"\n";
materialFile << "}\n";
}
@@ -393,7 +390,6 @@ TEST(MaterialLoader, LoadMaterialWithAuthoringShaderResolvesShaderPass) {
Material* material = static_cast<Material*>(result.resource);
ASSERT_NE(material, nullptr);
ASSERT_NE(material->GetShader(), nullptr);
EXPECT_TRUE(material->GetLegacyShaderPassHint().Empty());
ASSERT_NE(material->GetShader()->FindPass("ForwardLit"), nullptr);
const ShaderStageVariant* vertexVariant =
material->GetShader()->FindVariant("ForwardLit", ShaderType::Vertex, ShaderBackend::OpenGL);
@@ -419,7 +415,6 @@ TEST(MaterialLoader, LoadMaterialWithPropertiesObjectAppliesTypedOverrides) {
materialPath,
"{\n"
" \"shader\": \"" + shaderPath.generic_string() + "\",\n"
" \"shaderPass\": \"ForwardLit\",\n"
" \"properties\": {\n"
" \"_BaseColor\": [0.2, 0.4, 0.6, 0.8],\n"
" \"_Metallic\": 0.15,\n"
@@ -435,7 +430,6 @@ TEST(MaterialLoader, LoadMaterialWithPropertiesObjectAppliesTypedOverrides) {
auto* material = static_cast<Material*>(result.resource);
ASSERT_NE(material, nullptr);
ASSERT_NE(material->GetShader(), nullptr);
EXPECT_TRUE(material->GetLegacyShaderPassHint().Empty());
EXPECT_EQ(material->GetFloat4("_BaseColor"), XCEngine::Math::Vector4(0.2f, 0.4f, 0.6f, 0.8f));
EXPECT_FLOAT_EQ(material->GetFloat("_Metallic"), 0.15f);
EXPECT_EQ(material->GetInt("_Mode"), 5);
@@ -446,7 +440,7 @@ TEST(MaterialLoader, LoadMaterialWithPropertiesObjectAppliesTypedOverrides) {
fs::remove_all(rootPath);
}
TEST(MaterialLoader, LoadBuiltinShaderMaterialDropsRedundantBuiltinShaderPassHint) {
TEST(MaterialLoader, LoadBuiltinShaderMaterialUsesShaderMetadataWithoutMaterialPassHint) {
namespace fs = std::filesystem;
ResourceManager& manager = ResourceManager::Get();
@@ -460,8 +454,7 @@ TEST(MaterialLoader, LoadBuiltinShaderMaterialDropsRedundantBuiltinShaderPassHin
WriteTextFile(
materialPath,
"{\n"
" \"shader\": \"" + std::string(GetBuiltinUnlitShaderPath().CStr()) + "\",\n"
" \"shaderPass\": \"Unlit\"\n"
" \"shader\": \"" + std::string(GetBuiltinUnlitShaderPath().CStr()) + "\"\n"
"}\n");
MaterialLoader loader;
@@ -472,7 +465,6 @@ TEST(MaterialLoader, LoadBuiltinShaderMaterialDropsRedundantBuiltinShaderPassHin
auto* material = static_cast<Material*>(result.resource);
ASSERT_NE(material, nullptr);
ASSERT_NE(material->GetShader(), nullptr);
EXPECT_TRUE(material->GetLegacyShaderPassHint().Empty());
EXPECT_NE(material->GetShader()->FindPass("Unlit"), nullptr);
delete material;
@@ -568,7 +560,7 @@ TEST(MaterialLoader, LoadMaterialWithPropertiesObjectPreservesShaderDefaultsForO
fs::remove_all(rootPath);
}
TEST(MaterialLoader, LoadMaterialMapsLegacySemanticKeysIntoShaderSchemaProperties) {
TEST(MaterialLoader, RejectsSemanticKeysWhenShaderSchemaRequiresExactPropertyNames) {
namespace fs = std::filesystem;
const fs::path rootPath = fs::temp_directory_path() / "xc_material_loader_semantic_alias_test";
@@ -593,21 +585,7 @@ TEST(MaterialLoader, LoadMaterialMapsLegacySemanticKeysIntoShaderSchemaPropertie
MaterialLoader loader;
LoadResult result = loader.Load(materialPath.generic_string().c_str());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
auto* material = static_cast<Material*>(result.resource);
ASSERT_NE(material, nullptr);
ASSERT_NE(material->GetShader(), nullptr);
EXPECT_FALSE(material->HasProperty("baseColor"));
EXPECT_EQ(material->GetFloat4("_BaseColor"), XCEngine::Math::Vector4(0.2f, 0.4f, 0.6f, 0.8f));
ASSERT_EQ(material->GetTextureBindingCount(), 1u);
EXPECT_EQ(material->GetTextureBindingName(0), "_MainTex");
EXPECT_EQ(
fs::path(material->GetTextureBindingPath(0).CStr()).lexically_normal().generic_string(),
(rootPath / "checker.bmp").lexically_normal().generic_string());
delete material;
EXPECT_FALSE(result);
fs::remove_all(rootPath);
}
@@ -624,7 +602,6 @@ TEST(MaterialLoader, LoadMaterialParsesKeywordArrayAgainstShaderSchema) {
materialPath,
"{\n"
" \"shader\": \"" + shaderPath.generic_string() + "\",\n"
" \"shaderPass\": \"ForwardLit\",\n"
" \"keywords\": [\"XC_MAIN_LIGHT_SHADOWS\", \"XC_ALPHA_TEST\", \"XC_ALPHA_TEST\", \"_\"]\n"
"}\n");
@@ -839,7 +816,6 @@ TEST(MaterialLoader, AssetDatabaseMaterialArtifactRoundTripsKeywords) {
materialPath,
"{\n"
" \"shader\": \"Assets/Shaders/keyword.shader\",\n"
" \"shaderPass\": \"ForwardLit\",\n"
" \"keywords\": [\"XC_MAIN_LIGHT_SHADOWS\", \"XC_ALPHA_TEST\"]\n"
"}\n");
@@ -873,7 +849,7 @@ TEST(MaterialLoader, AssetDatabaseMaterialArtifactRoundTripsKeywords) {
fs::remove_all(projectRoot);
}
TEST(MaterialLoader, AssetDatabaseMaterialArtifactStripsRedundantBuiltinShaderPassHint) {
TEST(MaterialLoader, AssetDatabaseMaterialArtifactRoundTripsBuiltinShaderWithoutMaterialPassHint) {
namespace fs = std::filesystem;
ResourceManager& manager = ResourceManager::Get();
@@ -890,7 +866,6 @@ TEST(MaterialLoader, AssetDatabaseMaterialArtifactStripsRedundantBuiltinShaderPa
materialPath,
"{\n"
" \"shader\": \"" + std::string(GetBuiltinUnlitShaderPath().CStr()) + "\",\n"
" \"shaderPass\": \"Unlit\",\n"
" \"properties\": {\n"
" \"_BaseColor\": [1.0, 1.0, 1.0, 1.0]\n"
" }\n"
@@ -914,7 +889,6 @@ TEST(MaterialLoader, AssetDatabaseMaterialArtifactStripsRedundantBuiltinShaderPa
auto* material = static_cast<Material*>(result.resource);
ASSERT_NE(material, nullptr);
ASSERT_NE(material->GetShader(), nullptr);
EXPECT_TRUE(material->GetLegacyShaderPassHint().Empty());
EXPECT_EQ(material->GetFloat4("_BaseColor"), XCEngine::Math::Vector4(1.0f, 1.0f, 1.0f, 1.0f));
delete material;
@@ -1065,7 +1039,6 @@ TEST(MaterialLoader, AssetDatabaseReimportsMaterialWhenShaderDependencyChanges)
ASSERT_TRUE(materialFile.is_open());
materialFile << "{\n";
materialFile << " \"shader\": \"Assets/Shaders/lit.shader\",\n";
materialFile << " \"shaderPass\": \"ForwardLit\",\n";
materialFile << " \"renderQueue\": \"geometry\"\n";
materialFile << "}\n";
}
@@ -1133,7 +1106,6 @@ TEST(MaterialLoader, LoadMaterialArtifactDefersTexturePayloadUntilRequested) {
WriteArtifactString(output, "LazyMaterial");
WriteArtifactString(output, "Assets/lazy.material");
WriteArtifactString(output, "");
WriteArtifactString(output, "");
MaterialArtifactHeader header;
header.renderQueue = static_cast<XCEngine::Core::int32>(MaterialRenderQueue::Geometry);