rendering: formalize legacy material shader pass hints
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <XCEngine/Rendering/Builtin/BuiltinPassMetadataUtils.h>
|
||||
#include <XCEngine/Rendering/FrameData/VisibleRenderItem.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -430,10 +431,87 @@ inline const Resources::Material* ResolveMaterial(const VisibleRenderItem& visib
|
||||
return ResolveMaterial(visibleItem.meshRenderer, visibleItem.mesh, visibleItem.materialIndex);
|
||||
}
|
||||
|
||||
inline bool TryResolveRenderQueueTagValue(
|
||||
const Containers::String& queueValue,
|
||||
Core::int32& outRenderQueue) {
|
||||
const Containers::String normalized = NormalizeBuiltinPassMetadataValue(queueValue);
|
||||
if (normalized.Empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (normalized == Containers::String("background")) {
|
||||
outRenderQueue = static_cast<Core::int32>(Resources::MaterialRenderQueue::Background);
|
||||
return true;
|
||||
}
|
||||
if (normalized == Containers::String("geometry")) {
|
||||
outRenderQueue = static_cast<Core::int32>(Resources::MaterialRenderQueue::Geometry);
|
||||
return true;
|
||||
}
|
||||
if (normalized == Containers::String("alphatest")) {
|
||||
outRenderQueue = static_cast<Core::int32>(Resources::MaterialRenderQueue::AlphaTest);
|
||||
return true;
|
||||
}
|
||||
if (normalized == Containers::String("transparent")) {
|
||||
outRenderQueue = static_cast<Core::int32>(Resources::MaterialRenderQueue::Transparent);
|
||||
return true;
|
||||
}
|
||||
if (normalized == Containers::String("overlay")) {
|
||||
outRenderQueue = static_cast<Core::int32>(Resources::MaterialRenderQueue::Overlay);
|
||||
return true;
|
||||
}
|
||||
|
||||
char* end = nullptr;
|
||||
const long parsedValue = std::strtol(normalized.CStr(), &end, 10);
|
||||
if (end != nullptr && *end == '\0') {
|
||||
outRenderQueue = static_cast<Core::int32>(parsedValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryResolveShaderPassRenderQueue(const Resources::ShaderPass& shaderPass, Core::int32& outRenderQueue) {
|
||||
for (const Resources::ShaderPassTagEntry& tag : shaderPass.tags) {
|
||||
if (NormalizeBuiltinPassMetadataValue(tag.name) == Containers::String("queue") &&
|
||||
TryResolveRenderQueueTagValue(tag.value, outRenderQueue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline Core::int32 ResolveMaterialRenderQueue(const Resources::Material* material) {
|
||||
return material != nullptr
|
||||
? material->GetRenderQueue()
|
||||
: static_cast<Core::int32>(Resources::MaterialRenderQueue::Geometry);
|
||||
const Core::int32 defaultQueue = static_cast<Core::int32>(Resources::MaterialRenderQueue::Geometry);
|
||||
if (material == nullptr) {
|
||||
return defaultQueue;
|
||||
}
|
||||
|
||||
const Core::int32 materialQueue = material->GetRenderQueue();
|
||||
if (materialQueue != defaultQueue) {
|
||||
return materialQueue;
|
||||
}
|
||||
|
||||
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)) {
|
||||
return shaderQueue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return materialQueue;
|
||||
}
|
||||
|
||||
inline bool IsTransparentRenderQueue(Core::int32 renderQueue) {
|
||||
@@ -445,7 +523,7 @@ inline bool HasLegacyMaterialBuiltinPassHints(const Resources::Material* materia
|
||||
return false;
|
||||
}
|
||||
|
||||
return !NormalizeBuiltinPassMetadataValue(material->GetShaderPass()).Empty() ||
|
||||
return !NormalizeBuiltinPassMetadataValue(material->GetLegacyShaderPassHint()).Empty() ||
|
||||
!NormalizeBuiltinPassMetadataValue(material->GetTag("LightMode")).Empty();
|
||||
}
|
||||
|
||||
@@ -456,7 +534,7 @@ inline bool LegacyMaterialBuiltinPassHintsMatch(
|
||||
return false;
|
||||
}
|
||||
|
||||
const Containers::String shaderPass = material->GetShaderPass();
|
||||
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();
|
||||
|
||||
@@ -102,8 +102,15 @@ public:
|
||||
bool HasRenderStateOverride() const { return m_hasRenderStateOverride; }
|
||||
void SetRenderStateOverrideEnabled(bool enabled);
|
||||
|
||||
// Legacy-only compatibility hint for older material assets that still
|
||||
// select a builtin pass by serialized name.
|
||||
void SetLegacyShaderPassHint(const Containers::String& shaderPass);
|
||||
const Containers::String& GetLegacyShaderPassHint() const { return m_legacyShaderPassHint; }
|
||||
bool HasLegacyShaderPassHint() const { return !m_legacyShaderPassHint.Empty(); }
|
||||
void ClearLegacyShaderPassHint();
|
||||
|
||||
void SetShaderPass(const Containers::String& shaderPass);
|
||||
const Containers::String& GetShaderPass() const { return m_shaderPass; }
|
||||
const Containers::String& GetShaderPass() const { return GetLegacyShaderPassHint(); }
|
||||
|
||||
void SetTag(const Containers::String& name, const Containers::String& value);
|
||||
Containers::String GetTag(const Containers::String& name) const;
|
||||
@@ -179,7 +186,7 @@ private:
|
||||
Core::int32 m_renderQueue = static_cast<Core::int32>(MaterialRenderQueue::Geometry);
|
||||
MaterialRenderState m_renderState;
|
||||
bool m_hasRenderStateOverride = false;
|
||||
Containers::String m_shaderPass;
|
||||
Containers::String m_legacyShaderPassHint;
|
||||
Containers::Array<MaterialTagEntry> m_tags;
|
||||
ShaderKeywordSet m_keywordSet;
|
||||
Containers::HashMap<Containers::String, MaterialProperty> m_properties;
|
||||
|
||||
Reference in New Issue
Block a user