rendering: formalize legacy shader pass fallback

This commit is contained in:
2026-04-06 18:24:10 +08:00
parent 97e986b52c
commit 7acc397714
5 changed files with 136 additions and 40 deletions

View File

@@ -79,6 +79,16 @@ inline bool ShaderPassHasExplicitBuiltinMetadata(const Resources::ShaderPass& sh
return false;
}
inline bool ShaderHasExplicitBuiltinMetadata(const Resources::Shader& shader) {
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
if (ShaderPassHasExplicitBuiltinMetadata(shaderPass)) {
return true;
}
}
return false;
}
inline bool ShaderPassMatchesBuiltinPass(
const Resources::ShaderPass& shaderPass,
BuiltinMaterialPass pass) {

View File

@@ -409,43 +409,72 @@ inline bool IsTransparentRenderQueue(Core::int32 renderQueue) {
return renderQueue >= static_cast<Core::int32>(Resources::MaterialRenderQueue::Transparent);
}
inline bool MatchesBuiltinPass(const Resources::Material* material, BuiltinMaterialPass pass) {
inline bool HasLegacyMaterialBuiltinPassHints(const Resources::Material* material) {
if (material == nullptr) {
return pass == BuiltinMaterialPass::ForwardLit;
return false;
}
return !NormalizeBuiltinPassMetadataValue(material->GetShaderPass()).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->GetShaderPass();
const Containers::String lightMode = material->GetTag("LightMode");
const bool hasMaterialShaderPass = !NormalizeBuiltinPassMetadataValue(shaderPass).Empty();
const bool hasMaterialLightMode = !NormalizeBuiltinPassMetadataValue(lightMode).Empty();
if (hasMaterialShaderPass || hasMaterialLightMode) {
if (hasMaterialShaderPass &&
!MatchesBuiltinPassName(shaderPass, pass)) {
return false;
}
if (hasMaterialLightMode &&
!MatchesBuiltinPassName(lightMode, pass)) {
return false;
}
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;
}
const Resources::Shader* shader = material->GetShader();
if (shader != nullptr) {
bool shaderHasExplicitBuiltinMetadata = false;
for (const Resources::ShaderPass& shaderPassEntry : shader->GetPasses()) {
if (ShaderPassMatchesBuiltinPass(shaderPassEntry, pass)) {
return true;
}
if (ShaderPassHasExplicitBuiltinMetadata(shaderPassEntry)) {
shaderHasExplicitBuiltinMetadata = true;
}
}
}
if (shaderHasExplicitBuiltinMetadata) {
return false;
}
if (!CanUseLegacyMaterialPassFallback(material)) {
return false;
}
if (HasLegacyMaterialBuiltinPassHints(material)) {
return LegacyMaterialBuiltinPassHintsMatch(material, pass);
}
return pass == BuiltinMaterialPass::ForwardLit;