Formalize imported mesh materials

This commit is contained in:
2026-04-08 02:31:10 +08:00
parent 6e6a98a022
commit 75defb0a49
7 changed files with 12453 additions and 30913 deletions

View File

@@ -620,7 +620,7 @@ void BackpackTest::InitializeMaterialResources() {
MaterialResources& resources = mMaterialResources[materialIndex];
Texture* baseColorTexture = GetMaterialTexture(material, "baseColorTexture");
Texture* baseColorTexture = GetMaterialTexture(material, "_MainTex");
if (baseColorTexture != nullptr) {
const bool created =
CreateTextureViewFromResourceTexture(

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <XCEngine/Core/Asset/AssetDatabase.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Resources/BuiltinResources.h>
#include <XCEngine/Resources/Material/MaterialLoader.h>
#include <XCEngine/Resources/Mesh/MeshLoader.h>
@@ -25,16 +24,6 @@ std::string GetMeshFixturePath(const char* fileName) {
return (std::filesystem::path(XCENGINE_TEST_FIXTURES_DIR) / "Resources" / "Mesh" / fileName).string();
}
XCEngine::Core::uint32 ReadMeshIndex(const Mesh& mesh, XCEngine::Core::uint32 index) {
if (mesh.IsUse32BitIndex()) {
const auto* indices = static_cast<const XCEngine::Core::uint32*>(mesh.GetIndexData());
return indices[index];
}
const auto* indices = static_cast<const XCEngine::Core::uint16*>(mesh.GetIndexData());
return static_cast<XCEngine::Core::uint32>(indices[index]);
}
XCEngine::Core::uint32 GetFirstSectionMaterialIndex(const Mesh& mesh) {
if (mesh.GetSections().Empty()) {
return 0;
@@ -154,41 +143,6 @@ TEST(MeshLoader, LoadValidObjMesh) {
delete mesh;
}
TEST(MeshLoader, BuiltinSphereUsesFrontFacingWindingForOutwardNormals) {
LoadResult result = CreateBuiltinMeshResource(GetBuiltinPrimitiveMeshPath(BuiltinPrimitiveType::Sphere));
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
auto* mesh = static_cast<Mesh*>(result.resource);
const auto* vertices = static_cast<const StaticMeshVertex*>(mesh->GetVertexData());
ASSERT_NE(vertices, nullptr);
ASSERT_GE(mesh->GetIndexCount(), 3u);
bool foundNonDegenerateTriangle = false;
for (XCEngine::Core::uint32 index = 0; index + 2 < mesh->GetIndexCount(); index += 3) {
const XCEngine::Core::uint32 i0 = ReadMeshIndex(*mesh, index + 0);
const XCEngine::Core::uint32 i1 = ReadMeshIndex(*mesh, index + 1);
const XCEngine::Core::uint32 i2 = ReadMeshIndex(*mesh, index + 2);
const XCEngine::Math::Vector3 edge01 = vertices[i1].position - vertices[i0].position;
const XCEngine::Math::Vector3 edge02 = vertices[i2].position - vertices[i0].position;
const XCEngine::Math::Vector3 geometricNormal =
XCEngine::Math::Vector3::Cross(edge01, edge02);
if (geometricNormal.SqrMagnitude() <= XCEngine::Math::EPSILON) {
continue;
}
const XCEngine::Math::Vector3 averagedVertexNormal =
(vertices[i0].normal + vertices[i1].normal + vertices[i2].normal).Normalized();
EXPECT_LT(XCEngine::Math::Vector3::Dot(geometricNormal, averagedVertexNormal), 0.0f);
foundNonDegenerateTriangle = true;
break;
}
EXPECT_TRUE(foundNonDegenerateTriangle);
delete mesh;
}
TEST(MeshLoader, GeneratesNormalsAndTangentsWhenRequested) {
MeshLoader loader;
MeshImportSettings settings;
@@ -229,10 +183,15 @@ TEST(MeshLoader, ImportsMaterialTexturesFromObj) {
Material* material = mesh->GetMaterial(mesh->GetSections()[0].materialID);
ASSERT_NE(material, nullptr);
EXPECT_TRUE(material->HasProperty("baseColorTexture"));
ASSERT_NE(material->GetShader(), nullptr);
EXPECT_EQ(material->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_TRUE(material->HasProperty("_BaseColor"));
EXPECT_TRUE(material->HasProperty("_MainTex"));
EXPECT_FALSE(material->HasProperty("baseColorTexture"));
EXPECT_EQ(material->GetTextureBindingCount(), 1u);
EXPECT_EQ(material->GetTextureBindingName(0), "_MainTex");
ResourceHandle<Texture> diffuseTexture = material->GetTexture("baseColorTexture");
ResourceHandle<Texture> diffuseTexture = material->GetTexture("_MainTex");
ASSERT_TRUE(diffuseTexture.IsValid());
EXPECT_EQ(diffuseTexture->GetWidth(), 2u);
EXPECT_EQ(diffuseTexture->GetHeight(), 2u);
@@ -276,8 +235,10 @@ TEST(MeshLoader, AssetDatabaseCreatesModelArtifactAndReusesItWithoutReimport) {
Material* sourceSectionMaterial = GetFirstSectionMaterial(*sourceMesh);
ASSERT_NE(sourceSectionMaterial, nullptr);
const XCEngine::Core::uint32 sourceMaterialIndex = GetFirstSectionMaterialIndex(*sourceMesh);
ASSERT_NE(sourceSectionMaterial->GetShader(), nullptr);
EXPECT_EQ(sourceSectionMaterial->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_EQ(sourceSectionMaterial->GetTextureBindingCount(), 1u);
EXPECT_EQ(sourceSectionMaterial->GetTextureBindingName(0), "baseColorTexture");
EXPECT_EQ(sourceSectionMaterial->GetTextureBindingName(0), "_MainTex");
EXPECT_FALSE(sourceSectionMaterial->GetTextureBindingPath(0).Empty());
delete sourceMesh;
@@ -304,14 +265,16 @@ TEST(MeshLoader, AssetDatabaseCreatesModelArtifactAndReusesItWithoutReimport) {
ASSERT_NE(materialArtifactResult.resource, nullptr);
auto* artifactMaterial = static_cast<Material*>(materialArtifactResult.resource);
ASSERT_NE(artifactMaterial, nullptr);
ASSERT_NE(artifactMaterial->GetShader(), nullptr);
EXPECT_EQ(artifactMaterial->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_EQ(artifactMaterial->GetTextureBindingCount(), 1u);
EXPECT_EQ(artifactMaterial->GetTextureBindingName(0), "baseColorTexture");
EXPECT_EQ(artifactMaterial->GetTextureBindingName(0), "_MainTex");
EXPECT_FALSE(artifactMaterial->GetTextureBindingPath(0).Empty());
const ResourceHandle<Texture> artifactLazyTexture = artifactMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> artifactLazyTexture = artifactMaterial->GetTexture("_MainTex");
EXPECT_FALSE(artifactLazyTexture.IsValid());
EXPECT_GT(manager.GetAsyncPendingCount(), 0u);
ASSERT_TRUE(PumpAsyncLoadsUntilIdle(manager));
const ResourceHandle<Texture> artifactResolvedTexture = artifactMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> artifactResolvedTexture = artifactMaterial->GetTexture("_MainTex");
ASSERT_TRUE(artifactResolvedTexture.IsValid());
EXPECT_EQ(artifactResolvedTexture->GetWidth(), 2u);
EXPECT_EQ(artifactResolvedTexture->GetHeight(), 2u);
@@ -326,15 +289,17 @@ TEST(MeshLoader, AssetDatabaseCreatesModelArtifactAndReusesItWithoutReimport) {
ASSERT_GE(artifactMesh->GetMaterials().Size(), 1u);
Material* artifactSectionMaterial = GetFirstSectionMaterial(*artifactMesh);
ASSERT_NE(artifactSectionMaterial, nullptr);
ASSERT_NE(artifactSectionMaterial->GetShader(), nullptr);
EXPECT_EQ(artifactSectionMaterial->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_EQ(artifactSectionMaterial->GetTextureBindingCount(), 1u);
EXPECT_EQ(artifactSectionMaterial->GetTextureBindingName(0), "baseColorTexture");
EXPECT_EQ(artifactSectionMaterial->GetTextureBindingName(0), "_MainTex");
EXPECT_FALSE(artifactSectionMaterial->GetTextureBindingPath(0).Empty());
const ResourceHandle<Texture> artifactMeshLazyTexture = artifactSectionMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> artifactMeshLazyTexture = artifactSectionMaterial->GetTexture("_MainTex");
EXPECT_FALSE(artifactMeshLazyTexture.IsValid());
EXPECT_GT(manager.GetAsyncPendingCount(), 0u);
ASSERT_TRUE(PumpAsyncLoadsUntilIdle(manager));
const ResourceHandle<Texture> artifactMeshResolvedTexture =
artifactSectionMaterial->GetTexture("baseColorTexture");
artifactSectionMaterial->GetTexture("_MainTex");
ASSERT_TRUE(artifactMeshResolvedTexture.IsValid());
EXPECT_EQ(artifactMeshResolvedTexture->GetWidth(), 2u);
EXPECT_EQ(artifactMeshResolvedTexture->GetHeight(), 2u);
@@ -449,14 +414,16 @@ TEST(MeshLoader, ResourceManagerLoadsModelByAssetRefFromProjectAssets) {
EXPECT_LT(firstSectionMaterialIndex, initialMaterialCount);
Material* firstMaterial = GetFirstSectionMaterial(*firstHandle.Get());
ASSERT_NE(firstMaterial, nullptr);
ASSERT_NE(firstMaterial->GetShader(), nullptr);
EXPECT_EQ(firstMaterial->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_EQ(firstMaterial->GetTextureBindingCount(), 1u);
EXPECT_EQ(firstMaterial->GetTextureBindingName(0), "baseColorTexture");
EXPECT_EQ(firstMaterial->GetTextureBindingName(0), "_MainTex");
EXPECT_FALSE(firstMaterial->GetTextureBindingPath(0).Empty());
const ResourceHandle<Texture> firstLazyTexture = firstMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> firstLazyTexture = firstMaterial->GetTexture("_MainTex");
EXPECT_FALSE(firstLazyTexture.IsValid());
EXPECT_GT(manager.GetAsyncPendingCount(), 0u);
ASSERT_TRUE(PumpAsyncLoadsUntilIdle(manager));
const ResourceHandle<Texture> firstResolvedTexture = firstMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> firstResolvedTexture = firstMaterial->GetTexture("_MainTex");
ASSERT_TRUE(firstResolvedTexture.IsValid());
EXPECT_EQ(firstResolvedTexture->GetWidth(), 2u);
EXPECT_EQ(firstResolvedTexture->GetHeight(), 2u);
@@ -477,14 +444,16 @@ TEST(MeshLoader, ResourceManagerLoadsModelByAssetRefFromProjectAssets) {
EXPECT_EQ(GetFirstSectionMaterialIndex(*secondHandle.Get()), firstSectionMaterialIndex);
Material* secondMaterial = GetFirstSectionMaterial(*secondHandle.Get());
ASSERT_NE(secondMaterial, nullptr);
ASSERT_NE(secondMaterial->GetShader(), nullptr);
EXPECT_EQ(secondMaterial->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_EQ(secondMaterial->GetTextureBindingCount(), 1u);
EXPECT_EQ(secondMaterial->GetTextureBindingName(0), "baseColorTexture");
EXPECT_EQ(secondMaterial->GetTextureBindingName(0), "_MainTex");
EXPECT_FALSE(secondMaterial->GetTextureBindingPath(0).Empty());
const ResourceHandle<Texture> secondLazyTexture = secondMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> secondLazyTexture = secondMaterial->GetTexture("_MainTex");
EXPECT_FALSE(secondLazyTexture.IsValid());
EXPECT_GT(manager.GetAsyncPendingCount(), 0u);
ASSERT_TRUE(PumpAsyncLoadsUntilIdle(manager));
const ResourceHandle<Texture> secondResolvedTexture = secondMaterial->GetTexture("baseColorTexture");
const ResourceHandle<Texture> secondResolvedTexture = secondMaterial->GetTexture("_MainTex");
ASSERT_TRUE(secondResolvedTexture.IsValid());
EXPECT_EQ(secondResolvedTexture->GetWidth(), 2u);
EXPECT_EQ(secondResolvedTexture->GetHeight(), 2u);