rendering: formalize legacy material shader pass hints
This commit is contained in:
@@ -54,7 +54,7 @@ Mesh* CreateSectionedTestMesh(const char* path, std::initializer_list<uint32_t>
|
||||
return mesh;
|
||||
}
|
||||
|
||||
Material* CreateTestMaterial(const char* path, int32_t renderQueue, const char* shaderPass = nullptr, const char* lightMode = nullptr) {
|
||||
Material* CreateTestMaterial(const char* path, int32_t renderQueue, const char* legacyShaderPassHint = nullptr, const char* lightMode = nullptr) {
|
||||
auto* material = new Material();
|
||||
IResource::ConstructParams params = {};
|
||||
params.name = "TestMaterial";
|
||||
@@ -62,8 +62,8 @@ Material* CreateTestMaterial(const char* path, int32_t renderQueue, const char*
|
||||
params.guid = ResourceGUID::Generate(path);
|
||||
material->Initialize(params);
|
||||
material->SetRenderQueue(renderQueue);
|
||||
if (shaderPass != nullptr) {
|
||||
material->SetShaderPass(shaderPass);
|
||||
if (legacyShaderPassHint != nullptr) {
|
||||
material->SetLegacyShaderPassHint(legacyShaderPassHint);
|
||||
}
|
||||
if (lightMode != nullptr) {
|
||||
material->SetTag("LightMode", lightMode);
|
||||
@@ -461,7 +461,7 @@ TEST(RenderSceneExtractor_Test, FallsBackToEmbeddedMeshMaterialsWhenRendererHasN
|
||||
|
||||
TEST(RenderMaterialUtility_Test, LegacyMaterialPassHintsCanDriveBuiltinPassMatching) {
|
||||
Material forwardMaterial;
|
||||
forwardMaterial.SetShaderPass("ForwardLit");
|
||||
forwardMaterial.SetLegacyShaderPassHint("ForwardLit");
|
||||
forwardMaterial.SetTag("LightMode", "ForwardBase");
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&forwardMaterial, BuiltinMaterialPass::ForwardLit));
|
||||
|
||||
@@ -469,7 +469,7 @@ TEST(RenderMaterialUtility_Test, LegacyMaterialPassHintsCanDriveBuiltinPassMatch
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&noMetadataMaterial, BuiltinMaterialPass::ForwardLit));
|
||||
|
||||
Material shadowMaterial;
|
||||
shadowMaterial.SetShaderPass("ShadowCaster");
|
||||
shadowMaterial.SetLegacyShaderPassHint("ShadowCaster");
|
||||
EXPECT_FALSE(MatchesBuiltinPass(&shadowMaterial, BuiltinMaterialPass::ForwardLit));
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&shadowMaterial, BuiltinMaterialPass::ShadowCaster));
|
||||
|
||||
@@ -480,7 +480,7 @@ TEST(RenderMaterialUtility_Test, LegacyMaterialPassHintsCanDriveBuiltinPassMatch
|
||||
|
||||
TEST(RenderMaterialUtility_Test, LegacyMaterialPassHintsSupportUnlitDepthAndObjectId) {
|
||||
Material unlitMaterial;
|
||||
unlitMaterial.SetShaderPass("Unlit");
|
||||
unlitMaterial.SetLegacyShaderPassHint("Unlit");
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&unlitMaterial, BuiltinMaterialPass::Unlit));
|
||||
EXPECT_FALSE(MatchesBuiltinPass(&unlitMaterial, BuiltinMaterialPass::ForwardLit));
|
||||
|
||||
@@ -490,7 +490,7 @@ TEST(RenderMaterialUtility_Test, LegacyMaterialPassHintsSupportUnlitDepthAndObje
|
||||
EXPECT_FALSE(MatchesBuiltinPass(&depthMaterial, BuiltinMaterialPass::Unlit));
|
||||
|
||||
Material objectIdMaterial;
|
||||
objectIdMaterial.SetShaderPass("ObjectId");
|
||||
objectIdMaterial.SetLegacyShaderPassHint("ObjectId");
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&objectIdMaterial, BuiltinMaterialPass::ObjectId));
|
||||
EXPECT_FALSE(MatchesBuiltinPass(&objectIdMaterial, BuiltinMaterialPass::ForwardLit));
|
||||
}
|
||||
@@ -534,7 +534,7 @@ TEST(RenderMaterialUtility_Test, ShaderMetadataOverridesConflictingLegacyMateria
|
||||
shader->AddPass(forwardPass);
|
||||
|
||||
material.SetShader(ResourceHandle<Shader>(shader));
|
||||
material.SetShaderPass("ShadowCaster");
|
||||
material.SetLegacyShaderPassHint("ShadowCaster");
|
||||
material.SetTag("LightMode", "DepthOnly");
|
||||
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&material, BuiltinMaterialPass::ForwardLit));
|
||||
@@ -551,7 +551,7 @@ TEST(RenderMaterialUtility_Test, LegacyMaterialPassHintsRemainAvailableForShader
|
||||
shader->AddPass(defaultPass);
|
||||
|
||||
material.SetShader(ResourceHandle<Shader>(shader));
|
||||
material.SetShaderPass("ShadowCaster");
|
||||
material.SetLegacyShaderPassHint("ShadowCaster");
|
||||
|
||||
EXPECT_FALSE(MatchesBuiltinPass(&material, BuiltinMaterialPass::ForwardLit));
|
||||
EXPECT_TRUE(MatchesBuiltinPass(&material, BuiltinMaterialPass::ShadowCaster));
|
||||
@@ -734,9 +734,10 @@ TEST(RenderMaterialUtility_Test, MapsMaterialRenderStateToRhiDescriptors) {
|
||||
renderState.depthFunc = MaterialComparisonFunc::LessEqual;
|
||||
material.SetRenderState(renderState);
|
||||
|
||||
const XCEngine::RHI::RasterizerDesc rasterizerState = BuildRasterizerState(&material);
|
||||
const XCEngine::RHI::BlendDesc blendState = BuildBlendState(&material);
|
||||
const XCEngine::RHI::DepthStencilStateDesc depthStencilState = BuildDepthStencilState(&material);
|
||||
const MaterialRenderState effectiveRenderState = ResolveEffectiveRenderState(nullptr, &material);
|
||||
const XCEngine::RHI::RasterizerDesc rasterizerState = BuildRasterizerState(effectiveRenderState);
|
||||
const XCEngine::RHI::BlendDesc blendState = BuildBlendState(effectiveRenderState);
|
||||
const XCEngine::RHI::DepthStencilStateDesc depthStencilState = BuildDepthStencilState(effectiveRenderState);
|
||||
|
||||
EXPECT_EQ(rasterizerState.cullMode, static_cast<uint32_t>(XCEngine::RHI::CullMode::Back));
|
||||
EXPECT_EQ(rasterizerState.frontFace, static_cast<uint32_t>(XCEngine::RHI::FrontFace::CounterClockwise));
|
||||
@@ -755,4 +756,45 @@ TEST(RenderMaterialUtility_Test, MapsMaterialRenderStateToRhiDescriptors) {
|
||||
EXPECT_EQ(depthStencilState.depthFunc, static_cast<uint32_t>(XCEngine::RHI::ComparisonFunc::LessEqual));
|
||||
}
|
||||
|
||||
TEST(RenderMaterialUtility_Test, ShaderPassFixedFunctionStateIsUsedBeforeLegacyMaterialOverride) {
|
||||
ShaderPass shaderPass = {};
|
||||
shaderPass.name = "ForwardLit";
|
||||
shaderPass.hasFixedFunctionState = true;
|
||||
shaderPass.fixedFunctionState.cullMode = MaterialCullMode::Back;
|
||||
shaderPass.fixedFunctionState.blendEnable = true;
|
||||
shaderPass.fixedFunctionState.srcBlend = MaterialBlendFactor::SrcAlpha;
|
||||
shaderPass.fixedFunctionState.dstBlend = MaterialBlendFactor::InvSrcAlpha;
|
||||
shaderPass.fixedFunctionState.srcBlendAlpha = MaterialBlendFactor::SrcAlpha;
|
||||
shaderPass.fixedFunctionState.dstBlendAlpha = MaterialBlendFactor::InvSrcAlpha;
|
||||
shaderPass.fixedFunctionState.depthWriteEnable = false;
|
||||
shaderPass.fixedFunctionState.depthFunc = MaterialComparisonFunc::LessEqual;
|
||||
|
||||
Material material;
|
||||
MaterialRenderState effectiveState = ResolveEffectiveRenderState(&shaderPass, &material);
|
||||
EXPECT_EQ(effectiveState.cullMode, MaterialCullMode::Back);
|
||||
EXPECT_TRUE(effectiveState.blendEnable);
|
||||
EXPECT_FALSE(effectiveState.depthWriteEnable);
|
||||
EXPECT_EQ(effectiveState.depthFunc, MaterialComparisonFunc::LessEqual);
|
||||
|
||||
MaterialRenderState legacyOverride = {};
|
||||
legacyOverride.cullMode = MaterialCullMode::Front;
|
||||
legacyOverride.depthWriteEnable = true;
|
||||
material.SetRenderState(legacyOverride);
|
||||
|
||||
effectiveState = ResolveEffectiveRenderState(&shaderPass, &material);
|
||||
EXPECT_EQ(effectiveState.cullMode, MaterialCullMode::Front);
|
||||
EXPECT_FALSE(effectiveState.blendEnable);
|
||||
EXPECT_TRUE(effectiveState.depthWriteEnable);
|
||||
EXPECT_EQ(effectiveState.depthFunc, MaterialComparisonFunc::Less);
|
||||
}
|
||||
|
||||
TEST(RenderMaterialUtility_Test, ShaderPassQueueTagResolvesUnityStyleRenderQueue) {
|
||||
ShaderPass shaderPass = {};
|
||||
shaderPass.tags.PushBack({ "Queue", "Transparent" });
|
||||
|
||||
int32 renderQueue = 0;
|
||||
EXPECT_TRUE(TryResolveShaderPassRenderQueue(shaderPass, renderQueue));
|
||||
EXPECT_EQ(renderQueue, static_cast<int32>(MaterialRenderQueue::Transparent));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user