Complete material inspector keyword and reset flow

This commit is contained in:
2026-04-08 01:01:28 +08:00
parent b5bc9d41cb
commit 077a6b0a51
4 changed files with 213 additions and 49 deletions

View File

@@ -423,6 +423,52 @@ std::vector<MaterialPropertyState> BuildShaderDefaultPropertyStates(
return CollectMaterialPropertyStates(scratchMaterial);
}
std::vector<MaterialKeywordState> BuildShaderKeywordStates(
const ::XCEngine::Resources::ResourceHandle<::XCEngine::Resources::Shader>& shaderHandle,
const std::vector<MaterialKeywordState>& previousKeywords) {
if (!shaderHandle.IsValid() || shaderHandle.Get() == nullptr) {
return {};
}
std::unordered_map<std::string, MaterialKeywordState> previousKeywordStates;
previousKeywordStates.reserve(previousKeywords.size());
for (const MaterialKeywordState& keyword : previousKeywords) {
const std::string keywordValue = TrimCopy(keyword.value);
if (!keywordValue.empty()) {
previousKeywordStates.emplace(keywordValue, keyword);
}
}
std::vector<MaterialKeywordState> keywordStates;
std::unordered_set<std::string> seenKeywords;
for (const ::XCEngine::Resources::ShaderPass& pass : shaderHandle->GetPasses()) {
for (const ::XCEngine::Resources::ShaderKeywordDeclaration& declaration : pass.keywordDeclarations) {
for (const Containers::String& option : declaration.options) {
const Containers::String normalizedKeyword =
::XCEngine::Resources::NormalizeShaderKeywordToken(option);
if (normalizedKeyword.Empty()) {
continue;
}
const std::string keywordValue(normalizedKeyword.CStr());
if (!seenKeywords.insert(keywordValue).second) {
continue;
}
MaterialKeywordState state;
state.value = keywordValue;
const auto previousKeywordIt = previousKeywordStates.find(keywordValue);
if (previousKeywordIt != previousKeywordStates.end()) {
state.serialized = previousKeywordIt->second.serialized;
}
keywordStates.push_back(std::move(state));
}
}
}
return keywordStates;
}
constexpr int kCustomRenderQueuePresetIndex = 5;
int ResolveRenderQueuePresetIndex(int renderQueue) {
@@ -652,16 +698,40 @@ void SyncMaterialAssetStateWithShader(
CopyMaterialPropertyValue(previousPropertyIt->second, property);
}
state.properties = std::move(nextProperties);
state.keywords = BuildShaderKeywordStates(shaderHandle, state.keywords);
}
std::vector<MaterialKeywordState> nextKeywords;
nextKeywords.reserve(state.keywords.size());
for (const MaterialKeywordState& keyword : state.keywords) {
const std::string keywordValue = TrimCopy(keyword.value);
if (!keywordValue.empty() && shaderHandle->DeclaresKeyword(keywordValue.c_str())) {
nextKeywords.push_back(keyword);
bool ResetMaterialPropertyStateToShaderDefault(
const ::XCEngine::Resources::ResourceHandle<::XCEngine::Resources::Shader>& shaderHandle,
const std::string& propertyName,
MaterialAssetState& state) {
if (!shaderHandle.IsValid() || shaderHandle.Get() == nullptr || propertyName.empty()) {
return false;
}
MaterialPropertyState* stateProperty = nullptr;
for (MaterialPropertyState& property : state.properties) {
if (property.name == propertyName) {
stateProperty = &property;
break;
}
}
state.keywords = std::move(nextKeywords);
if (stateProperty == nullptr) {
return false;
}
const std::vector<MaterialPropertyState> defaultProperties = BuildShaderDefaultPropertyStates(shaderHandle);
for (const MaterialPropertyState& defaultProperty : defaultProperties) {
if (defaultProperty.name != propertyName || defaultProperty.type != stateProperty->type) {
continue;
}
CopyMaterialPropertyValue(defaultProperty, *stateProperty);
stateProperty->serialized = false;
return true;
}
return false;
}
void ApplyMaterialAuthoringPresenceToState(