From e06b8782cc9781660dda860daef76bdf546fe10a Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 21 Jan 2022 15:55:37 -0800 Subject: [PATCH 01/24] Add AZ::Dom::Patch, a Generic DOM analog to JSON patch - Currently supports JSON patch operations (add/remove/replace/copy/move/test) - `GenerateHierarchicalDeltaPatch` provides a patch generation mechanism that produces forward and inverse patches - Patch application comes with a `PatchApplicationStrategy` functor that allows customizing behavior for patch failure that may be useful for the prefab system - Serialization to/from JSON patch by way of `AZ::Dom::Value` is supported Benchmarks provided, split into three categories on the Dom value benchmark payload (payloads with up to 10k entries populated with strings up to 100 characters in length): - Patch generation based on a deep copy of the affected data ``` DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_DeepCopy/10/5 0.024 ms 0.024 ms 29867 items_per_second=41.5541k/s DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_DeepCopy/10/500 0.024 ms 0.024 ms 29867 items_per_second=41.5541k/s DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_DeepCopy/100/5 0.346 ms 0.345 ms 2036 items_per_second=2.89564k/s DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_DeepCopy/100/500 0.375 ms 0.377 ms 1867 items_per_second=2.65529k/s DomPatchBenchmark/AzDomPatch_Generate_TopLevelReplace/10/5 0.003 ms 0.003 ms 203636 items_per_second=289.616k/s DomPatchBenchmark/AzDomPatch_Generate_TopLevelReplace/10/500 0.004 ms 0.004 ms 194783 items_per_second=283.321k/s DomPatchBenchmark/AzDomPatch_Generate_TopLevelReplace/100/5 0.003 ms 0.003 ms 203636 items_per_second=289.616k/s DomPatchBenchmark/AzDomPatch_Generate_TopLevelReplace/100/500 0.004 ms 0.004 ms 194783 items_per_second=271.002k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_DeepCopy/10/5 0.023 ms 0.024 ms 29867 items_per_second=42.4775k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_DeepCopy/10/500 0.023 ms 0.023 ms 28000 items_per_second=42.6667k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_DeepCopy/100/5 0.341 ms 0.337 ms 2133 items_per_second=2.96765k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_DeepCopy/100/500 0.365 ms 0.361 ms 1948 items_per_second=2.77049k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_DeepCopy/10/5 0.023 ms 0.023 ms 29867 items_per_second=43.4429k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_DeepCopy/10/500 0.023 ms 0.024 ms 29867 items_per_second=42.4775k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_DeepCopy/100/5 0.330 ms 0.330 ms 2133 items_per_second=3.0336k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_DeepCopy/100/500 0.359 ms 0.360 ms 1867 items_per_second=2.77879k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_DeepCopy/10/5 0.023 ms 0.022 ms 29867 items_per_second=44.4532k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_DeepCopy/10/500 0.023 ms 0.023 ms 32000 items_per_second=43.5745k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_DeepCopy/100/5 0.329 ms 0.330 ms 2133 items_per_second=3.0336k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_DeepCopy/100/500 0.357 ms 0.361 ms 1948 items_per_second=2.77049k/s ``` - Patch generation based on a shallow copy of the affected data (this is faster because when using Dom::Value to copy and mutate, we can bypass expensive array and object comparisons for identical values) ``` DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_ShallowCopy/10/5 0.010 ms 0.010 ms 74667 items_per_second=99.556k/s DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_ShallowCopy/10/500 0.010 ms 0.010 ms 74667 items_per_second=97.5242k/s DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_ShallowCopy/100/5 0.079 ms 0.078 ms 8960 items_per_second=12.7431k/s DomPatchBenchmark/AzDomPatch_Generate_SimpleReplace_ShallowCopy/100/500 0.087 ms 0.087 ms 8960 items_per_second=11.4688k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_ShallowCopy/10/5 0.009 ms 0.009 ms 74667 items_per_second=116.553k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_ShallowCopy/10/500 0.009 ms 0.009 ms 74667 items_per_second=113.778k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_ShallowCopy/100/5 0.072 ms 0.071 ms 8960 items_per_second=13.9863k/s DomPatchBenchmark/AzDomPatch_Generate_KeyRemove_ShallowCopy/100/500 0.087 ms 0.088 ms 7467 items_per_second=11.3783k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_ShallowCopy/10/5 0.014 ms 0.014 ms 49778 items_per_second=72.4044k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_ShallowCopy/10/500 0.014 ms 0.014 ms 56000 items_per_second=70.2745k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_ShallowCopy/100/5 0.118 ms 0.117 ms 5600 items_per_second=8.53333k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayAppend_ShallowCopy/100/500 0.140 ms 0.141 ms 4978 items_per_second=7.07982k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_ShallowCopy/10/5 0.009 ms 0.009 ms 89600 items_per_second=108.196k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_ShallowCopy/10/500 0.009 ms 0.009 ms 74667 items_per_second=108.607k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_ShallowCopy/100/5 0.068 ms 0.068 ms 11200 items_per_second=14.6286k/s DomPatchBenchmark/AzDomPatch_Generate_ArrayPrepend_ShallowCopy/100/500 0.082 ms 0.082 ms 8960 items_per_second=12.2009k/s ``` - Patch application ``` DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_ShallowCopy/10/5 0.001 ms 0.001 ms 560000 items_per_second=874.146k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_ShallowCopy/10/500 0.001 ms 0.001 ms 560000 items_per_second=874.146k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_ShallowCopy/100/5 0.004 ms 0.004 ms 172308 items_per_second=250.63k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_ShallowCopy/100/500 0.004 ms 0.004 ms 179200 items_per_second=260.655k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_DeepCopy/10/5 0.005 ms 0.005 ms 112000 items_per_second=193.73k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_DeepCopy/10/500 0.005 ms 0.005 ms 112000 items_per_second=193.73k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_DeepCopy/100/5 0.052 ms 0.052 ms 10000 items_per_second=19.3939k/s DomPatchBenchmark/AzDomPatch_Apply_SimpleReplace_DeepCopy/100/500 0.052 ms 0.052 ms 11200 items_per_second=19.373k/s DomPatchBenchmark/AzDomPatch_Apply_TopLevelReplace/10/5 0.001 ms 0.001 ms 640000 items_per_second=910.222k/s DomPatchBenchmark/AzDomPatch_Apply_TopLevelReplace/10/500 0.001 ms 0.001 ms 640000 items_per_second=910.222k/s DomPatchBenchmark/AzDomPatch_Apply_TopLevelReplace/100/5 0.001 ms 0.001 ms 640000 items_per_second=910.222k/s DomPatchBenchmark/AzDomPatch_Apply_TopLevelReplace/100/500 0.001 ms 0.001 ms 640000 items_per_second=910.222k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_ShallowCopy/10/5 0.001 ms 0.001 ms 560000 items_per_second=896k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_ShallowCopy/10/500 0.001 ms 0.001 ms 640000 items_per_second=871.489k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_ShallowCopy/100/5 0.004 ms 0.004 ms 160000 items_per_second=232.727k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_ShallowCopy/100/500 0.004 ms 0.004 ms 165926 items_per_second=235.984k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_DeepCopy/10/5 0.005 ms 0.005 ms 112000 items_per_second=193.73k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_DeepCopy/10/500 0.005 ms 0.005 ms 112000 items_per_second=193.73k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_DeepCopy/100/5 0.053 ms 0.053 ms 10000 items_per_second=18.8235k/s DomPatchBenchmark/AzDomPatch_Apply_KeyRemove_DeepCopy/100/500 0.051 ms 0.052 ms 10000 items_per_second=19.3939k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_ShallowCopy/10/5 0.001 ms 0.001 ms 497778 items_per_second=692.561k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_ShallowCopy/10/500 0.001 ms 0.001 ms 497778 items_per_second=692.561k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_ShallowCopy/100/5 0.006 ms 0.006 ms 112000 items_per_second=174.829k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_ShallowCopy/100/500 0.006 ms 0.006 ms 100000 items_per_second=177.778k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_DeepCopy/10/5 0.005 ms 0.005 ms 112000 items_per_second=193.73k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_DeepCopy/10/500 0.005 ms 0.005 ms 100000 items_per_second=188.235k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_DeepCopy/100/5 0.053 ms 0.052 ms 11200 items_per_second=19.373k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayAppend_DeepCopy/100/500 0.052 ms 0.053 ms 11200 items_per_second=18.8632k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_ShallowCopy/10/5 0.001 ms 0.001 ms 560000 items_per_second=874.146k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_ShallowCopy/10/500 0.001 ms 0.001 ms 560000 items_per_second=874.146k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_ShallowCopy/100/5 0.004 ms 0.004 ms 179200 items_per_second=260.655k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_ShallowCopy/100/500 0.004 ms 0.004 ms 179200 items_per_second=260.655k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_DeepCopy/10/5 0.005 ms 0.005 ms 100000 items_per_second=193.939k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_DeepCopy/10/500 0.005 ms 0.005 ms 100000 items_per_second=193.939k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_DeepCopy/100/5 0.052 ms 0.052 ms 11200 items_per_second=19.373k/s DomPatchBenchmark/AzDomPatch_Apply_ArrayPrepend_DeepCopy/100/500 0.053 ms 0.053 ms 10000 items_per_second=18.8235k/s ``` At a glance, patch generation using `GenerateHierarchicalDeltaPatch` is slower than applying its created patches, but not prohibitively so. Ideally patches shouldn't be recreated unnecessarily, but especially when diffing `Value`s that have been copied and then mutated, a generate + apply operation similar to what prefabs currently do is reasonably fast. Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp | 959 ++++++++++++++++++ Code/Framework/AzCore/AzCore/DOM/DomPatch.h | 191 ++++ Code/Framework/AzCore/AzCore/DOM/DomPath.cpp | 15 +- .../AzCore/AzCore/azcore_files.cmake | 2 + .../AzCore/Tests/DOM/DomPatchBenchmarks.cpp | 179 ++++ .../AzCore/Tests/DOM/DomPatchTests.cpp | 562 ++++++++++ .../AzCore/Tests/azcoretests_files.cmake | 2 + 7 files changed, 1904 insertions(+), 6 deletions(-) create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomPatch.h create mode 100644 Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp create mode 100644 Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp new file mode 100644 index 0000000000..963308e9c8 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp @@ -0,0 +1,959 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include + +namespace AZ::Dom +{ + PatchOperation::PatchOperation(Path destinationPath, Type type, Value value) + : m_domPath(destinationPath) + , m_type(type) + , m_value(value) + { + } + + PatchOperation::PatchOperation(Path destinationPath, Type type, Path sourcePath) + : m_domPath(destinationPath) + , m_type(type) + , m_value(sourcePath) + { + } + + PatchOperation::PatchOperation(Path destinationPath, Type type) + : m_domPath(destinationPath) + , m_type(type) + { + } + + bool PatchOperation::operator==(const PatchOperation& rhs) const + { + if (m_type != rhs.m_type) + { + return false; + } + + switch (m_type) + { + case Type::Add: + return m_domPath == rhs.m_domPath && Utils::DeepCompareIsEqual(GetValue(), rhs.GetValue()); + case Type::Remove: + return m_domPath == rhs.m_domPath; + case Type::Replace: + return m_domPath == rhs.m_domPath && Utils::DeepCompareIsEqual(GetValue(), rhs.GetValue()); + case Type::Copy: + return m_domPath == rhs.m_domPath && GetSourcePath() == rhs.GetSourcePath(); + case Type::Move: + return m_domPath == rhs.m_domPath && GetSourcePath() == rhs.GetSourcePath(); + case Type::Test: + return m_domPath == rhs.m_domPath && Utils::DeepCompareIsEqual(GetValue(), rhs.GetValue()); + default: + AZ_Assert(false, "PatchOperation::GetDomRepresentation: invalid patch type specified"); + return false; + } + } + + bool PatchOperation::operator!=(const PatchOperation& rhs) const + { + return !operator==(rhs); + } + + PatchOperation::Type PatchOperation::GetType() const + { + return m_type; + } + + void PatchOperation::SetType(Type type) + { + m_type = type; + } + + const Path& PatchOperation::GetDestinationPath() const + { + return m_domPath; + } + + void PatchOperation::SetDestinationPath(Path path) + { + m_domPath = path; + } + + const Value& PatchOperation::GetValue() const + { + return AZStd::get(m_value); + } + + void PatchOperation::SetValue(Value value) + { + m_value = AZStd::move(value); + } + + const Path& PatchOperation::GetSourcePath() const + { + return AZStd::get(m_value); + } + + void PatchOperation::SetSourcePath(Path path) + { + m_value = AZStd::move(path); + } + + AZ::Outcome PatchOperation::Apply(Value rootElement) const + { + PatchOutcome outcome = ApplyInPlace(rootElement); + if (!outcome.IsSuccess()) + { + return AZ::Failure(outcome.TakeError()); + } + return AZ::Success(AZStd::move(rootElement)); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyInPlace(Value& rootElement) const + { + switch (m_type) + { + case Type::Add: + return ApplyAdd(rootElement); + case Type::Remove: + return ApplyRemove(rootElement); + case Type::Replace: + return ApplyReplace(rootElement); + case Type::Copy: + return ApplyCopy(rootElement); + case Type::Move: + return ApplyMove(rootElement); + case Type::Test: + return ApplyTest(rootElement); + } + return AZ::Failure("Unsupported DOM patch operation specified"); + } + + Value PatchOperation::GetDomRepresentation() const + { + Value serializedPatch(Dom::Type::Object); + switch (m_type) + { + case Type::Add: + serializedPatch["op"].SetString("add"); + serializedPatch["path"].CopyFromString(GetDestinationPath().ToString()); + serializedPatch["value"] = GetValue(); + break; + case Type::Remove: + serializedPatch["op"].SetString("remove"); + serializedPatch["path"].CopyFromString(GetDestinationPath().ToString()); + break; + case Type::Replace: + serializedPatch["op"].SetString("replace"); + serializedPatch["path"].CopyFromString(GetDestinationPath().ToString()); + serializedPatch["value"] = GetValue(); + break; + case Type::Copy: + serializedPatch["op"].SetString("copy"); + serializedPatch["from"].CopyFromString(GetSourcePath().ToString()); + serializedPatch["path"].CopyFromString(GetDestinationPath().ToString()); + break; + case Type::Move: + serializedPatch["op"].SetString("move"); + serializedPatch["from"].CopyFromString(GetSourcePath().ToString()); + serializedPatch["path"].CopyFromString(GetDestinationPath().ToString()); + break; + case Type::Test: + serializedPatch["op"].SetString("test"); + serializedPatch["path"].CopyFromString(GetDestinationPath().ToString()); + serializedPatch["value"] = GetValue(); + break; + default: + AZ_Assert(false, "PatchOperation::GetDomRepresentation: invalid patch type specified"); + } + return serializedPatch; + } + + AZ::Outcome PatchOperation::CreateFromDomRepresentation(Value domValue) + { + if (!domValue.IsObject()) + { + return AZ::Failure("PatchOperation failed to load: PatchOperation must be specified as an Object"); + } + + auto loadField = [&](const char* field, AZStd::optional type = {}) -> AZ::Outcome + { + auto it = domValue.FindMember(field); + if (it == domValue.MemberEnd()) + { + return AZ::Failure(AZStd::string::format("PatchOperation failed to load: no \"%s\" specified", field)); + } + + if (type.has_value() && it->second.GetType() != type) + { + return AZ::Failure(AZStd::string::format("PatchOperation failed to load: \"%s\" is invalid", field)); + } + + return AZ::Success(it->second); + }; + + auto opLoad = loadField("op", Dom::Type::String); + if (!opLoad.IsSuccess()) + { + return AZ::Failure(opLoad.TakeError()); + } + AZStd::string_view op = opLoad.GetValue().GetString(); + if (op == "add") + { + auto pathLoad = loadField("path", Dom::Type::String); + if (!pathLoad.IsSuccess()) + { + return AZ::Failure(pathLoad.TakeError()); + } + auto valueLoad = loadField("value"); + if (!valueLoad.IsSuccess()) + { + return AZ::Failure(valueLoad.TakeError()); + } + + return AZ::Success(PatchOperation::AddOperation(Path(pathLoad.GetValue().GetString()), valueLoad.TakeValue())); + } + else if (op == "remove") + { + auto pathLoad = loadField("path", Dom::Type::String); + if (!pathLoad.IsSuccess()) + { + return AZ::Failure(pathLoad.TakeError()); + } + + return AZ::Success(PatchOperation::RemoveOperation(Path(pathLoad.GetValue().GetString()))); + } + else if (op == "replace") + { + auto pathLoad = loadField("path", Dom::Type::String); + if (!pathLoad.IsSuccess()) + { + return AZ::Failure(pathLoad.TakeError()); + } + auto valueLoad = loadField("value"); + if (!valueLoad.IsSuccess()) + { + return AZ::Failure(valueLoad.TakeError()); + } + + return AZ::Success(PatchOperation::ReplaceOperation(Path(pathLoad.GetValue().GetString()), valueLoad.TakeValue())); + } + else if (op == "copy") + { + auto destLoad = loadField("path", Dom::Type::String); + if (!destLoad.IsSuccess()) + { + return AZ::Failure(destLoad.TakeError()); + } + auto sourceLoad = loadField("from", Dom::Type::String); + if (!sourceLoad.IsSuccess()) + { + return AZ::Failure(sourceLoad.TakeError()); + } + + return AZ::Success(PatchOperation::CopyOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString()))); + } + else if (op == "move") + { + auto destLoad = loadField("path", Dom::Type::String); + if (!destLoad.IsSuccess()) + { + return AZ::Failure(destLoad.TakeError()); + } + auto sourceLoad = loadField("from", Dom::Type::String); + if (!sourceLoad.IsSuccess()) + { + return AZ::Failure(sourceLoad.TakeError()); + } + + return AZ::Success(PatchOperation::MoveOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString()))); + } + else if (op == "test") + { + auto pathLoad = loadField("path", Dom::Type::String); + if (!pathLoad.IsSuccess()) + { + return AZ::Failure(pathLoad.TakeError()); + } + auto valueLoad = loadField("value"); + if (!valueLoad.IsSuccess()) + { + return AZ::Failure(valueLoad.TakeError()); + } + + return AZ::Success(PatchOperation::TestOperation(Path(pathLoad.GetValue().GetString()), valueLoad.TakeValue())); + } + else + { + return AZ::Failure("PatchOperation failed to create DOM representation: invalid \"op\" specified"); + } + } + + AZ::Outcome PatchOperation::GetInverse(Value stateBeforeApplication) const + { + switch (m_type) + { + case Type::Add: + { + // Add -> Replace (if value already existed in an object) otherwise + // Add -> Remove + if (m_domPath.Size() > 0 && m_domPath[m_domPath.Size() - 1].IsKey()) + { + const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); + if (existingValue != nullptr) + { + return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); + } + } + return AZ::Success(PatchOperation::RemoveOperation(m_domPath)); + } + case Type::Remove: + { + // Remove -> Add + const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); + if (existingValue == nullptr) + { + return AZ::Failure( + AZStd::string::format("Unable to invert DOM remove patch, source path not found: %s", m_domPath.ToString().data())); + } + return AZ::Success(PatchOperation::AddOperation(m_domPath, *existingValue)); + } + case Type::Replace: + { + // Replace -> Replace (with old value) + const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); + if (existingValue == nullptr) + { + return AZ::Failure(AZStd::string::format( + "Unable to invert DOM replace patch, source path not found: %s", m_domPath.ToString().data())); + } + return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); + } + case Type::Copy: + { + // Copy -> Replace (with old value) + const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); + if (existingValue == nullptr) + { + return AZ::Failure( + AZStd::string::format("Unable to invert DOM copy patch, source path not found: %s", m_domPath.ToString().data())); + } + return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); + } + case Type::Move: + { + // Move -> Replace, using the common ancestor of the two paths as the replacement + // This is not a minimal inverse, which would be two replace operations at each path + const Path& destPath = m_domPath; + const Path& sourcePath = GetSourcePath(); + + Path commonAncestor; + for (size_t i = 0; i < destPath.Size() && i < sourcePath.Size(); ++i) + { + if (destPath[i] != sourcePath[i]) + { + break; + } + + commonAncestor.Push(destPath[i]); + } + + const Value* existingValue = stateBeforeApplication.FindChild(commonAncestor); + if (existingValue == nullptr) + { + return AZ::Failure(AZStd::string::format( + "Unable to invert DOM move patch, common ancestor path not found: %s", commonAncestor.ToString().data())); + } + return AZ::Success(PatchOperation::ReplaceOperation(commonAncestor, *existingValue)); + } + case Type::Test: + { + // Test -> Test (no change) + // When inverting a sequence of patches, applying them in reverse order should allow the test to continue to succeed + return AZ::Success(*this); + } + } + return AZ::Failure("Unable to invert DOM patch, unknown type specified"); + } + + AZ::Outcome PatchOperation::LookupPath( + Value& rootElement, const Path& path, AZ::u8 existenceCheckFlags) + { + const bool verifyFullPath = existenceCheckFlags & VerifyFullPath; + const bool allowEndOfArray = existenceCheckFlags & AllowEndOfArray; + + Path target = path; + if (target.Size() == 0) + { + Value wrapper(Dom::Type::Array); + wrapper.ArrayPushBack(rootElement); + return AZ::Success({ wrapper, PathEntry(0) }); + } + + if (verifyFullPath || !allowEndOfArray) + { + for (size_t i = 0; i < path.Size(); ++i) + { + const PathEntry& entry = path[i]; + if (entry.IsEndOfArray() && (!allowEndOfArray || i != path.Size() - 1)) + { + return AZ::Failure("Append to array index (\"-\") specified for path that must already exist"); + } + } + } + + PathEntry destinationIndex = target[target.Size() - 1]; + target.Pop(); + + Value* targetValue = rootElement.FindMutableChild(target); + if (targetValue == nullptr) + { + return AZ::Failure(AZStd::string::format("Path not found (%s)", target.ToString().data())); + } + + if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray()) + { + if (!targetValue->IsArray() && !targetValue->IsNode()) + { + return AZ::Failure("Array index specified for a value that is not an array or node"); + } + + if (destinationIndex.IsIndex() && destinationIndex.GetIndex() >= targetValue->ArraySize()) + { + return AZ::Failure("Array index out bounds"); + } + } + else + { + if (!targetValue->IsObject() && !targetValue->IsNode()) + { + return AZ::Failure("Key specified for a value that is not an object or node"); + } + + if (verifyFullPath) + { + if (auto it = targetValue->FindMember(destinationIndex.GetKey()); it == targetValue->MemberEnd()) + { + return AZ::Failure("Key not found in container"); + } + } + } + + return AZ::Success({ *targetValue, AZStd::move(destinationIndex) }); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyAdd(Value& rootElement) const + { + auto pathLookup = LookupPath(rootElement, m_domPath, AllowEndOfArray); + if (!pathLookup.IsSuccess()) + { + return AZ::Failure(pathLookup.TakeError()); + } + const PathContext& context = pathLookup.GetValue(); + const PathEntry& destinationIndex = context.m_key; + Value& targetValue = context.m_value; + + if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray()) + { + if (destinationIndex.IsEndOfArray()) + { + targetValue.ArrayPushBack(GetValue()); + } + else + { + const size_t index = destinationIndex.GetIndex(); + auto& arrayToChange = targetValue.GetMutableArray(); + arrayToChange.insert(arrayToChange.begin() + index, GetValue()); + } + } + else + { + targetValue[destinationIndex] = GetValue(); + } + return AZ::Success(); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyRemove(Value& rootElement) const + { + auto pathLookup = LookupPath(rootElement, m_domPath, VerifyFullPath | AllowEndOfArray); + if (!pathLookup.IsSuccess()) + { + return AZ::Failure(pathLookup.TakeError()); + } + const PathContext& context = pathLookup.GetValue(); + const PathEntry& destinationIndex = context.m_key; + Value& targetValue = context.m_value; + + if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray()) + { + size_t index = destinationIndex.IsEndOfArray() ? targetValue.ArraySize() - 1 : destinationIndex.GetIndex(); + targetValue.ArrayErase(targetValue.MutableArrayBegin() + index); + } + else + { + auto it = targetValue.FindMutableMember(destinationIndex.GetKey()); + targetValue.EraseMember(it); + } + return AZ::Success(); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyReplace(Value& rootElement) const + { + auto pathLookup = LookupPath(rootElement, m_domPath, VerifyFullPath); + if (!pathLookup.IsSuccess()) + { + return AZ::Failure(pathLookup.TakeError()); + } + + rootElement[m_domPath] = GetValue(); + return AZ::Success(); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyCopy(Value& rootElement) const + { + auto sourceLookup = LookupPath(rootElement, GetSourcePath(), VerifyFullPath); + if (!sourceLookup.IsSuccess()) + { + return AZ::Failure(sourceLookup.TakeError()); + } + + auto destLookup = LookupPath(rootElement, m_domPath, AllowEndOfArray); + if (!destLookup.IsSuccess()) + { + return AZ::Failure(destLookup.TakeError()); + } + + rootElement[m_domPath] = rootElement[GetSourcePath()]; + return AZ::Success(); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyMove(Value& rootElement) const + { + auto sourceLookup = LookupPath(rootElement, GetSourcePath(), VerifyFullPath); + if (!sourceLookup.IsSuccess()) + { + return AZ::Failure(sourceLookup.TakeError()); + } + + auto destLookup = LookupPath(rootElement, m_domPath, AllowEndOfArray); + if (!destLookup.IsSuccess()) + { + return AZ::Failure(destLookup.TakeError()); + } + + Value valueToMove = rootElement[GetSourcePath()]; + const PathContext& sourceContext = sourceLookup.GetValue(); + if (sourceContext.m_key.IsEndOfArray()) + { + sourceContext.m_value.ArrayPopBack(); + } + else if (sourceContext.m_key.IsIndex()) + { + sourceContext.m_value.ArrayErase(sourceContext.m_value.MutableArrayBegin() + sourceContext.m_key.GetIndex()); + } + else + { + sourceContext.m_value.EraseMember(sourceContext.m_key.GetKey()); + } + + rootElement[m_domPath] = AZStd::move(valueToMove); + return AZ::Success(); + } + + PatchOperation::PatchOutcome PatchOperation::ApplyTest(Value& rootElement) const + { + auto pathLookup = LookupPath(rootElement, m_domPath, VerifyFullPath); + if (!pathLookup.IsSuccess()) + { + return AZ::Failure(pathLookup.TakeError()); + } + + if (!Utils::DeepCompareIsEqual(rootElement[m_domPath], GetValue())) + { + return AZ::Failure("Test failed, values don't match"); + } + + return AZ::Success(); + } + + namespace PatchApplicationStrategy + { + void HaltOnFailure(PatchApplicationState& state) + { + if (!state.m_outcome.IsSuccess()) + { + state.m_shouldContinue = false; + } + } + + void IgnoreFailureAndContinue([[maybe_unused]] PatchApplicationState& state) + { + } + } // namespace PatchApplicationStrategy + + Patch::Patch(AZStd::initializer_list init) + : m_operations(init) + { + } + + bool Patch::operator==(const Patch& rhs) const + { + if (m_operations.size() != rhs.m_operations.size()) + { + return false; + } + + for (size_t i = 0; i < m_operations.size(); ++i) + { + if (m_operations[i] != rhs.m_operations[i]) + { + return false; + } + } + + return true; + } + + bool Patch::operator!=(const Patch& rhs) const + { + return !operator==(rhs); + } + + const Patch::OperationsContainer& Patch::GetOperations() const + { + return m_operations; + } + + void Patch::PushBack(PatchOperation op) + { + m_operations.push_back(AZStd::move(op)); + } + + void Patch::PushFront(PatchOperation op) + { + m_operations.insert(m_operations.begin(), AZStd::move(op)); + } + + void Patch::Pop() + { + m_operations.pop_back(); + } + + void Patch::Clear() + { + m_operations.clear(); + } + + const PatchOperation& Patch::At(size_t index) const + { + return m_operations[index]; + } + + size_t Patch::Size() const + { + return m_operations.size(); + } + + PatchOperation& Patch::operator[](size_t index) + { + return m_operations[index]; + } + + const PatchOperation& Patch::operator[](size_t index) const + { + return m_operations[index]; + } + + Patch::OperationsContainer::iterator Patch::begin() + { + return m_operations.begin(); + } + + Patch::OperationsContainer::iterator Patch::end() + { + return m_operations.end(); + } + + Patch::OperationsContainer::const_iterator Patch::begin() const + { + return m_operations.cbegin(); + } + + Patch::OperationsContainer::const_iterator Patch::end() const + { + return m_operations.cend(); + } + + Patch::OperationsContainer::const_iterator Patch::cbegin() const + { + return m_operations.cbegin(); + } + + Patch::OperationsContainer::const_iterator Patch::cend() const + { + return m_operations.cend(); + } + + size_t Patch::size() const + { + return m_operations.size(); + } + + AZ::Outcome Patch::Apply(Value rootElement, StrategyFunctor strategy) const + { + auto result = ApplyInPlace(rootElement, strategy); + if (!result.IsSuccess()) + { + return AZ::Failure(result.TakeError()); + } + return AZ::Success(AZStd::move(rootElement)); + } + + AZ::Outcome Patch::ApplyInPlace(Value& rootElement, StrategyFunctor strategy) const + { + PatchApplicationState state; + state.m_currentState = &rootElement; + state.m_patch = this; + + for (const PatchOperation& operation : m_operations) + { + state.m_lastOperation = &operation; + state.m_outcome = operation.ApplyInPlace(rootElement); + strategy(state); + if (!state.m_shouldContinue) + { + break; + } + } + return state.m_outcome; + } + + Value Patch::GetDomRepresentation() const + { + Value domValue(Dom::Type::Array); + for (const PatchOperation& operation : m_operations) + { + domValue.ArrayPushBack(operation.GetDomRepresentation()); + } + return domValue; + } + + AZ::Outcome Patch::CreateFromDomRepresentation(Value domValue) + { + if (!domValue.IsArray()) + { + return AZ::Failure("Patch must be an array"); + } + + Patch patch; + for (auto it = domValue.ArrayBegin(); it != domValue.ArrayEnd(); ++it) + { + auto operationLoadResult = PatchOperation::CreateFromDomRepresentation(*it); + if (!operationLoadResult.IsSuccess()) + { + return AZ::Failure(operationLoadResult.TakeError()); + } + patch.PushBack(operationLoadResult.TakeValue()); + } + return AZ::Success(AZStd::move(patch)); + } + + PatchOperation PatchOperation::AddOperation(Path destinationPath, Value value) + { + return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Add, AZStd::move(value)); + } + + PatchOperation PatchOperation::RemoveOperation(Path pathToRemove) + { + return PatchOperation(AZStd::move(pathToRemove), PatchOperation::Type::Remove); + } + + PatchOperation PatchOperation::ReplaceOperation(Path destinationPath, Value value) + { + return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Replace, AZStd::move(value)); + } + + PatchOperation PatchOperation::CopyOperation(Path destinationPath, Path sourcePath) + { + return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Copy, AZStd::move(sourcePath)); + } + + PatchOperation PatchOperation::MoveOperation(Path destinationPath, Path sourcePath) + { + return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Move, AZStd::move(sourcePath)); + } + + PatchOperation PatchOperation::TestOperation(Path testPath, Value value) + { + return PatchOperation(AZStd::move(testPath), PatchOperation::Type::Test, AZStd::move(value)); + } + + PatchInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState) + { + PatchInfo patches; + + auto AddPatch = [&patches](PatchOperation op, PatchOperation inverse) + { + patches.m_forwardPatches.PushBack(AZStd::move(op)); + patches.m_inversePatches.PushFront(AZStd::move(inverse)); + }; + + AZStd::function CompareValues; + + struct PendingComparison + { + Path m_path; + const Value& m_before; + const Value& m_after; + + PendingComparison(Path path, const Value& before, const Value& after) + : m_path(AZStd::move(path)) + , m_before(before) + , m_after(after) + { + } + }; + AZStd::queue entriesToCompare; + + AZStd::unordered_set desiredKeys; + auto CompareObjects = [&](const Path& path, const Value& before, const Value& after) + { + desiredKeys.clear(); + Path subPath = path; + for (auto it = after.MemberBegin(); it != after.MemberEnd(); ++it) + { + desiredKeys.insert(it->first.GetHash()); + subPath.Push(it->first); + auto beforeIt = before.FindMember(it->first); + if (beforeIt == before.MemberEnd()) + { + AddPatch(PatchOperation::AddOperation(subPath, it->second), PatchOperation::RemoveOperation(subPath)); + } + else + { + entriesToCompare.emplace(subPath, beforeIt->second, it->second); + } + subPath.Pop(); + } + + for (auto it = before.MemberBegin(); it != before.MemberEnd(); ++it) + { + if (!desiredKeys.contains(it->first.GetHash())) + { + subPath.Push(it->first); + AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, it->second)); + subPath.Pop(); + } + } + }; + + auto CompareArrays = [&](const Path& path, const Value& before, const Value& after) + { + const size_t beforeSize = before.ArraySize(); + const size_t afterSize = after.ArraySize(); + + // If more than replaceThreshold values differ, do a replace operation instead + constexpr size_t replaceThreshold = 3; + size_t changedValueCount = 0; + for (size_t i = 0; i < afterSize; ++i) + { + if (i < beforeSize) + { + if (before[i] != after[i]) + { + ++changedValueCount; + if (changedValueCount >= replaceThreshold) + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + return; + } + } + } + } + + Path subPath = path; + for (size_t i = 0; i < afterSize; ++i) + { + if (i >= beforeSize) + { + subPath.Push(PathEntry(PathEntry::EndOfArrayIndex)); + AddPatch(PatchOperation::AddOperation(subPath, after[i]), PatchOperation::RemoveOperation(subPath)); + subPath.Pop(); + } + else + { + subPath.Push(PathEntry(i)); + entriesToCompare.emplace(subPath, before[i], after[i]); + subPath.Pop(); + } + } + + if (beforeSize > afterSize) + { + subPath.Push(PathEntry(PathEntry::EndOfArrayIndex)); + for (size_t i = beforeSize; i > afterSize; --i) + { + AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, before[i - 1])); + } + } + }; + + auto CompareNodes = [&](const Path& path, const Value& before, const Value& after) + { + if (before.GetNodeName() != after.GetNodeName()) + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + } + else + { + CompareObjects(path, before, after); + CompareArrays(path, before, after); + } + }; + + CompareValues = [&](const Path& path, const Value& before, const Value& after) + { + if (before.GetType() != after.GetType()) + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + } + else if (before == after) + { + // If a shallow comparison succeeds we're pointing to an identical value or container + // and don't need to drill down. + return; + } + else if (before.IsObject()) + { + CompareObjects(path, before, after); + } + else if (before.IsArray()) + { + CompareArrays(path, before, after); + } + else if (before.IsNode()) + { + CompareNodes(path, before, after); + } + else + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + } + }; + + entriesToCompare.emplace(Path(), beforeState, afterState); + while (!entriesToCompare.empty()) + { + PendingComparison& comparison = entriesToCompare.front(); + CompareValues(comparison.m_path, comparison.m_before, comparison.m_after); + entriesToCompare.pop(); + } + return patches; + } +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h new file mode 100644 index 0000000000..9d9ad7560a --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +namespace AZ::Dom +{ + //! A patch operation that represents an atomic operation for mutating or validating a Value. + //! PatchOperations can be created with helper methods in Patch. /see Patch + class PatchOperation final + { + public: + using PatchOutcome = AZ::Outcome; + + //! The operation to perform. + enum class Type + { + Add, //!< Inserts or replaces the value at DestinationPath with Value + Remove, //!< Removes the entry at DestinationPath + Replace, //!< Replaces the value at DestinationPath with Value + Copy, //!< Copies the contents of SourcePath to DestinationPath + Move, //!< Moves the contents of SourcePath to DestinationPath + Test //!< Ensures the contents of DestinationPath match Value or fails, performs no mutations + }; + + PatchOperation() = default; + PatchOperation(const PatchOperation&) = default; + PatchOperation(PatchOperation&&) = default; + + explicit PatchOperation(Path destinationPath, Type type, Value value); + explicit PatchOperation(Path destionationPath, Type type, Path sourcePath); + explicit PatchOperation(Path path, Type type); + + static PatchOperation AddOperation(Path destinationPath, Value value); + static PatchOperation RemoveOperation(Path pathToRemove); + static PatchOperation ReplaceOperation(Path destinationPath, Value value); + static PatchOperation CopyOperation(Path destinationPath, Path sourcePath); + static PatchOperation MoveOperation(Path destinationPath, Path sourcePath); + static PatchOperation TestOperation(Path testPath, Value value); + + PatchOperation& operator=(const PatchOperation&) = default; + PatchOperation& operator=(PatchOperation&&) = default; + + bool operator==(const PatchOperation& rhs) const; + bool operator!=(const PatchOperation& rhs) const; + + Type GetType() const; + void SetType(Type type); + + const Path& GetDestinationPath() const; + void SetDestinationPath(Path path); + + const Value& GetValue() const; + void SetValue(Value value); + + const Path& GetSourcePath() const; + void SetSourcePath(Path path); + + AZ::Outcome Apply(Value rootElement) const; + PatchOutcome ApplyInPlace(Value& rootElement) const; + + Value GetDomRepresentation() const; + static AZ::Outcome CreateFromDomRepresentation(Value domValue); + + AZ::Outcome GetInverse(Value stateBeforeApplication) const; + + private: + struct PathContext + { + Value& m_value; + PathEntry m_key; + }; + + static constexpr AZ::u8 DefaultExistenceCheck = 0x0; + static constexpr AZ::u8 VerifyFullPath = 0x1; + static constexpr AZ::u8 AllowEndOfArray = 0x2; + + static AZ::Outcome LookupPath( + Value& rootElement, const Path& path, AZ::u8 existenceCheckFlags = DefaultExistenceCheck); + + PatchOutcome ApplyAdd(Value& rootElement) const; + PatchOutcome ApplyRemove(Value& rootElement) const; + PatchOutcome ApplyReplace(Value& rootElement) const; + PatchOutcome ApplyCopy(Value& rootElement) const; + PatchOutcome ApplyMove(Value& rootElement) const; + PatchOutcome ApplyTest(Value& rootElement) const; + + Path m_domPath; + Type m_type; + AZStd::variant m_value; + }; + + class Patch; + + //! The current state of a Patch application operation. + struct PatchApplicationState + { + //! The patch being applied. + const Patch* m_patch = nullptr; + //! The last operation attempted. + const PatchOperation* m_lastOperation = nullptr; + //! The outcome of the last operation, may be overridden to produce a different failure outcome. + PatchOperation::PatchOutcome m_outcome; + //! The current state of the value being patched, will be returned if the patch operation succeeds. + Value* m_currentState = nullptr; + //! If set to false, the patch operation should halt. + bool m_shouldContinue = true; + }; + + namespace PatchApplicationStrategy + { + //! The default patching strategy. Applies all operations in a patch, but halts if any one operation fails. + void HaltOnFailure(PatchApplicationState& state); + //! Patching strategy that attemps to apply all operations in a patch, but ignores operation failures and continues. + void IgnoreFailureAndContinue(PatchApplicationState& state); + } // namespace PatchApplicationStrategy + + //! A set of operations that can be applied to a Value to produce a new Value. + //! \see PatchOperation + class Patch final + { + public: + using StrategyFunctor = AZStd::function; + using OperationsContainer = AZStd::vector; + + Patch() = default; + Patch(const Patch&) = default; + Patch(Patch&&) = default; + Patch(AZStd::initializer_list init); + + template + Patch(InputIterator first, InputIterator last) + : m_operations(first, last) + { + } + + Patch& operator=(const Patch&) = default; + Patch& operator=(Patch&&) = default; + + bool operator==(const Patch& rhs) const; + bool operator!=(const Patch& rhs) const; + + const OperationsContainer& GetOperations() const; + void PushBack(PatchOperation op); + void PushFront(PatchOperation op); + void Pop(); + void Clear(); + const PatchOperation& At(size_t index) const; + size_t Size() const; + + PatchOperation& operator[](size_t index); + const PatchOperation& operator[](size_t index) const; + + OperationsContainer::iterator begin(); + OperationsContainer::iterator end(); + OperationsContainer::const_iterator begin() const; + OperationsContainer::const_iterator end() const; + OperationsContainer::const_iterator cbegin() const; + OperationsContainer::const_iterator cend() const; + size_t size() const; + + AZ::Outcome Apply(Value rootElement, StrategyFunctor strategy = PatchApplicationStrategy::HaltOnFailure) const; + AZ::Outcome ApplyInPlace(Value& rootElement, StrategyFunctor strategy = PatchApplicationStrategy::HaltOnFailure) const; + + Value GetDomRepresentation() const; + static AZ::Outcome CreateFromDomRepresentation(Value domValue); + + private: + OperationsContainer m_operations; + }; + + //! A set of patches for applying a change and doing the inverse operation (i.e. undoing it). + struct PatchInfo + { + Patch m_forwardPatches; + Patch m_inversePatches; + }; + + //! Generates a set of patches such that m_forwardPatches.Apply(beforeState) shall produce a document equivalent to afterState, and + //! a subsequent m_inversePatches.Apply(beforeState) shall produce the original document. This patch generation strategy does a + //! hierarchical comparison and is not guaranteed to create the minimal set of patches required to transform between the two states. + PatchInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState); +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp index bc50a8513c..a5d130d48c 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp @@ -53,17 +53,20 @@ namespace AZ::Dom bool PathEntry::operator==(size_t value) const { - return IsIndex() && GetIndex() == value; + const size_t* internalValue = AZStd::get_if(&m_value); + return internalValue == nullptr ? false : (*internalValue) == value; } bool PathEntry::operator==(const AZ::Name& key) const { - return IsKey() && GetKey() == key; + const AZ::Name* internalValue = AZStd::get_if(&m_value); + return internalValue == nullptr ? false : (*internalValue) == key; } bool PathEntry::operator==(AZStd::string_view key) const { - return IsKey() && GetKey() == AZ::Name(key); + const AZ::Name* internalValue = AZStd::get_if(&m_value); + return internalValue == nullptr ? false : (*internalValue) == AZ::Name(key); } bool PathEntry::operator!=(const PathEntry& other) const @@ -73,17 +76,17 @@ namespace AZ::Dom bool PathEntry::operator!=(size_t value) const { - return !IsIndex() || GetIndex() != value; + return !operator==(value); } bool PathEntry::operator!=(const AZ::Name& key) const { - return !IsKey() || GetKey() != key; + return !operator==(key); } bool PathEntry::operator!=(AZStd::string_view key) const { - return !IsKey() || GetKey() != AZ::Name(key); + return !operator==(key); } void PathEntry::SetEndOfArray() diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 2c0c318648..c5928f1c84 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -116,6 +116,8 @@ set(FILES Debug/TraceReflection.h DOM/DomBackend.cpp DOM/DomBackend.h + DOM/DomPatch.cpp + DOM/DomPatch.h DOM/DomPath.cpp DOM/DomPath.h DOM/DomUtils.cpp diff --git a/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp new file mode 100644 index 0000000000..de19ee1783 --- /dev/null +++ b/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include + +namespace AZ::Dom::Benchmark +{ + class DomPatchBenchmark : public Tests::DomBenchmarkFixture + { + public: + void TearDownHarness() override + { + m_before = {}; + m_after = {}; + Tests::DomBenchmarkFixture::TearDownHarness(); + } + + void SimpleReplace(benchmark::State& state, bool deepCopy, bool apply) + { + m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before; + m_after["entries"]["Key0"] = Value("replacement string", true); + + RunBenchmarkInternal(state, apply); + } + + void TopLevelReplace(benchmark::State& state, bool apply) + { + m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + m_after = Value(Type::Object); + m_after["UnrelatedKey"] = Value(42); + + RunBenchmarkInternal(state, apply); + } + + void KeyRemove(benchmark::State& state, bool deepCopy, bool apply) + { + m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before; + m_after["entries"].RemoveMember("Key1"); + + RunBenchmarkInternal(state, apply); + } + + void ArrayAppend(benchmark::State& state, bool deepCopy, bool apply) + { + m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before; + m_after["entries"]["Key2"].ArrayPushBack(Value(0)); + + RunBenchmarkInternal(state, apply); + } + + void ArrayPrepend(benchmark::State& state, bool deepCopy, bool apply) + { + m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before; + auto& arr = m_after["entries"]["Key2"].GetMutableArray(); + arr.insert(arr.begin(), Value(42)); + + RunBenchmarkInternal(state, apply); + } + + private: + void RunBenchmarkInternal(benchmark::State& state, bool apply) + { + if (apply) + { + auto patchInfo = GenerateHierarchicalDeltaPatch(m_before, m_after); + for (auto _ : state) + { + auto patchResult = patchInfo.m_forwardPatches.Apply(m_before); + benchmark::DoNotOptimize(patchResult); + } + } + else + { + for (auto _ : state) + { + auto patchInfo = GenerateHierarchicalDeltaPatch(m_before, m_after); + benchmark::DoNotOptimize(patchInfo); + } + } + + state.SetItemsProcessed(state.iterations()); + } + + Value m_before; + Value m_after; + }; + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_ShallowCopy)(benchmark::State& state) + { + SimpleReplace(state, false, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_ShallowCopy) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_DeepCopy)(benchmark::State& state) + { + SimpleReplace(state, true, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_DeepCopy) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_TopLevelReplace)(benchmark::State& state) + { + TopLevelReplace(state, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_TopLevelReplace) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_ShallowCopy)(benchmark::State& state) + { + KeyRemove(state, false, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_ShallowCopy) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_DeepCopy)(benchmark::State& state) + { + KeyRemove(state, true, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_DeepCopy) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_ShallowCopy)(benchmark::State& state) + { + ArrayAppend(state, false, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_ShallowCopy) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_DeepCopy)(benchmark::State& state) + { + ArrayAppend(state, true, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_DeepCopy) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_ArrayPrepend)(benchmark::State& state) + { + ArrayPrepend(state, true, false); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_ArrayPrepend) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_SimpleReplace)(benchmark::State& state) + { + SimpleReplace(state, true, true); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_SimpleReplace) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_TopLevelReplace)(benchmark::State& state) + { + TopLevelReplace(state, true); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_TopLevelReplace) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_KeyRemove)(benchmark::State& state) + { + KeyRemove(state, true, true); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_KeyRemove) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_ArrayAppend)(benchmark::State& state) + { + ArrayAppend(state, true, true); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_ArrayAppend) + + BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_ArrayPrepend)(benchmark::State& state) + { + ArrayPrepend(state, true, true); + } + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_ArrayPrepend) +} // namespace AZ::Dom::Benchmark diff --git a/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp new file mode 100644 index 0000000000..a0e4f349a5 --- /dev/null +++ b/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp @@ -0,0 +1,562 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +namespace AZ::Dom::Tests +{ + class DomPatchTests : public DomTestFixture + { + public: + void SetUp() override + { + DomTestFixture::SetUp(); + + m_dataset = Value(Type::Object); + m_dataset["arr"].SetArray(); + + m_dataset["node"].SetNode("SomeNode"); + m_dataset["node"]["int"] = 5; + m_dataset["node"]["null"] = Value(); + + for (int i = 0; i < 5; ++i) + { + m_dataset["arr"].ArrayPushBack(Value(i)); + m_dataset["node"].ArrayPushBack(Value(i * 2)); + } + + m_dataset["obj"].SetObject(); + m_dataset["obj"]["foo"] = true; + m_dataset["obj"]["bar"] = false; + + m_deltaDataset = m_dataset; + } + + void TearDown() override + { + m_dataset = m_deltaDataset = Value(); + + DomTestFixture::TearDown(); + } + + PatchInfo GenerateAndVerifyDelta() + { + PatchInfo info = GenerateHierarchicalDeltaPatch(m_dataset, m_deltaDataset); + + auto result = info.m_forwardPatches.Apply(m_dataset); + EXPECT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue(), m_deltaDataset)); + + result = info.m_inversePatches.Apply(result.GetValue()); + EXPECT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue(), m_dataset)); + + // Verify serialization of the patches + auto VerifySerialization = [](const Patch& patch) + { + Value serializedPatch = patch.GetDomRepresentation(); + auto deserializePatchResult = Patch::CreateFromDomRepresentation(serializedPatch); + EXPECT_TRUE(deserializePatchResult.IsSuccess()); + EXPECT_EQ(deserializePatchResult.GetValue(), patch); + }; + VerifySerialization(info.m_forwardPatches); + VerifySerialization(info.m_inversePatches); + + return info; + } + + Value m_dataset; + Value m_deltaDataset; + }; + + TEST_F(DomPatchTests, AddOperation_InsertInObject_Succeeds) + { + Path p("/obj/baz"); + PatchOperation op = PatchOperation::AddOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()[p].GetInt64(), 42); + } + + TEST_F(DomPatchTests, AddOperation_ReplaceInObject_Succeeds) + { + Path p("/obj/foo"); + PatchOperation op = PatchOperation::AddOperation(p, Value(false)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()[p].GetBool(), false); + } + + TEST_F(DomPatchTests, AddOperation_InsertObjectKeyInArray_Fails) + { + Path p("/arr/key"); + PatchOperation op = PatchOperation::AddOperation(p, Value(999)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, AddOperation_AppendInArray_Succeeds) + { + Path p("/arr/-"); + PatchOperation op = PatchOperation::AddOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()["arr"][5].GetInt64(), 42); + } + + TEST_F(DomPatchTests, AddOperation_InsertKeyInNode_Succeeds) + { + Path p("/node/attr"); + PatchOperation op = PatchOperation::AddOperation(p, Value(500)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()[p].GetInt64(), 500); + } + + TEST_F(DomPatchTests, AddOperation_ReplaceIndexInNode_Succeeds) + { + Path p("/node/0"); + PatchOperation op = PatchOperation::AddOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()[p].GetInt64(), 42); + } + + TEST_F(DomPatchTests, AddOperation_AppendInNode_Succeeds) + { + Path p("/node/-"); + PatchOperation op = PatchOperation::AddOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()["node"][5].GetInt64(), 42); + } + + TEST_F(DomPatchTests, AddOperation_InvalidPath_Fails) + { + Path p("/non/existent/path"); + PatchOperation op = PatchOperation::AddOperation(p, Value(0)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, RemoveOperation_RemoveKeyFromObject_Succeeds) + { + Path p("/obj/foo"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_FALSE(result.GetValue()["obj"].HasMember("foo")); + } + + TEST_F(DomPatchTests, RemoveOperation_RemoveIndexFromArray_Succeeds) + { + Path p("/arr/0"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()["arr"].ArraySize(), 4); + EXPECT_EQ(result.GetValue()["arr"][0].GetInt64(), 1); + } + + TEST_F(DomPatchTests, RemoveOperation_PopArray_Succeeds) + { + Path p("/arr/-"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + EXPECT_EQ(result.GetValue()["arr"].ArraySize(), 4); + } + + TEST_F(DomPatchTests, RemoveOperation_RemoveKeyFromNode_Succeeds) + { + Path p("/node/int"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_FALSE(result.GetValue()["node"].HasMember("int")); + } + + TEST_F(DomPatchTests, RemoveOperation_RemoveIndexFromNode_Succeeds) + { + Path p("/node/1"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()["node"].ArraySize(), 4); + EXPECT_EQ(result.GetValue()["node"][1].GetInt64(), 4); + } + + TEST_F(DomPatchTests, RemoveOperation_PopIndexFromNode_Succeeds) + { + Path p("/node/-"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()["node"].ArraySize(), 4); + } + + TEST_F(DomPatchTests, RemoveOperation_RemoveKeyFromArray_Fails) + { + Path p("/arr/foo"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, RemoveOperation_InvalidPath_Fails) + { + Path p("/non/existent/path"); + PatchOperation op = PatchOperation::RemoveOperation(p); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, ReplaceOperation_InsertInObject_Fails) + { + Path p("/obj/baz"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, ReplaceOperation_ReplaceInObject_Succeeds) + { + Path p("/obj/foo"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(false)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()[p].GetBool(), false); + } + + TEST_F(DomPatchTests, ReplaceOperation_InsertObjectKeyInArray_Fails) + { + Path p("/arr/key"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(999)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, ReplaceOperation_AppendInArray_Fails) + { + Path p("/arr/-"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, ReplaceOperation_InsertKeyInNode_Fails) + { + Path p("/node/attr"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(500)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, ReplaceOperation_ReplaceIndexInNode_Succeeds) + { + Path p("/node/0"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_EQ(result.GetValue()[p].GetInt64(), 42); + } + + TEST_F(DomPatchTests, ReplaceOperation_AppendInNode_Fails) + { + Path p("/node/-"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, ReplaceOperation_InvalidPath_Fails) + { + Path p("/non/existent/path"); + PatchOperation op = PatchOperation::ReplaceOperation(p, Value(0)); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, CopyOperation_ArrayToObject_Succeeds) + { + Path dest("/obj/arr"); + Path src("/arr"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest])); + EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue()[src], result.GetValue()[dest])); + } + + TEST_F(DomPatchTests, CopyOperation_ObjectToArrayInRange_Succeeds) + { + Path dest("/arr/0"); + Path src("/obj"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest])); + EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue()[src], result.GetValue()[dest])); + } + + TEST_F(DomPatchTests, CopyOperation_ObjectToArrayOutOfRange_Fails) + { + Path dest("/arr/5"); + Path src("/obj"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, CopyOperation_ObjectToNodeChildInRange_Succeeds) + { + Path dest("/node/0"); + Path src("/obj"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest])); + EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue()[src], result.GetValue()[dest])); + } + + TEST_F(DomPatchTests, CopyOperation_ObjectToNodeChildOutOfRange_Fails) + { + Path dest("/node/5"); + Path src("/obj"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, CopyOperation_InvalidSourcePath_Fails) + { + Path dest("/node/0"); + Path src("/invalid/path"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, CopyOperation_InvalidDestinationPath_Fails) + { + Path dest("/invalid/path"); + Path src("/arr/0"); + PatchOperation op = PatchOperation::CopyOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, MoveOperation_ArrayToObject_Succeeds) + { + Path dest("/obj/arr"); + Path src("/arr"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest])); + EXPECT_FALSE(result.GetValue().HasMember("arr")); + } + + TEST_F(DomPatchTests, MoveOperation_ObjectToArrayInRange_Succeeds) + { + Path dest("/arr/0"); + Path src("/obj"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest])); + EXPECT_FALSE(result.GetValue().HasMember("obj")); + } + + TEST_F(DomPatchTests, MoveOperation_ObjectToArrayOutOfRange_Fails) + { + Path dest("/arr/5"); + Path src("/obj"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, MoveOperation_ObjectToNodeChildInRange_Succeeds) + { + Path dest("/node/0"); + Path src("/obj"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest])); + EXPECT_FALSE(result.GetValue().HasMember("obj")); + } + + TEST_F(DomPatchTests, MoveOperation_ObjectToNodeChildOutOfRange_Fails) + { + Path dest("/node/5"); + Path src("/obj"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, MoveOperation_InvalidSourcePath_Fails) + { + Path dest("/node/0"); + Path src("/invalid/path"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, MoveOperation_InvalidDestinationPath_Fails) + { + Path dest("/invalid/path"); + Path src("/arr/0"); + PatchOperation op = PatchOperation::MoveOperation(dest, src); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestOperation_TestCorrectValue_Succeeds) + { + Path path("/arr/1"); + Value value(1); + PatchOperation op = PatchOperation::TestOperation(path, value); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestOperation_TestIncorrectValue_Fails) + { + Path path("/arr/1"); + Value value(55); + PatchOperation op = PatchOperation::TestOperation(path, value); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestOperation_TestCorrectComplexValue_Succeeds) + { + Path path; + Value value = m_dataset; + PatchOperation op = PatchOperation::TestOperation(path, value); + auto result = op.Apply(m_dataset); + ASSERT_TRUE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestOperation_TestIncorrectComplexValue_Fails) + { + Path path; + Value value = m_dataset; + value["arr"][4] = 9; + PatchOperation op = PatchOperation::TestOperation(path, value); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestOperation_TestInvalidPath_Fails) + { + Path path("/invalid/path"); + Value value; + PatchOperation op = PatchOperation::TestOperation(path, value); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestOperation_TestInsertArrayPath_Fails) + { + Path path("/arr/-"); + Value value(4); + PatchOperation op = PatchOperation::TestOperation(path, value); + auto result = op.Apply(m_dataset); + ASSERT_FALSE(result.IsSuccess()); + } + + TEST_F(DomPatchTests, TestPatch_ReplaceArrayValue) + { + m_deltaDataset["arr"][0] = 5; + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_AppendArrayValue) + { + m_deltaDataset["arr"].ArrayPushBack(Value(7)); + auto result = GenerateAndVerifyDelta(); + + // Ensure the generated patch uses the array append operation + ASSERT_EQ(result.m_forwardPatches.Size(), 1); + EXPECT_TRUE(result.m_forwardPatches[0].GetDestinationPath()[1].IsEndOfArray()); + } + + TEST_F(DomPatchTests, TestPatch_AppendArrayValues) + { + m_deltaDataset["arr"].ArrayPushBack(Value(7)); + m_deltaDataset["arr"].ArrayPushBack(Value(8)); + m_deltaDataset["arr"].ArrayPushBack(Value(9)); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_InsertArrayValue) + { + auto& arr = m_deltaDataset["arr"].GetMutableArray(); + arr.insert(arr.begin(), Value(42)); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_InsertObjectKey) + { + m_deltaDataset["obj"]["newKey"].CopyFromString("test"); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_DeleteObjectKey) + { + m_deltaDataset["obj"].RemoveMember("foo"); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_AppendNodeValues) + { + m_deltaDataset["node"].ArrayPushBack(Value(7)); + m_deltaDataset["node"].ArrayPushBack(Value(8)); + m_deltaDataset["node"].ArrayPushBack(Value(9)); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_InsertNodeValue) + { + auto& node = m_deltaDataset["node"].GetMutableNode(); + node.GetChildren().insert(node.GetChildren().begin(), Value(42)); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_InsertNodeKey) + { + m_deltaDataset["node"]["newKey"].CopyFromString("test"); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_DeleteNodeKey) + { + m_deltaDataset["node"].RemoveMember("int"); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_RenameNode) + { + m_deltaDataset["node"].SetNodeName("RenamedNode"); + GenerateAndVerifyDelta(); + } + + TEST_F(DomPatchTests, TestPatch_ReplaceRoot) + { + m_deltaDataset = Value(Type::Array); + m_deltaDataset.ArrayPushBack(Value(2)); + m_deltaDataset.ArrayPushBack(Value(4)); + m_deltaDataset.ArrayPushBack(Value(6)); + GenerateAndVerifyDelta(); + } +} // namespace AZ::Dom::Tests diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index 24a6601cf0..86bf943a5a 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -221,6 +221,8 @@ set(FILES DOM/DomJsonBenchmarks.cpp DOM/DomPathTests.cpp DOM/DomPathBenchmarks.cpp + DOM/DomPatchTests.cpp + DOM/DomPatchBenchmarks.cpp DOM/DomValueTests.cpp DOM/DomValueBenchmarks.cpp ) From 73f166241e33edd33d2211c8c91a1dcf786fb3e5 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 27 Jan 2022 13:15:30 -0800 Subject: [PATCH 02/24] Address review feedback Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp | 101 ++++++++++-------- Code/Framework/AzCore/AzCore/DOM/DomPatch.h | 35 ++++-- Code/Framework/AzCore/AzCore/DOM/DomPath.cpp | 18 +++- Code/Framework/AzCore/AzCore/DOM/DomPath.h | 11 +- .../AzCore/Tests/DOM/DomPathBenchmarks.cpp | 21 ++++ .../AzCore/Tests/DOM/DomPathTests.cpp | 19 ++++ 6 files changed, 143 insertions(+), 62 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp index 963308e9c8..6e53de0689 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp @@ -8,8 +8,8 @@ #include #include -#include #include +#include namespace AZ::Dom { @@ -257,7 +257,8 @@ namespace AZ::Dom return AZ::Failure(sourceLoad.TakeError()); } - return AZ::Success(PatchOperation::CopyOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString()))); + return AZ::Success( + PatchOperation::CopyOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString()))); } else if (op == "move") { @@ -272,7 +273,8 @@ namespace AZ::Dom return AZ::Failure(sourceLoad.TakeError()); } - return AZ::Success(PatchOperation::MoveOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString()))); + return AZ::Success( + PatchOperation::MoveOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString()))); } else if (op == "test") { @@ -319,8 +321,9 @@ namespace AZ::Dom const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); if (existingValue == nullptr) { - return AZ::Failure( - AZStd::string::format("Unable to invert DOM remove patch, source path not found: %s", m_domPath.ToString().data())); + AZStd::string errorMessage = "Unable to invert DOM remove patch, source path not found: "; + m_domPath.AppendToString(errorMessage); + return AZ::Failure(AZStd::move(errorMessage)); } return AZ::Success(PatchOperation::AddOperation(m_domPath, *existingValue)); } @@ -330,8 +333,9 @@ namespace AZ::Dom const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); if (existingValue == nullptr) { - return AZ::Failure(AZStd::string::format( - "Unable to invert DOM replace patch, source path not found: %s", m_domPath.ToString().data())); + AZStd::string errorMessage = "Unable to invert DOM replace patch, source path not found: "; + m_domPath.AppendToString(errorMessage); + return AZ::Failure(AZStd::move(errorMessage)); } return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); } @@ -341,8 +345,9 @@ namespace AZ::Dom const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); if (existingValue == nullptr) { - return AZ::Failure( - AZStd::string::format("Unable to invert DOM copy patch, source path not found: %s", m_domPath.ToString().data())); + AZStd::string errorMessage = "Unable to invert DOM copy patch, source path not found: "; + m_domPath.AppendToString(errorMessage); + return AZ::Failure(AZStd::move(errorMessage)); } return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); } @@ -367,8 +372,9 @@ namespace AZ::Dom const Value* existingValue = stateBeforeApplication.FindChild(commonAncestor); if (existingValue == nullptr) { - return AZ::Failure(AZStd::string::format( - "Unable to invert DOM move patch, common ancestor path not found: %s", commonAncestor.ToString().data())); + AZStd::string errorMessage = "Unable to invert DOM copy patch, common ancestor path not found: "; + commonAncestor.AppendToString(errorMessage); + return AZ::Failure(AZStd::move(errorMessage)); } return AZ::Success(PatchOperation::ReplaceOperation(commonAncestor, *existingValue)); } @@ -383,10 +389,10 @@ namespace AZ::Dom } AZ::Outcome PatchOperation::LookupPath( - Value& rootElement, const Path& path, AZ::u8 existenceCheckFlags) + Value& rootElement, const Path& path, ExistenceCheckFlags flags) { - const bool verifyFullPath = existenceCheckFlags & VerifyFullPath; - const bool allowEndOfArray = existenceCheckFlags & AllowEndOfArray; + const bool verifyFullPath = (flags & ExistenceCheckFlags::VerifyFullPath) != ExistenceCheckFlags::DefaultExistenceCheck; + const bool allowEndOfArray = (flags & ExistenceCheckFlags::AllowEndOfArray) != ExistenceCheckFlags::DefaultExistenceCheck; Path target = path; if (target.Size() == 0) @@ -414,7 +420,9 @@ namespace AZ::Dom Value* targetValue = rootElement.FindMutableChild(target); if (targetValue == nullptr) { - return AZ::Failure(AZStd::string::format("Path not found (%s)", target.ToString().data())); + AZStd::string errorMessage = "Path not found: "; + target.AppendToString(errorMessage); + return AZ::Failure(AZStd::move(errorMessage)); } if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray()) @@ -450,7 +458,7 @@ namespace AZ::Dom PatchOperation::PatchOutcome PatchOperation::ApplyAdd(Value& rootElement) const { - auto pathLookup = LookupPath(rootElement, m_domPath, AllowEndOfArray); + auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::AllowEndOfArray); if (!pathLookup.IsSuccess()) { return AZ::Failure(pathLookup.TakeError()); @@ -481,7 +489,7 @@ namespace AZ::Dom PatchOperation::PatchOutcome PatchOperation::ApplyRemove(Value& rootElement) const { - auto pathLookup = LookupPath(rootElement, m_domPath, VerifyFullPath | AllowEndOfArray); + auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::VerifyFullPath | ExistenceCheckFlags::AllowEndOfArray); if (!pathLookup.IsSuccess()) { return AZ::Failure(pathLookup.TakeError()); @@ -505,7 +513,7 @@ namespace AZ::Dom PatchOperation::PatchOutcome PatchOperation::ApplyReplace(Value& rootElement) const { - auto pathLookup = LookupPath(rootElement, m_domPath, VerifyFullPath); + auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::VerifyFullPath); if (!pathLookup.IsSuccess()) { return AZ::Failure(pathLookup.TakeError()); @@ -517,13 +525,13 @@ namespace AZ::Dom PatchOperation::PatchOutcome PatchOperation::ApplyCopy(Value& rootElement) const { - auto sourceLookup = LookupPath(rootElement, GetSourcePath(), VerifyFullPath); + auto sourceLookup = LookupPath(rootElement, GetSourcePath(), ExistenceCheckFlags::VerifyFullPath); if (!sourceLookup.IsSuccess()) { return AZ::Failure(sourceLookup.TakeError()); } - auto destLookup = LookupPath(rootElement, m_domPath, AllowEndOfArray); + auto destLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::AllowEndOfArray); if (!destLookup.IsSuccess()) { return AZ::Failure(destLookup.TakeError()); @@ -535,13 +543,13 @@ namespace AZ::Dom PatchOperation::PatchOutcome PatchOperation::ApplyMove(Value& rootElement) const { - auto sourceLookup = LookupPath(rootElement, GetSourcePath(), VerifyFullPath); + auto sourceLookup = LookupPath(rootElement, GetSourcePath(), ExistenceCheckFlags::VerifyFullPath); if (!sourceLookup.IsSuccess()) { return AZ::Failure(sourceLookup.TakeError()); } - auto destLookup = LookupPath(rootElement, m_domPath, AllowEndOfArray); + auto destLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::AllowEndOfArray); if (!destLookup.IsSuccess()) { return AZ::Failure(destLookup.TakeError()); @@ -568,7 +576,7 @@ namespace AZ::Dom PatchOperation::PatchOutcome PatchOperation::ApplyTest(Value& rootElement) const { - auto pathLookup = LookupPath(rootElement, m_domPath, VerifyFullPath); + auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::VerifyFullPath); if (!pathLookup.IsSuccess()) { return AZ::Failure(pathLookup.TakeError()); @@ -670,32 +678,32 @@ namespace AZ::Dom return m_operations[index]; } - Patch::OperationsContainer::iterator Patch::begin() + auto Patch::begin() -> OperationsContainer::iterator { return m_operations.begin(); } - Patch::OperationsContainer::iterator Patch::end() + auto Patch::end() -> OperationsContainer::iterator { return m_operations.end(); } - Patch::OperationsContainer::const_iterator Patch::begin() const + auto Patch::begin() const -> OperationsContainer::const_iterator { return m_operations.cbegin(); } - Patch::OperationsContainer::const_iterator Patch::end() const + auto Patch::end() const -> OperationsContainer::const_iterator { return m_operations.cend(); } - Patch::OperationsContainer::const_iterator Patch::cbegin() const + auto Patch::cbegin() const -> OperationsContainer::const_iterator { return m_operations.cbegin(); } - Patch::OperationsContainer::const_iterator Patch::cend() const + auto Patch::cend() const -> OperationsContainer::const_iterator { return m_operations.cend(); } @@ -794,7 +802,8 @@ namespace AZ::Dom return PatchOperation(AZStd::move(testPath), PatchOperation::Type::Test, AZStd::move(value)); } - PatchInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState) + PatchInfo GenerateHierarchicalDeltaPatch( + const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params) { PatchInfo patches; @@ -804,7 +813,7 @@ namespace AZ::Dom patches.m_inversePatches.PushFront(AZStd::move(inverse)); }; - AZStd::function CompareValues; + AZStd::function compareValues; struct PendingComparison { @@ -822,7 +831,7 @@ namespace AZ::Dom AZStd::queue entriesToCompare; AZStd::unordered_set desiredKeys; - auto CompareObjects = [&](const Path& path, const Value& before, const Value& after) + auto compareObjects = [&](const Path& path, const Value& before, const Value& after) { desiredKeys.clear(); Path subPath = path; @@ -853,22 +862,22 @@ namespace AZ::Dom } }; - auto CompareArrays = [&](const Path& path, const Value& before, const Value& after) + auto compareArrays = [&](const Path& path, const Value& before, const Value& after) { const size_t beforeSize = before.ArraySize(); const size_t afterSize = after.ArraySize(); // If more than replaceThreshold values differ, do a replace operation instead - constexpr size_t replaceThreshold = 3; - size_t changedValueCount = 0; - for (size_t i = 0; i < afterSize; ++i) + if (params.m_replaceThreshold != DeltaPatchGenerationParameters::NoReplace) { - if (i < beforeSize) + size_t changedValueCount = 0; + const size_t entriesToEnumerate = AZStd::min(beforeSize, afterSize); + for (size_t i = 0; i < entriesToEnumerate; ++i) { if (before[i] != after[i]) { ++changedValueCount; - if (changedValueCount >= replaceThreshold) + if (changedValueCount >= params.m_replaceThreshold) { AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); return; @@ -904,7 +913,7 @@ namespace AZ::Dom } }; - auto CompareNodes = [&](const Path& path, const Value& before, const Value& after) + auto compareNodes = [&](const Path& path, const Value& before, const Value& after) { if (before.GetNodeName() != after.GetNodeName()) { @@ -912,12 +921,12 @@ namespace AZ::Dom } else { - CompareObjects(path, before, after); - CompareArrays(path, before, after); + compareObjects(path, before, after); + compareArrays(path, before, after); } }; - CompareValues = [&](const Path& path, const Value& before, const Value& after) + compareValues = [&](const Path& path, const Value& before, const Value& after) { if (before.GetType() != after.GetType()) { @@ -931,15 +940,15 @@ namespace AZ::Dom } else if (before.IsObject()) { - CompareObjects(path, before, after); + compareObjects(path, before, after); } else if (before.IsArray()) { - CompareArrays(path, before, after); + compareArrays(path, before, after); } else if (before.IsNode()) { - CompareNodes(path, before, after); + compareNodes(path, before, after); } else { @@ -951,7 +960,7 @@ namespace AZ::Dom while (!entriesToCompare.empty()) { PendingComparison& comparison = entriesToCompare.front(); - CompareValues(comparison.m_path, comparison.m_before, comparison.m_after); + compareValues(comparison.m_path, comparison.m_before, comparison.m_after); entriesToCompare.pop(); } return patches; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h index 9d9ad7560a..633a611c73 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h @@ -35,9 +35,9 @@ namespace AZ::Dom PatchOperation(const PatchOperation&) = default; PatchOperation(PatchOperation&&) = default; - explicit PatchOperation(Path destinationPath, Type type, Value value); - explicit PatchOperation(Path destionationPath, Type type, Path sourcePath); - explicit PatchOperation(Path path, Type type); + PatchOperation(Path destionationPath, Type type, Value value); + PatchOperation(Path destionationPath, Type type, Path sourcePath); + PatchOperation(Path path, Type type); static PatchOperation AddOperation(Path destinationPath, Value value); static PatchOperation RemoveOperation(Path pathToRemove); @@ -72,6 +72,13 @@ namespace AZ::Dom AZ::Outcome GetInverse(Value stateBeforeApplication) const; + enum class ExistenceCheckFlags : AZ::u8 + { + DefaultExistenceCheck = 0x0, + VerifyFullPath = 0x1, + AllowEndOfArray = 0x2, + }; + private: struct PathContext { @@ -79,12 +86,8 @@ namespace AZ::Dom PathEntry m_key; }; - static constexpr AZ::u8 DefaultExistenceCheck = 0x0; - static constexpr AZ::u8 VerifyFullPath = 0x1; - static constexpr AZ::u8 AllowEndOfArray = 0x2; - static AZ::Outcome LookupPath( - Value& rootElement, const Path& path, AZ::u8 existenceCheckFlags = DefaultExistenceCheck); + Value& rootElement, const Path& path, ExistenceCheckFlags existenceCheckFlags = ExistenceCheckFlags::DefaultExistenceCheck); PatchOutcome ApplyAdd(Value& rootElement) const; PatchOutcome ApplyRemove(Value& rootElement) const; @@ -93,11 +96,13 @@ namespace AZ::Dom PatchOutcome ApplyMove(Value& rootElement) const; PatchOutcome ApplyTest(Value& rootElement) const; + AZStd::variant m_value; Path m_domPath; Type m_type; - AZStd::variant m_value; }; + AZ_DEFINE_ENUM_BITWISE_OPERATORS(PatchOperation::ExistenceCheckFlags); + class Patch; //! The current state of a Patch application operation. @@ -184,8 +189,18 @@ namespace AZ::Dom Patch m_inversePatches; }; + //! Parameters for GenerateHierarchicalDeltaPatch. + struct DeltaPatchGenerationParameters + { + static constexpr size_t NoReplace = AZStd::numeric_limits::max(); + + //! The threshold of changed values in a node or array which, if exceeded, will cause the generation to create an + //! entire "replace" oepration instead. If set to NoReplace, no replacement will occur. + size_t m_replaceThreshold = 3; + }; + //! Generates a set of patches such that m_forwardPatches.Apply(beforeState) shall produce a document equivalent to afterState, and //! a subsequent m_inversePatches.Apply(beforeState) shall produce the original document. This patch generation strategy does a //! hierarchical comparison and is not guaranteed to create the minimal set of patches required to transform between the two states. - PatchInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState); + PatchInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params = {}); } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp index a5d130d48c..f98dad4adb 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp @@ -54,19 +54,19 @@ namespace AZ::Dom bool PathEntry::operator==(size_t value) const { const size_t* internalValue = AZStd::get_if(&m_value); - return internalValue == nullptr ? false : (*internalValue) == value; + return internalValue != nullptr && *internalValue == value; } bool PathEntry::operator==(const AZ::Name& key) const { const AZ::Name* internalValue = AZStd::get_if(&m_value); - return internalValue == nullptr ? false : (*internalValue) == key; + return internalValue != nullptr && *internalValue == key; } bool PathEntry::operator==(AZStd::string_view key) const { const AZ::Name* internalValue = AZStd::get_if(&m_value); - return internalValue == nullptr ? false : (*internalValue) == AZ::Name(key); + return internalValue != nullptr && *internalValue == AZ::Name(key); } bool PathEntry::operator!=(const PathEntry& other) const @@ -323,13 +323,13 @@ namespace AZ::Dom return size; } - void Path::FormatString(char* stringBuffer, size_t bufferSize) const + size_t Path::FormatString(char* stringBuffer, size_t bufferSize) const { size_t bufferIndex = 0; auto putChar = [&](char c) { - if (bufferIndex == bufferSize) + if (bufferIndex >= bufferSize) { return; } @@ -360,6 +360,11 @@ namespace AZ::Dom for (const PathEntry& entry : m_entries) { + if (bufferIndex >= bufferSize) + { + return bufferIndex; + } + putChar(PathSeparator); if (entry.IsEndOfArray()) { @@ -375,7 +380,10 @@ namespace AZ::Dom } } + size_t bytesWritten = bufferIndex; putChar('\0'); + + return bytesWritten; } AZStd::string Path::ToString() const diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.h b/Code/Framework/AzCore/AzCore/DOM/DomPath.h index 39f7c7da98..f1a95b4e70 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPath.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.h @@ -128,10 +128,19 @@ namespace AZ::Dom size_t GetStringLength() const; //! Formats a JSON-pointer style path string into the target buffer. //! This operation will fail if bufferSize < GetStringLength() + 1 - void FormatString(char* stringBuffer, size_t bufferSize) const; + //! \return The number of bytes written, excepting the null terminator. + size_t FormatString(char* stringBuffer, size_t bufferSize) const; //! Returns a JSON-pointer style path string for this path. AZStd::string ToString() const; + void AppendToString(AZStd::string& output) const; + template + void AppendToString(T& output) const + { + const size_t startIndex = output.length(); + output.resize_no_construct(startIndex + FormatString(output.data() + startIndex, output.capacity() - startIndex)); + } + //! Reads a JSON-pointer style path from pathString and replaces this path's contents. //! Paths are accepted in the following forms: //! "/path/to/foo/0" diff --git a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp index 624b24cd20..c3c8139f6c 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp @@ -96,4 +96,25 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(3 * state.iterations()); } BENCHMARK_REGISTER_F(DomPathBenchmark, DomPathEntry_IsEndOfArray); + + BENCHMARK_DEFINE_F(DomPathBenchmark, DomPathEntry_Comparison)(benchmark::State& state) + { + PathEntry name("name"); + PathEntry index(0); + PathEntry endOfArray; + endOfArray.SetEndOfArray(); + + for (auto _ : state) + { + name == name; + name == index; + name == endOfArray; + index == index; + index == endOfArray; + endOfArray == endOfArray; + } + + state.SetItemsProcessed(6 * state.iterations()); + } + BENCHMARK_REGISTER_F(DomPathBenchmark, DomPathEntry_Comparison); } diff --git a/Code/Framework/AzCore/Tests/DOM/DomPathTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomPathTests.cpp index 54bff9f29b..5f3aa946b2 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPathTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPathTests.cpp @@ -174,4 +174,23 @@ namespace AZ::Dom::Tests p.AppendToString(s); EXPECT_EQ(s, "/foo/0/foo/0"); } + + TEST_F(DomPathTests, MixedPath_AppendToFixedString) + { + Path p("/foo/0"); + + { + AZStd::fixed_string<7> s; + p.AppendToString(s); + EXPECT_EQ(s, "/foo/0"); + } + + { + AZStd::fixed_string<9> s; + p.AppendToString(s); + EXPECT_EQ(s, "/foo/0"); + p.AppendToString(s); + EXPECT_EQ(s, "/foo/0/fo"); + } + } } // namespace AZ::Dom::Tests From 155cc5845b656b1a9c31b100ac6e5379e24e74eb Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 27 Jan 2022 13:44:35 -0800 Subject: [PATCH 03/24] Add Path::IsEmpty Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp | 2 +- Code/Framework/AzCore/AzCore/DOM/DomPath.cpp | 5 +++++ Code/Framework/AzCore/AzCore/DOM/DomPath.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp index 6e53de0689..44c16baa16 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp @@ -395,7 +395,7 @@ namespace AZ::Dom const bool allowEndOfArray = (flags & ExistenceCheckFlags::AllowEndOfArray) != ExistenceCheckFlags::DefaultExistenceCheck; Path target = path; - if (target.Size() == 0) + if (target.IsEmpty()) { Value wrapper(Dom::Type::Array); wrapper.ArrayPushBack(rootElement); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp index f98dad4adb..5f6438518f 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp @@ -246,6 +246,11 @@ namespace AZ::Dom return m_entries.size(); } + bool Path::IsEmpty() const + { + return m_entries.empty(); + } + PathEntry& Path::operator[](size_t index) { return m_entries[index]; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.h b/Code/Framework/AzCore/AzCore/DOM/DomPath.h index f1a95b4e70..7a031a2c68 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPath.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.h @@ -111,6 +111,7 @@ namespace AZ::Dom void Clear(); PathEntry At(size_t index) const; size_t Size() const; + bool IsEmpty() const; PathEntry& operator[](size_t index); const PathEntry& operator[](size_t index) const; From 4bb93e4c94a5aaa88841d1d208cd9ad126ee3eeb Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Thu, 3 Feb 2022 14:58:03 -0800 Subject: [PATCH 04/24] Removed unnecessary MaterialSourceData::Property class. This wrapper used to be needed in order to bind the custom JsonMaterialPropertyValueSerializer back when property values were represented by AZStd::any. Now that property values have a custom MaterialPropertyValue type, the wrapper class is no longer needed. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../MaterialConverterSystemComponent.cpp | 14 ++-- .../RPI.Edit/Material/MaterialSourceData.h | 9 +-- .../MaterialPropertyValueSerializer.cpp | 68 +++++++++---------- .../RPI.Edit/Material/MaterialSourceData.cpp | 16 ++--- .../Material/MaterialSourceDataTests.cpp | 32 ++++----- .../Code/Source/Document/MaterialDocument.cpp | 2 +- .../Material/EditorMaterialComponentUtil.cpp | 2 +- 7 files changed, 66 insertions(+), 77 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp index d5096d7a0b..835aa90ceb 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp @@ -101,7 +101,7 @@ namespace AZ if (assetFound) { - properties["textureMap"].m_value = texturePath; + properties["textureMap"] = texturePath; } else if (!texturePath.empty()) { @@ -120,7 +120,7 @@ namespace AZ { anyPBRInUse = true; handleTexture("baseColor", SceneAPI::DataTypes::IMaterialData::TextureMapType::BaseColor); - sourceData.m_properties["baseColor"]["textureBlendMode"].m_value = AZStd::string("Lerp"); + sourceData.m_properties["baseColor"]["textureBlendMode"] = AZStd::string("Lerp"); } else { @@ -135,10 +135,10 @@ namespace AZ if (baseColor.has_value()) { anyPBRInUse = true; - sourceData.m_properties["baseColor"]["color"].m_value = toColor(baseColor.value()); + sourceData.m_properties["baseColor"]["color"] = toColor(baseColor.value()); } - sourceData.m_properties["opacity"]["factor"].m_value = materialData.GetOpacity(); + sourceData.m_properties["opacity"]["factor"] = materialData.GetOpacity(); auto applyOptionalPropertiesFunc = [&sourceData, &anyPBRInUse](const auto& propertyGroup, const auto& propertyName, const auto& propertyOptional) { @@ -147,7 +147,7 @@ namespace AZ if (propertyOptional.has_value()) { anyPBRInUse = true; - sourceData.m_properties[propertyGroup][propertyName].m_value = propertyOptional.value(); + sourceData.m_properties[propertyGroup][propertyName] = propertyOptional.value(); } }; @@ -160,7 +160,7 @@ namespace AZ applyOptionalPropertiesFunc("roughness", "useTexture", materialData.GetUseRoughnessMap()); handleTexture("emissive", SceneAPI::DataTypes::IMaterialData::TextureMapType::Emissive); - sourceData.m_properties["emissive"]["color"].m_value = toColor(materialData.GetEmissiveColor()); + sourceData.m_properties["emissive"]["color"] = toColor(materialData.GetEmissiveColor()); applyOptionalPropertiesFunc("emissive", "intensity", materialData.GetEmissiveIntensity()); applyOptionalPropertiesFunc("emissive", "useTexture", materialData.GetUseEmissiveMap()); @@ -171,7 +171,7 @@ namespace AZ { // If it doesn't have the useColorMap property, then it's a non-PBR material and the baseColor // texture needs to be set to the diffuse color. - sourceData.m_properties["baseColor"]["color"].m_value = toColor(materialData.GetDiffuseColor()); + sourceData.m_properties["baseColor"]["color"] = toColor(materialData.GetDiffuseColor()); } return true; } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h index 0a9371f722..8b782fe66c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h @@ -59,14 +59,7 @@ namespace AZ uint32_t m_materialTypeVersion = 0; //!< The version of the material type that was used to configure this material - struct Property - { - AZ_TYPE_INFO(AZ::RPI::MaterialSourceData::Property, "{8D613464-3750-4122-AFFE-9238010D5AFC}"); - - MaterialPropertyValue m_value; - }; - - using PropertyMap = AZStd::map; + using PropertyMap = AZStd::map; using PropertyGroupMap = AZStd::map; PropertyGroupMap m_properties; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp index cb345e1d93..07d8c919d0 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp @@ -47,61 +47,61 @@ namespace AZ { namespace JSR = JsonSerializationResult; - AZ_Assert(azrtti_typeid() == outputValueTypeId, + AZ_Assert(azrtti_typeid() == outputValueTypeId, "Unable to deserialize material property value to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - MaterialSourceData::Property* property = reinterpret_cast(outputValue); + MaterialPropertyValue* property = reinterpret_cast(outputValue); AZ_Assert(property, "Output value for JsonMaterialPropertyValueSerializer can't be null."); JSR::ResultCode result(JSR::Tasks::ReadField); if (inputValue.IsBool()) { - result.Combine(LoadVariant(property->m_value, false, inputValue, context)); + result.Combine(LoadVariant(*property, false, inputValue, context)); } else if (inputValue.IsInt() || inputValue.IsInt64()) { - result.Combine(LoadVariant(property->m_value, 0, inputValue, context)); + result.Combine(LoadVariant(*property, 0, inputValue, context)); } else if (inputValue.IsUint() || inputValue.IsUint64()) { - result.Combine(LoadVariant(property->m_value, 0u, inputValue, context)); + result.Combine(LoadVariant(*property, 0u, inputValue, context)); } else if (inputValue.IsFloat() || inputValue.IsDouble()) { - result.Combine(LoadVariant(property->m_value, 0.0f, inputValue, context)); + result.Combine(LoadVariant(*property, 0.0f, inputValue, context)); } else if (inputValue.IsArray() && inputValue.Size() == 4) { - result.Combine(LoadVariant(property->m_value, Vector4{0.0f, 0.0f, 0.0f, 0.0f}, inputValue, context)); + result.Combine(LoadVariant(*property, Vector4{0.0f, 0.0f, 0.0f, 0.0f}, inputValue, context)); } else if (inputValue.IsArray() && inputValue.Size() == 3) { - result.Combine(LoadVariant(property->m_value, Vector3{0.0f, 0.0f, 0.0f}, inputValue, context)); + result.Combine(LoadVariant(*property, Vector3{0.0f, 0.0f, 0.0f}, inputValue, context)); } else if (inputValue.IsArray() && inputValue.Size() == 2) { - result.Combine(LoadVariant(property->m_value, Vector2{0.0f, 0.0f}, inputValue, context)); + result.Combine(LoadVariant(*property, Vector2{0.0f, 0.0f}, inputValue, context)); } else if (inputValue.IsObject()) { - JsonSerializationResult::ResultCode resultCode = LoadVariant(property->m_value, Color::CreateZero(), inputValue, context); + JsonSerializationResult::ResultCode resultCode = LoadVariant(*property, Color::CreateZero(), inputValue, context); if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed) { - resultCode = LoadVariant(property->m_value, Vector4::CreateZero(), inputValue, context); + resultCode = LoadVariant(*property, Vector4::CreateZero(), inputValue, context); } if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed) { - resultCode = LoadVariant(property->m_value, Vector3::CreateZero(), inputValue, context); + resultCode = LoadVariant(*property, Vector3::CreateZero(), inputValue, context); } if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed) { - resultCode = LoadVariant(property->m_value, Vector2::CreateZero(), inputValue, context); + resultCode = LoadVariant(*property, Vector2::CreateZero(), inputValue, context); } if(resultCode.GetProcessing() == JsonSerializationResult::Processing::Completed) @@ -115,7 +115,7 @@ namespace AZ } else if (inputValue.IsString()) { - result.Combine(LoadVariant(property->m_value, AZStd::string{}, inputValue, context)); + result.Combine(LoadVariant(*property, AZStd::string{}, inputValue, context)); } else { @@ -137,51 +137,51 @@ namespace AZ { namespace JSR = JsonSerializationResult; - AZ_Assert(azrtti_typeid() == valueTypeId, + AZ_Assert(azrtti_typeid() == valueTypeId, "Unable to serialize material property value to json because the provided type is %s", valueTypeId.ToString().c_str()); AZ_UNUSED(valueTypeId); - const MaterialSourceData::Property* property = reinterpret_cast(inputValue); + const MaterialPropertyValue* property = reinterpret_cast(inputValue); AZ_Assert(property, "Input value for JsonMaterialPropertyValueSerializer can't be null."); JSR::ResultCode result(JSR::Tasks::WriteValue); - if (property->m_value.Is()) + if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } - else if (property->m_value.Is()) + else if (property->Is()) { - result.Combine(ContinueStoring(outputValue, &property->m_value.GetValue(), nullptr, azrtti_typeid(), context)); + result.Combine(ContinueStoring(outputValue, &property->GetValue(), nullptr, azrtti_typeid(), context)); } if (result.GetProcessing() == JsonSerializationResult::Processing::Completed) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index ae7889aa93..c2b80e726b 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -44,7 +44,7 @@ namespace AZ { if (JsonRegistrationContext* jsonContext = azrtti_cast(context)) { - jsonContext->Serializer()->HandlesType(); + jsonContext->Serializer()->HandlesType(); } else if (auto* serializeContext = azrtti_cast(context)) { @@ -59,10 +59,6 @@ namespace AZ serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); - - serializeContext->Class() - ->Version(1) - ; } } @@ -323,25 +319,25 @@ namespace AZ for (auto& property : group.second) { MaterialPropertyId propertyId{ group.first, property.first }; - if (!property.second.m_value.IsValid()) + if (!property.second.IsValid()) { materialAssetCreator.ReportWarning("Source data for material property value is invalid."); } // If the source value type is a string, there are two possible property types: Image and Enum. If there is a "." in // the string (for the extension) we assume it's an Image and look up the referenced Asset. Otherwise, we can assume // it's an Enum value and just preserve the original string. - else if (property.second.m_value.Is() && AzFramework::StringFunc::Contains(property.second.m_value.GetValue(), ".")) + else if (property.second.Is() && AzFramework::StringFunc::Contains(property.second.GetValue(), ".")) { Data::Asset imageAsset; MaterialUtils::GetImageAssetResult result = MaterialUtils::GetImageAssetReference( - imageAsset, materialSourceFilePath, property.second.m_value.GetValue()); + imageAsset, materialSourceFilePath, property.second.GetValue()); if (result == MaterialUtils::GetImageAssetResult::Missing) { materialAssetCreator.ReportWarning( "Material property '%s': Could not find the image '%s'", propertyId.GetCStr(), - property.second.m_value.GetValue().data()); + property.second.GetValue().data()); } imageAsset.SetAutoLoadBehavior(Data::AssetLoadBehavior::PreLoad); @@ -349,7 +345,7 @@ namespace AZ } else { - materialAssetCreator.SetPropertyValue(propertyId, property.second.m_value); + materialAssetCreator.SetPropertyValue(propertyId, property.second); } } } diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index 2bd257d55b..2ac363058c 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -160,7 +160,7 @@ namespace UnitTest void AddProperty(MaterialSourceData& material, AZStd::string_view groupName, AZStd::string_view propertyName, const MaterialPropertyValue& anyValue) { - material.m_properties[groupName][propertyName].m_value = anyValue; + material.m_properties[groupName][propertyName] = anyValue; } TEST_F(MaterialSourceDataTests, CreateMaterialAsset_BasicProperties) @@ -398,33 +398,33 @@ namespace UnitTest // We allow some types like Vector4 and Color or Int and UInt to be interchangeable since they serialize the same and can be converted when the MaterialAsset is finalized. - if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_EQ(propertyA.m_value.GetValue(), propertyB.m_value.GetValue()) << propertyReference.c_str(); + EXPECT_EQ(propertyA.GetValue(), propertyB.GetValue()) << propertyReference.c_str(); } - else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + else if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_EQ(GetAsInt(propertyA.m_value), GetAsInt(propertyB.m_value)) << propertyReference.c_str(); + EXPECT_EQ(GetAsInt(propertyA), GetAsInt(propertyB)) << propertyReference.c_str(); } - else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + else if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_NEAR(propertyA.m_value.GetValue(), propertyB.m_value.GetValue(), 0.01) << propertyReference.c_str(); + EXPECT_NEAR(propertyA.GetValue(), propertyB.GetValue(), 0.01) << propertyReference.c_str(); } - else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + else if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); + EXPECT_TRUE(propertyA.GetValue().IsClose(propertyB.GetValue())) << propertyReference.c_str(); } - else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + else if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); + EXPECT_TRUE(propertyA.GetValue().IsClose(propertyB.GetValue())) << propertyReference.c_str(); } - else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + else if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_TRUE(GetAsVector4(propertyA.m_value).IsClose(GetAsVector4(propertyB.m_value))) << propertyReference.c_str(); + EXPECT_TRUE(GetAsVector4(propertyA).IsClose(GetAsVector4(propertyB))) << propertyReference.c_str(); } - else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + else if (AreTypesCompatible(propertyA, propertyB)) { - EXPECT_STREQ(propertyA.m_value.GetValue().c_str(), propertyB.m_value.GetValue().c_str()) << propertyReference.c_str(); + EXPECT_STREQ(propertyA.GetValue().c_str(), propertyB.GetValue().c_str()) << propertyReference.c_str(); } else { @@ -513,7 +513,7 @@ namespace UnitTest EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - float testValue = material.m_properties["general"]["testValue"].m_value.GetValue(); + float testValue = material.m_properties["general"]["testValue"].GetValue(); EXPECT_FLOAT_EQ(1.2f, testValue); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp index 283b7a8a7f..28de56c75e 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp @@ -363,7 +363,7 @@ namespace MaterialEditor // TODO: Support populating the Material Editor with nested property groups, not just the top level. const AZStd::string groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1); - sourceData.m_properties[groupName][propertyDefinition->GetName()].m_value = propertyValue; + sourceData.m_properties[groupName][propertyDefinition->GetName()] = propertyValue; } } return true; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp index dde9644c50..1e5e25fa30 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp @@ -150,7 +150,7 @@ namespace AZ // TODO: Support populating the Material Editor with nested property groups, not just the top level. const AZStd::string groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1); - exportData.m_properties[groupName][propertyDefinition->GetName()].m_value = propertyValue; + exportData.m_properties[groupName][propertyDefinition->GetName()] = propertyValue; return true; }); From 1daa9fbbed4e72a1ce2b3c44f89630d7d238e6e7 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 4 Feb 2022 12:04:50 -0800 Subject: [PATCH 05/24] Changed the .material file format to use a flat list for material property values, instead of a tree structure. This is needed to support deeply nested material property groups, it just makes the serialization code a lot simpler than trying to support nested groups in the .material file. It also makes the file more readable and easier to search all files for particular properties. I also updated MaterialSourceData to hide the property values behind a clean API. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../MaterialConverterSystemComponent.cpp | 19 +- .../RPI.Edit/Material/MaterialSourceData.h | 26 +- .../Material/MaterialTypeSourceData.h | 4 +- .../Atom/RPI.Edit/Material/MaterialUtils.h | 6 +- .../RPI.Builders/Material/MaterialBuilder.cpp | 36 +- .../RPI.Edit/Material/MaterialSourceData.cpp | 81 ++- .../Material/MaterialTypeSourceData.cpp | 6 +- .../RPI.Edit/Material/MaterialUtils.cpp | 43 +- .../Material/MaterialSourceDataTests.cpp | 464 ++++++++++++++---- .../Code/Source/Document/MaterialDocument.cpp | 14 +- .../Material/EditorMaterialComponentUtil.cpp | 4 +- 11 files changed, 535 insertions(+), 168 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp index 835aa90ceb..680ad5f690 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp @@ -82,9 +82,8 @@ namespace AZ // The source data for generating material asset sourceData.m_materialType = GetMaterialTypePath(); - auto handleTexture = [&materialData, &sourceData]( - const char* propertyTextureGroup, SceneAPI::DataTypes::IMaterialData::TextureMapType textureType) { - MaterialSourceData::PropertyMap& properties = sourceData.m_properties[propertyTextureGroup]; + auto handleTexture = [&materialData, &sourceData](const char* propertyTextureGroup, SceneAPI::DataTypes::IMaterialData::TextureMapType textureType) + { const AZStd::string& texturePath = materialData.GetTexture(textureType); // Check to see if the image asset exists. If not, skip this texture map and just disable it. @@ -101,7 +100,7 @@ namespace AZ if (assetFound) { - properties["textureMap"] = texturePath; + sourceData.SetPropertyValue(MaterialPropertyId{propertyTextureGroup, "textureMap"}, texturePath); } else if (!texturePath.empty()) { @@ -120,7 +119,7 @@ namespace AZ { anyPBRInUse = true; handleTexture("baseColor", SceneAPI::DataTypes::IMaterialData::TextureMapType::BaseColor); - sourceData.m_properties["baseColor"]["textureBlendMode"] = AZStd::string("Lerp"); + sourceData.SetPropertyValue(Name{"baseColor.textureBlendMode"}, AZStd::string("Lerp")); } else { @@ -135,10 +134,10 @@ namespace AZ if (baseColor.has_value()) { anyPBRInUse = true; - sourceData.m_properties["baseColor"]["color"] = toColor(baseColor.value()); + sourceData.SetPropertyValue(Name{"baseColor.color"}, toColor(baseColor.value())); } - sourceData.m_properties["opacity"]["factor"] = materialData.GetOpacity(); + sourceData.SetPropertyValue(Name{"opacity.factor"}, materialData.GetOpacity()); auto applyOptionalPropertiesFunc = [&sourceData, &anyPBRInUse](const auto& propertyGroup, const auto& propertyName, const auto& propertyOptional) { @@ -147,7 +146,7 @@ namespace AZ if (propertyOptional.has_value()) { anyPBRInUse = true; - sourceData.m_properties[propertyGroup][propertyName] = propertyOptional.value(); + sourceData.SetPropertyValue(MaterialPropertyId{propertyGroup, propertyName}, propertyOptional.value()); } }; @@ -160,7 +159,7 @@ namespace AZ applyOptionalPropertiesFunc("roughness", "useTexture", materialData.GetUseRoughnessMap()); handleTexture("emissive", SceneAPI::DataTypes::IMaterialData::TextureMapType::Emissive); - sourceData.m_properties["emissive"]["color"] = toColor(materialData.GetEmissiveColor()); + sourceData.SetPropertyValue(Name{"emissive.color"}, toColor(materialData.GetEmissiveColor())); applyOptionalPropertiesFunc("emissive", "intensity", materialData.GetEmissiveIntensity()); applyOptionalPropertiesFunc("emissive", "useTexture", materialData.GetUseEmissiveMap()); @@ -171,7 +170,7 @@ namespace AZ { // If it doesn't have the useColorMap property, then it's a non-PBR material and the baseColor // texture needs to be set to the diffuse color. - sourceData.m_properties["baseColor"]["color"] = toColor(materialData.GetDiffuseColor()); + sourceData.SetPropertyValue(Name{"baseColor.color"}, toColor(materialData.GetDiffuseColor())); } return true; } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h index 8b782fe66c..b8c613fd12 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h @@ -59,17 +59,25 @@ namespace AZ uint32_t m_materialTypeVersion = 0; //!< The version of the material type that was used to configure this material - using PropertyMap = AZStd::map; - using PropertyGroupMap = AZStd::map; - - PropertyGroupMap m_properties; - enum class ApplyVersionUpdatesResult { Failed, NoUpdates, UpdatesApplied }; + + //! If the data was loaded from an old format file (i.e. where "properties" was a tree with property values nested under groups), + //! this converts to the new format where properties are stored in a flat list. + void ConvertToNewDataFormat(); + + // Note that even though we use an unordered map, the JSON serialization system is nice enough to sort the data when saving to JSON. + using PropertyValueMap = AZStd::unordered_map; + + void SetPropertyValue(const Name& propertyId, const MaterialPropertyValue& value); + const MaterialPropertyValue& GetPropertyValue(const Name& propertyId) const; + PropertyValueMap GetPropertyValues() const; + bool HasPropertyValue(const Name& propertyId) const; + void RemovePropertyValue(const Name& propertyId); //! Creates a MaterialAsset from the MaterialSourceData content. //! @param assetId ID for the MaterialAsset @@ -96,8 +104,16 @@ namespace AZ AZStd::unordered_set* sourceDependencies = nullptr) const; private: + void ApplyPropertiesToAssetCreator( AZ::RPI::MaterialAssetCreator& materialAssetCreator, const AZStd::string_view& materialSourceFilePath) const; + + // @deprecated: Don't use "properties" in JSON, use "propertyValues" instead. + using PropertyGroupMap = AZStd::unordered_map; + PropertyGroupMap m_propertiesOld; + + PropertyValueMap m_propertyValues; + MaterialPropertyValue m_invalidValue; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h index 79c73495e0..23219cfa89 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h @@ -216,11 +216,11 @@ namespace AZ //! This field is unused, and has been replaced by MaterialTypeSourceData::m_version below. It is kept for legacy file compatibility to suppress warnings and errors. uint32_t m_versionOld = 0; - //! [Deprecated] Use m_propertyGroups instead + //! @deprecated: Use m_propertyGroups instead //! List of groups that will contain the available properties AZStd::vector m_groupsOld; - //! [Deprecated] Use m_propertyGroups instead + //! @deprecated: Use m_propertyGroups instead AZStd::map> m_propertiesOld; //! Collection of all available user-facing properties diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h index 2fb55e5f40..f6c10e003e 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h @@ -24,6 +24,7 @@ namespace AZ namespace RPI { + class MaterialSourceData; class MaterialTypeSourceData; namespace MaterialUtils @@ -48,11 +49,14 @@ namespace AZ //! @return if resolving is successful. An error will be reported if it fails. bool ResolveMaterialPropertyEnumValue(const MaterialPropertyDescriptor* propertyDescriptor, const AZ::Name& enumName, MaterialPropertyValue& outResolvedValue); - //! Load material type from a json file. If the file path is relative, the loaded json document must be provided. + //! Load a material type from a json file. If the file path is relative, the loaded json document must be provided. //! Otherwise, it will use the passed in document first if not null, or load the json document from the path. //! @param filePath a relative path if document is provided, an absolute path if document is not provided. //! @param document the loaded json document. AZ::Outcome LoadMaterialTypeSourceData(const AZStd::string& filePath, const rapidjson::Value* document = nullptr); + + //! Load a material from a json file. + AZ::Outcome LoadMaterialSourceData(const AZStd::string& filePath, const rapidjson::Value* document = nullptr, bool warningsAsErrors = false); //! Utility function for custom JSON serializers to report results as "Skipped" when encountering keys that aren't recognized //! as part of the custom format. diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index d55f202c03..bb0330e7b6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -52,7 +52,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 117; // new material type file format + materialBuilderDescriptor.m_version = 119; // new material file format materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); @@ -129,38 +129,6 @@ namespace AZ } } - template - AZ::Outcome LoadSourceData(const rapidjson::Value& value, const AZStd::string& filePath) - { - MaterialSourceDataT material; - - JsonDeserializerSettings settings; - - JsonReportingHelper reportingHelper; - reportingHelper.Attach(settings); - - // This is required by some custom material serializers to support relative path references. - JsonFileLoadContext fileLoadContext; - fileLoadContext.PushFilePath(filePath); - settings.m_metadata.Add(fileLoadContext); - - JsonSerialization::Load(material, value, settings); - - if (reportingHelper.ErrorsReported()) - { - return AZ::Failure(); - } - else if (reportingHelper.WarningsReported()) - { - AZ_Error(MaterialBuilderName, false, "Warnings reported while loading '%s'", filePath.c_str()); - return AZ::Failure(); - } - else - { - return AZ::Success(AZStd::move(material)); - } - } - void MaterialBuilder::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) const { if (m_isShuttingDown) @@ -295,7 +263,7 @@ namespace AZ AZ::Data::Asset MaterialBuilder::CreateMaterialAsset(AZStd::string_view materialSourceFilePath, const rapidjson::Value& json) const { - auto material = LoadSourceData(json, materialSourceFilePath); + auto material = MaterialUtils::LoadMaterialSourceData(materialSourceFilePath, &json, true); if (!material.IsSuccess()) { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index c2b80e726b..e5092b5480 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -54,10 +54,11 @@ namespace AZ ->Field("materialType", &MaterialSourceData::m_materialType) ->Field("materialTypeVersion", &MaterialSourceData::m_materialTypeVersion) ->Field("parentMaterial", &MaterialSourceData::m_parentMaterial) - ->Field("properties", &MaterialSourceData::m_properties) + ->Field("properties", &MaterialSourceData::m_propertiesOld) + ->Field("propertyValues", &MaterialSourceData::m_propertyValues) ; - serializeContext->RegisterGenericType(); + serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); } } @@ -73,6 +74,55 @@ namespace AZ } } + void MaterialSourceData::SetPropertyValue(const Name& propertyId, const MaterialPropertyValue& value) + { + if (!propertyId.IsEmpty()) + { + m_propertyValues[propertyId] = value; + } + } + + const MaterialPropertyValue& MaterialSourceData::GetPropertyValue(const Name& propertyId) const + { + auto iter = m_propertyValues.find(propertyId); + if (iter == m_propertyValues.end()) + { + return m_invalidValue; + } + else + { + return iter->second; + } + } + + void MaterialSourceData::RemovePropertyValue(const Name& propertyId) + { + m_propertyValues.erase(propertyId); + } + + MaterialSourceData::PropertyValueMap MaterialSourceData::GetPropertyValues() const + { + return m_propertyValues; + } + + bool MaterialSourceData::HasPropertyValue(const Name& propertyId) const + { + return m_propertyValues.find(propertyId) != m_propertyValues.end(); + } + + void MaterialSourceData::ConvertToNewDataFormat() + { + for (auto& [groupName, propertyList] : m_propertiesOld) + { + for (auto& [propertyName, propertyValue] : propertyList) + { + SetPropertyValue(MaterialPropertyId{groupName, propertyName}, propertyValue); + } + } + + m_propertiesOld.clear(); + } + Outcome> MaterialSourceData::CreateMaterialAsset( Data::AssetId assetId, AZStd::string_view materialSourceFilePath, MaterialAssetProcessingMode processingMode, bool elevateWarnings) const { @@ -250,12 +300,14 @@ namespace AZ return Failure(); } - MaterialSourceData parentSourceData; - if (!AZ::RPI::JsonUtils::LoadObjectFromFile(parentSourceAbsPath, parentSourceData)) + auto loadParentResult = MaterialUtils::LoadMaterialSourceData(parentSourceAbsPath); + if (!loadParentResult) { AZ_Error("MaterialSourceData", false, "Failed to load MaterialSourceData for parent material: '%s'.", parentSourceAbsPath.c_str()); return Failure(); } + + MaterialSourceData parentSourceData = loadParentResult.TakeValue(); // Make sure that all materials in the hierarchy share the same material type const auto parentTypeAssetId = AssetUtils::MakeAssetId(parentSourceAbsPath, parentSourceData.m_materialType, 0); @@ -314,30 +366,29 @@ namespace AZ void MaterialSourceData::ApplyPropertiesToAssetCreator( AZ::RPI::MaterialAssetCreator& materialAssetCreator, const AZStd::string_view& materialSourceFilePath) const { - for (auto& group : m_properties) + for (auto& [propertyId, propertyValue] : m_propertyValues) { - for (auto& property : group.second) + if (!propertyValue.IsValid()) + { + materialAssetCreator.ReportWarning("Source data for material property value is invalid."); + } + else { - MaterialPropertyId propertyId{ group.first, property.first }; - if (!property.second.IsValid()) - { - materialAssetCreator.ReportWarning("Source data for material property value is invalid."); - } // If the source value type is a string, there are two possible property types: Image and Enum. If there is a "." in // the string (for the extension) we assume it's an Image and look up the referenced Asset. Otherwise, we can assume // it's an Enum value and just preserve the original string. - else if (property.second.Is() && AzFramework::StringFunc::Contains(property.second.GetValue(), ".")) + if (propertyValue.Is() && AzFramework::StringFunc::Contains(propertyValue.GetValue(), ".")) { Data::Asset imageAsset; MaterialUtils::GetImageAssetResult result = MaterialUtils::GetImageAssetReference( - imageAsset, materialSourceFilePath, property.second.GetValue()); + imageAsset, materialSourceFilePath, propertyValue.GetValue()); if (result == MaterialUtils::GetImageAssetResult::Missing) { materialAssetCreator.ReportWarning( "Material property '%s': Could not find the image '%s'", propertyId.GetCStr(), - property.second.GetValue().data()); + propertyValue.GetValue().data()); } imageAsset.SetAutoLoadBehavior(Data::AssetLoadBehavior::PreLoad); @@ -345,7 +396,7 @@ namespace AZ } else { - materialAssetCreator.SetPropertyValue(propertyId, property.second); + materialAssetCreator.SetPropertyValue(propertyId, propertyValue); } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp index b9a5754732..23976cf357 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp @@ -100,9 +100,9 @@ namespace AZ serializeContext->Class() ->Version(3) // Added propertyGroups - ->Field("version", &PropertyLayout::m_versionOld) //< Deprecated, preserved for backward compatibility, replaced by MaterialTypeSourceData::version - ->Field("groups", &PropertyLayout::m_groupsOld) //< Deprecated, preserved for backward compatibility, replaced by propertyGroups - ->Field("properties", &PropertyLayout::m_propertiesOld) //< Deprecated, preserved for backward compatibility, replaced by propertyGroups + ->Field("version", &PropertyLayout::m_versionOld) //< @deprecated: preserved for backward compatibility, replaced by MaterialTypeSourceData::version + ->Field("groups", &PropertyLayout::m_groupsOld) //< @deprecated: preserved for backward compatibility, replaced by propertyGroups + ->Field("properties", &PropertyLayout::m_propertiesOld) //< @deprecated: preserved for backward compatibility, replaced by propertyGroups ->Field("propertyGroups", &PropertyLayout::m_propertyGroups) ; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp index b03771173f..3855a0a222 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +83,7 @@ namespace AZ loadOutcome = AZ::JsonSerializationUtils::ReadJsonFile(filePath, AZ::RPI::JsonUtils::DefaultMaxFileSize); if (!loadOutcome.IsSuccess()) { - AZ_Error("AZ::RPI::JsonUtils", false, "%s", loadOutcome.GetError().c_str()); + AZ_Error("MaterialUtils", false, "%s", loadOutcome.GetError().c_str()); return AZ::Failure(); } @@ -114,6 +115,46 @@ namespace AZ return AZ::Success(AZStd::move(materialType)); } } + + AZ::Outcome LoadMaterialSourceData(const AZStd::string& filePath, const rapidjson::Value* document, bool warningsAsErrors) + { + AZ::Outcome loadOutcome; + if (document == nullptr) + { + loadOutcome = AZ::JsonSerializationUtils::ReadJsonFile(filePath, AZ::RPI::JsonUtils::DefaultMaxFileSize); + if (!loadOutcome.IsSuccess()) + { + AZ_Error("MaterialUtils", false, "%s", loadOutcome.GetError().c_str()); + return AZ::Failure(); + } + + document = &loadOutcome.GetValue(); + } + + MaterialSourceData material; + + JsonDeserializerSettings settings; + + JsonReportingHelper reportingHelper; + reportingHelper.Attach(settings); + + JsonSerialization::Load(material, *document, settings); + material.ConvertToNewDataFormat(); + + if (reportingHelper.ErrorsReported()) + { + return AZ::Failure(); + } + else if (warningsAsErrors && reportingHelper.WarningsReported()) + { + AZ_Error("MaterialUtils", false, "Warnings reported while loading '%s'", filePath.c_str()); + return AZ::Failure(); + } + else + { + return AZ::Success(AZStd::move(material)); + } + } void CheckForUnrecognizedJsonFields(const AZStd::string_view* acceptedFieldNames, uint32_t acceptedFieldNameCount, const rapidjson::Value& object, JsonDeserializerContext& context, JsonSerializationResult::ResultCode &result) { diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index 2ac363058c..362d7d8b6d 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -86,7 +86,7 @@ namespace UnitTest RPITestFixture::TearDown(); } - + Data::Asset CreateTestMaterialTypeAsset(Data::AssetId assetId) { const char* materialTypeJson = R"( @@ -146,21 +146,21 @@ namespace UnitTest } )"; - MaterialTypeSourceData materialTypeSourceData; LoadTestDataFromJson(materialTypeSourceData, materialTypeJson); return materialTypeSourceData.CreateMaterialTypeAsset(assetId).TakeValue(); } }; - void AddPropertyGroup(MaterialSourceData& material, AZStd::string_view groupName) + void AddPropertyGroup(MaterialSourceData&, AZStd::string_view) { - material.m_properties.insert(groupName); + // Old function, left blank intentionally } - void AddProperty(MaterialSourceData& material, AZStd::string_view groupName, AZStd::string_view propertyName, const MaterialPropertyValue& anyValue) + void AddProperty(MaterialSourceData& material, AZStd::string_view groupName, AZStd::string_view propertyName, const MaterialPropertyValue& value) { - material.m_properties[groupName][propertyName] = anyValue; + MaterialPropertyId id{groupName, propertyName}; + material.SetPropertyValue(id, value); } TEST_F(MaterialSourceDataTests, CreateMaterialAsset_BasicProperties) @@ -359,80 +359,61 @@ namespace UnitTest void CheckEqual(MaterialSourceData& a, MaterialSourceData& b) { - EXPECT_STREQ(a.m_materialType.data(), b.m_materialType.data()); - EXPECT_STREQ(a.m_description.data(), b.m_description.data()); - EXPECT_STREQ(a.m_parentMaterial.data(), b.m_parentMaterial.data()); + EXPECT_STREQ(a.m_materialType.c_str(), b.m_materialType.c_str()); + EXPECT_STREQ(a.m_description.c_str(), b.m_description.c_str()); + EXPECT_STREQ(a.m_parentMaterial.c_str(), b.m_parentMaterial.c_str()); EXPECT_EQ(a.m_materialTypeVersion, b.m_materialTypeVersion); - EXPECT_EQ(a.m_properties.size(), b.m_properties.size()); - for (auto& groupA : a.m_properties) - { - AZStd::string groupName = groupA.first; + EXPECT_EQ(a.GetPropertyValues().size(), b.GetPropertyValues().size()); - auto groupIterB = b.m_properties.find(groupName); - if (groupIterB == b.m_properties.end()) + for (auto& [propertyId, propertyValue] : a.GetPropertyValues()) + { + if (!b.HasPropertyValue(propertyId)) { - EXPECT_TRUE(false) << "groupB[" << groupName.c_str() << "] not found"; + EXPECT_TRUE(false) << "Property '" << propertyId.GetCStr() << "' not found in material B"; continue; } - auto& groupB = *groupIterB; - - EXPECT_EQ(groupA.second.size(), groupB.second.size()) << " for group[" << groupName.c_str() << "]"; - - for (auto& propertyIterA : groupA.second) - { - AZStd::string propertyName = propertyIterA.first; + auto& propertyA = propertyValue; + auto& propertyB = b.GetPropertyValue(propertyId); - auto propertyIterB = groupB.second.find(propertyName); - if (propertyIterB == groupB.second.end()) - { - EXPECT_TRUE(false) << "groupB[" << groupName.c_str() << "][" << propertyName.c_str() << "] not found"; - continue; - } - - auto& propertyA = propertyIterA.second; - auto& propertyB = propertyIterB->second; - - AZStd::string propertyReference = AZStd::string::format(" for property '%s.%s'", groupName.c_str(), propertyName.c_str()); + AZStd::string propertyReference = AZStd::string::format(" for property '%s'", propertyId.GetCStr()); - // We allow some types like Vector4 and Color or Int and UInt to be interchangeable since they serialize the same and can be converted when the MaterialAsset is finalized. + // We allow some types like Vector4 and Color or Int and UInt to be interchangeable since they serialize the same and can be converted when the MaterialAsset is finalized. - if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_EQ(propertyA.GetValue(), propertyB.GetValue()) << propertyReference.c_str(); - } - else if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_EQ(GetAsInt(propertyA), GetAsInt(propertyB)) << propertyReference.c_str(); - } - else if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_NEAR(propertyA.GetValue(), propertyB.GetValue(), 0.01) << propertyReference.c_str(); - } - else if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_TRUE(propertyA.GetValue().IsClose(propertyB.GetValue())) << propertyReference.c_str(); - } - else if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_TRUE(propertyA.GetValue().IsClose(propertyB.GetValue())) << propertyReference.c_str(); - } - else if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_TRUE(GetAsVector4(propertyA).IsClose(GetAsVector4(propertyB))) << propertyReference.c_str(); - } - else if (AreTypesCompatible(propertyA, propertyB)) - { - EXPECT_STREQ(propertyA.GetValue().c_str(), propertyB.GetValue().c_str()) << propertyReference.c_str(); - } - else - { - ADD_FAILURE(); - } + if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_EQ(propertyA.GetValue(), propertyB.GetValue()) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_EQ(GetAsInt(propertyA), GetAsInt(propertyB)) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_NEAR(propertyA.GetValue(), propertyB.GetValue(), 0.01) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_TRUE(propertyA.GetValue().IsClose(propertyB.GetValue())) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_TRUE(propertyA.GetValue().IsClose(propertyB.GetValue())) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_TRUE(GetAsVector4(propertyA).IsClose(GetAsVector4(propertyB))) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA, propertyB)) + { + EXPECT_STREQ(propertyA.GetValue().c_str(), propertyB.GetValue().c_str()) << propertyReference.c_str(); + } + else + { + ADD_FAILURE(); } } - } TEST_F(MaterialSourceDataTests, TestJsonRoundTrip) @@ -465,6 +446,88 @@ namespace UnitTest CheckEqual(sourceDataOriginal, sourceDataCopy); } + + TEST_F(MaterialSourceDataTests, TestLoadLegacyFormat) + { + const AZStd::string inputJson = R"( + { + "materialType": "test.materialtype", // Doesn't matter, this isn't loaded + "properties": { + "groupA": { + "myBool": true, + "myInt": 5, + "myFloat": 0.5 + }, + "groupB": { + "myFloat2": [0.1, 0.2], + "myFloat3": [0.3, 0.4, 0.5], + "myFloat4": [0.6, 0.7, 0.8, 0.9], + "myString": "Hello" + } + } + } + )"; + + MaterialSourceData material; + LoadTestDataFromJson(material, inputJson); + material.ConvertToNewDataFormat(); + + MaterialSourceData expectedMaterial; + expectedMaterial.m_materialType = "test.materialtype"; + expectedMaterial.SetPropertyValue(Name{"groupA.myBool"}, true); + expectedMaterial.SetPropertyValue(Name{"groupA.myInt"}, 5); + expectedMaterial.SetPropertyValue(Name{"groupA.myFloat"}, 0.5f); + expectedMaterial.SetPropertyValue(Name{"groupB.myFloat2"}, Vector2(0.1f, 0.2f)); + expectedMaterial.SetPropertyValue(Name{"groupB.myFloat3"}, Vector3(0.3f, 0.4f, 0.5f)); + expectedMaterial.SetPropertyValue(Name{"groupB.myFloat4"}, Vector4(0.6f, 0.7f, 0.8f, 0.9f)); + expectedMaterial.SetPropertyValue(Name{"groupB.myString"}, AZStd::string{"Hello"}); + + CheckEqual(expectedMaterial, material); + } + + TEST_F(MaterialSourceDataTests, TestPropertyValues) + { + MaterialSourceData material; + + Name foo{"foo"}; + Name bar{"bar"}; + Name baz{"baz"}; + + EXPECT_EQ(0, material.GetPropertyValues().size()); + EXPECT_FALSE(material.HasPropertyValue(foo)); + EXPECT_FALSE(material.HasPropertyValue(bar)); + EXPECT_FALSE(material.HasPropertyValue(baz)); + EXPECT_FALSE(material.GetPropertyValue(foo).IsValid()); + EXPECT_FALSE(material.GetPropertyValue(bar).IsValid()); + EXPECT_FALSE(material.GetPropertyValue(baz).IsValid()); + + material.SetPropertyValue(Name{"foo"}, 2); + material.SetPropertyValue(Name{"bar"}, true); + material.SetPropertyValue(Name{"baz"}, 0.5f); + + EXPECT_EQ(3, material.GetPropertyValues().size()); + EXPECT_TRUE(material.HasPropertyValue(foo)); + EXPECT_TRUE(material.HasPropertyValue(bar)); + EXPECT_TRUE(material.HasPropertyValue(baz)); + EXPECT_TRUE(material.GetPropertyValue(foo).IsValid()); + EXPECT_TRUE(material.GetPropertyValue(bar).IsValid()); + EXPECT_TRUE(material.GetPropertyValue(baz).IsValid()); + EXPECT_EQ(material.GetPropertyValue(foo).GetValue(), 2); + EXPECT_EQ(material.GetPropertyValue(bar).GetValue(), true); + EXPECT_EQ(material.GetPropertyValue(baz).GetValue(), 0.5f); + + material.RemovePropertyValue(bar); + + EXPECT_EQ(2, material.GetPropertyValues().size()); + EXPECT_TRUE(material.HasPropertyValue(foo)); + EXPECT_FALSE(material.HasPropertyValue(bar)); + EXPECT_TRUE(material.HasPropertyValue(baz)); + EXPECT_TRUE(material.GetPropertyValue(foo).IsValid()); + EXPECT_FALSE(material.GetPropertyValue(bar).IsValid()); + EXPECT_TRUE(material.GetPropertyValue(baz).IsValid()); + EXPECT_EQ(material.GetPropertyValue(foo).GetValue(), 2); + EXPECT_EQ(material.GetPropertyValue(baz).GetValue(), 0.5f); + } TEST_F(MaterialSourceDataTests, Load_MaterialTypeAfterPropertyList) { @@ -487,21 +550,14 @@ namespace UnitTest } )"; - const char* materialTypeFilePath = "@exefolder@/Temp/simpleMaterialType.materialtype"; - - AZ::IO::FileIOStream file; - EXPECT_TRUE(file.Open(materialTypeFilePath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeCreatePath)); - file.Write(simpleMaterialTypeJson.size(), simpleMaterialTypeJson.data()); - file.Close(); + AZ::Utils::WriteFile(simpleMaterialTypeJson, "@exefolder@/Temp/simpleMaterialType.materialtype"); // It shouldn't matter whether the materialType field appears before the property value list. This allows for the possibility // that customer scripts generate material data and happen to use an unexpected order. const AZStd::string inputJson = R"( { - "properties": { - "general": { - "testValue": 1.2 - } + "propertyValues": { + "general.testValue": 1.2 }, "materialType": "@exefolder@/Temp/simpleMaterialType.materialtype" } @@ -513,7 +569,7 @@ namespace UnitTest EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - float testValue = material.m_properties["general"]["testValue"].GetValue(); + float testValue = material.GetPropertyValue(Name{"general.testValue"}).GetValue(); EXPECT_FLOAT_EQ(1.2f, testValue); } @@ -522,10 +578,8 @@ namespace UnitTest const AZStd::string inputJson = R"( { "materialTypeVersion": 1, - "properties": { - "baseColor": { - "color": [1.0,1.0,1.0] - } + "propertyValues": { + "baseColor.color": [1.0,1.0,1.0] } } )"; @@ -561,10 +615,8 @@ namespace UnitTest { "materialType": "DoesNotExist.materialtype", "materialTypeVersion": 1, - "properties": { - "baseColor": { - "color": [1.0,1.0,1.0] - } + "propertyValues": { + "baseColor.color": [1.0,1.0,1.0] } } )"; @@ -900,10 +952,8 @@ namespace UnitTest const AZStd::string inputJson = AZStd::string::format(R"( { "materialType": "@exefolder@/Temp/test.materialtype", - "properties": { - "%s": { - "%s": %s - } + "propertyValues": { + "%s.%s": %s } } )", groupName, propertyName, jsonValue); @@ -965,7 +1015,239 @@ namespace UnitTest CheckEndToEndDataTypeResolution("MyFloat4", "{\"y\":0.2, \"x\":0.1, \"Z\":0.3}", Vector4{0.1f, 0.2f, 0.3f, 0.0f}); CheckEndToEndDataTypeResolution("MyFloat4", "{\"y\":0.2, \"W\":0.4, \"x\":0.1, \"Z\":0.3}", Vector4{0.1f, 0.2f, 0.3f, 0.4f}); } + + TEST_F(MaterialSourceDataTests, CreateMaterialAssetFromSourceData_MultiLevelDataInheritance) + { + // Note the data being tested here is based on CreateMaterialAsset_MultiLevelDataInheritance() + + const AZStd::string simpleMaterialTypeJson = R"( + { + "propertyLayout": { + "propertyGroups": + [ + { + "name": "general", + "properties": [ + { + "name": "MyFloat", + "type": "Float" + }, + { + "name": "MyFloat2", + "type": "Vector2" + }, + { + "name": "MyColor", + "type": "Color" + } + ] + } + ] + } + } + )"; + + AZ::Utils::WriteFile(simpleMaterialTypeJson, "@exefolder@/Temp/test.materialtype"); + + const AZStd::string material1Json = R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "propertyValues": { + "general.MyFloat": 1.5, + "general.MyColor": [0.1, 0.2, 0.3, 0.4] + } + } + )"; + + AZ::Utils::WriteFile(material1Json, "@exefolder@/Temp/m1.material"); + + const AZStd::string material2Json = R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "parentMaterial": "@exefolder@/Temp/m1.material", + "propertyValues": { + "general.MyFloat2": [4.1, 4.2], + "general.MyColor": [0.15, 0.25, 0.35, 0.45] + } + } + )"; + + AZ::Utils::WriteFile(material2Json, "@exefolder@/Temp/m2.material"); + + const AZStd::string material3Json = R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "parentMaterial": "@exefolder@/Temp/m2.material", + "propertyValues": { + "general.MyFloat": 3.5 + } + } + )"; + + AZ::Utils::WriteFile(material3Json, "@exefolder@/Temp/m3.material"); + + MaterialSourceData sourceDataLevel1 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m1.material").TakeValue(); + MaterialSourceData sourceDataLevel2 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m2.material").TakeValue(); + MaterialSourceData sourceDataLevel3 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m3.material").TakeValue(); + + auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); + EXPECT_TRUE(materialAssetLevel1.IsSuccess()); + EXPECT_TRUE(materialAssetLevel1.GetValue()->WasPreFinalized()); + + auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); + EXPECT_TRUE(materialAssetLevel2.IsSuccess()); + EXPECT_TRUE(materialAssetLevel2.GetValue()->WasPreFinalized()); + + auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); + EXPECT_TRUE(materialAssetLevel3.IsSuccess()); + EXPECT_TRUE(materialAssetLevel3.GetValue()->WasPreFinalized()); + + auto layout = materialAssetLevel1.GetValue()->GetMaterialPropertiesLayout(); + MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat")); + MaterialPropertyIndex myFloat2 = layout->FindPropertyIndex(Name("general.MyFloat2")); + MaterialPropertyIndex myColor = layout->FindPropertyIndex(Name("general.MyColor")); + + AZStd::span properties; + + // Check level 1 properties + properties = materialAssetLevel1.GetValue()->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 1.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(0.0f, 0.0f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.1f, 0.2f, 0.3f, 0.4f)); + + // Check level 2 properties + properties = materialAssetLevel2.GetValue()->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 1.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); + + // Check level 3 properties + properties = materialAssetLevel3.GetValue()->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 3.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); + } + TEST_F(MaterialSourceDataTests, CreateMaterialAssetFromSourceData_MultiLevelDataInheritance_OldFormat) + { + // This test is the same as CreateMaterialAssetFromSourceData_MultiLevelDataInheritance except it uses the old format + // where material property values in the .material file were nested, with properties listed under a group object, + // rather than using a flat list of property values. + // Basically, we are making sure that MaterialSourceData::ConvertToNewDataFormat() is getting called. + + const AZStd::string simpleMaterialTypeJson = R"( + { + "propertyLayout": { + "propertyGroups": + [ + { + "name": "general", + "properties": [ + { + "name": "MyFloat", + "type": "Float" + }, + { + "name": "MyFloat2", + "type": "Vector2" + }, + { + "name": "MyColor", + "type": "Color" + } + ] + } + ] + } + } + )"; + + AZ::Utils::WriteFile(simpleMaterialTypeJson, "@exefolder@/Temp/test.materialtype"); + + const AZStd::string material1Json = R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "properties": { + "general": { + "MyFloat": 1.5, + "MyColor": [0.1, 0.2, 0.3, 0.4] + } + } + } + )"; + + AZ::Utils::WriteFile(material1Json, "@exefolder@/Temp/m1.material"); + + const AZStd::string material2Json = R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "parentMaterial": "@exefolder@/Temp/m1.material", + "properties": { + "general": { + "MyFloat2": [4.1, 4.2], + "MyColor": [0.15, 0.25, 0.35, 0.45] + } + } + } + )"; + + AZ::Utils::WriteFile(material2Json, "@exefolder@/Temp/m2.material"); + + const AZStd::string material3Json = R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "parentMaterial": "@exefolder@/Temp/m2.material", + "properties": { + "general": { + "MyFloat": 3.5 + } + } + } + )"; + + AZ::Utils::WriteFile(material3Json, "@exefolder@/Temp/m3.material"); + + MaterialSourceData sourceDataLevel1 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m1.material").TakeValue(); + MaterialSourceData sourceDataLevel2 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m2.material").TakeValue(); + MaterialSourceData sourceDataLevel3 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m3.material").TakeValue(); + + auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); + EXPECT_TRUE(materialAssetLevel1.IsSuccess()); + EXPECT_TRUE(materialAssetLevel1.GetValue()->WasPreFinalized()); + + auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); + EXPECT_TRUE(materialAssetLevel2.IsSuccess()); + EXPECT_TRUE(materialAssetLevel2.GetValue()->WasPreFinalized()); + + auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); + EXPECT_TRUE(materialAssetLevel3.IsSuccess()); + EXPECT_TRUE(materialAssetLevel3.GetValue()->WasPreFinalized()); + + auto layout = materialAssetLevel1.GetValue()->GetMaterialPropertiesLayout(); + MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat")); + MaterialPropertyIndex myFloat2 = layout->FindPropertyIndex(Name("general.MyFloat2")); + MaterialPropertyIndex myColor = layout->FindPropertyIndex(Name("general.MyColor")); + + AZStd::span properties; + + // Check level 1 properties + properties = materialAssetLevel1.GetValue()->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 1.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(0.0f, 0.0f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.1f, 0.2f, 0.3f, 0.4f)); + + // Check level 2 properties + properties = materialAssetLevel2.GetValue()->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 1.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); + + // Check level 3 properties + properties = materialAssetLevel3.GetValue()->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 3.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); + } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp index 28de56c75e..7490fa5848 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp @@ -362,8 +362,8 @@ namespace MaterialEditor } // TODO: Support populating the Material Editor with nested property groups, not just the top level. - const AZStd::string groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1); - sourceData.m_properties[groupName][propertyDefinition->GetName()] = propertyValue; + AZStd::string_view groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1); + sourceData.SetPropertyValue(AZ::RPI::MaterialPropertyId{groupName, propertyDefinition->GetName()}, propertyValue); } } return true; @@ -395,12 +395,15 @@ namespace MaterialEditor if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::MaterialSourceData::Extension)) { // Load the material source data so that we can check properties and create a material asset from it - if (!AZ::RPI::JsonUtils::LoadObjectFromFile(m_absolutePath, m_materialSourceData)) + auto loadResult = AZ::RPI::MaterialUtils::LoadMaterialSourceData(m_absolutePath); + if (!loadResult) { AZ_Error("MaterialDocument", false, "Material source data could not be loaded: '%s'.", m_absolutePath.c_str()); return OpenFailed(); } + m_materialSourceData = loadResult.TakeValue(); + // We always need the absolute path for the material type and parent material to load source data and resolving // relative paths when saving. This will convert and store them as absolute paths for use within the document. if (!m_materialSourceData.m_parentMaterial.empty()) @@ -482,12 +485,15 @@ namespace MaterialEditor if (!m_materialSourceData.m_parentMaterial.empty()) { AZ::RPI::MaterialSourceData parentMaterialSourceData; - if (!AZ::RPI::JsonUtils::LoadObjectFromFile(m_materialSourceData.m_parentMaterial, parentMaterialSourceData)) + auto loadResult = AZ::RPI::MaterialUtils::LoadMaterialSourceData(m_materialSourceData.m_parentMaterial); + if (!loadResult) { AZ_Error("MaterialDocument", false, "Material parent source data could not be loaded for: '%s'.", m_materialSourceData.m_parentMaterial.c_str()); return OpenFailed(); } + parentMaterialSourceData = loadResult.TakeValue(); + const auto parentMaterialAssetIdResult = AZ::RPI::AssetUtils::MakeAssetId(m_materialSourceData.m_parentMaterial, 0); if (!parentMaterialAssetIdResult) { diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp index 1e5e25fa30..52e22645ca 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp @@ -149,8 +149,8 @@ namespace AZ } // TODO: Support populating the Material Editor with nested property groups, not just the top level. - const AZStd::string groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1); - exportData.m_properties[groupName][propertyDefinition->GetName()] = propertyValue; + AZStd::string_view groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1); + exportData.SetPropertyValue(RPI::MaterialPropertyId{groupName, propertyDefinition->GetName()}, propertyValue); return true; }); From c9a84d08a8e4298d5b7e57af05a3717d26008acb Mon Sep 17 00:00:00 2001 From: scspaldi Date: Fri, 4 Feb 2022 17:16:33 -0800 Subject: [PATCH 06/24] Added server launcher sanity test. Signed-off-by: scspaldi --- Tools/LyTestTools/tests/integ/sanity_tests.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Tools/LyTestTools/tests/integ/sanity_tests.py b/Tools/LyTestTools/tests/integ/sanity_tests.py index 2e46d822c7..f1d39891d3 100755 --- a/Tools/LyTestTools/tests/integ/sanity_tests.py +++ b/Tools/LyTestTools/tests/integ/sanity_tests.py @@ -63,6 +63,35 @@ class TestAutomatedTestingProject(object): # Clean up processes after the test is finished process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) + def test_StartServerLauncher_Sanity(self, project): + """ + The `test_StartServerLauncher_Sanity` test function verifies that the O3DE game client launches successfully. + Start the test by utilizing the `kill_processes_named` function to close any open O3DE processes that may + interfere with the test. The Workspace object emulates the O3DE package by locating the engine and project + directories. The Launcher object controls the O3DE game client and requires a Workspace object for + initialization. Add the `-rhi=Null` arg to the executable call to disable GPU rendering. This allows the + test to run on instances without a GPU. We launch the game client executable and wait for the process to exist. + A try/finally block ensures proper test cleanup if issues occur during the test. + """ + # Kill processes that may interfere with the test + process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) + + try: + # Create the Workspace object + workspace = helpers.create_builtin_workspace(project=project) + + # Create the Launcher object and add args + launcher = launcher_helper.create_dedicated_launcher(workspace) + launcher.args.extend(['-rhi=Null']) + + # Call the game client executable + with launcher.start(): + # Wait for the process to exist + waiter.wait_for(lambda: process_utils.process_exists(f"{project}.ServerLauncher.exe", ignore_extensions=True)) + finally: + # Clean up processes after the test is finished + process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) + def test_StartEditor_Sanity(self, project): """ The `test_StartEditor_Sanity` test function is similar to the previous example with minor adjustments. A From 0f07f581f8ca6eaa8c4645af58578afea40aa972 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Mon, 7 Feb 2022 15:11:03 -0600 Subject: [PATCH 07/24] Atom Tools: replaced document settings with settings registry Signed-off-by: Guthrie Adams --- .../AtomToolsDocumentSystemSettings.h | 30 ------------ .../Application/AtomToolsApplication.cpp | 3 +- .../AssetBrowser/AtomToolsAssetBrowser.cpp | 9 +++- .../AtomToolsDocumentSystemComponent.cpp | 19 +++++--- .../AtomToolsDocumentSystemComponent.h | 2 - .../AtomToolsDocumentSystemSettings.cpp | 47 ------------------- .../Code/atomtoolsframework_files.cmake | 2 - .../Window/SettingsDialog/SettingsWidget.cpp | 16 ------- .../Window/SettingsDialog/SettingsWidget.h | 5 -- 9 files changed, 22 insertions(+), 111 deletions(-) delete mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h delete mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemSettings.cpp diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h deleted file mode 100644 index 9b4c1d77fe..0000000000 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#endif - -namespace AtomToolsFramework -{ - struct AtomToolsDocumentSystemSettings - : public AZ::UserSettings - { - AZ_RTTI(AtomToolsDocumentSystemSettings, "{9E576D4F-A74A-4326-9135-C07284D0A3B9}", AZ::UserSettings); - AZ_CLASS_ALLOCATOR(AtomToolsDocumentSystemSettings, AZ::SystemAllocator, 0); - - static void Reflect(AZ::ReflectContext* context); - - bool m_showReloadDocumentPrompt = true; - }; -} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 150b06cabd..4ba1d04b71 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -189,8 +189,9 @@ namespace AtomToolsFramework AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast( &AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); + const bool enableSourceControl = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/EnableSourceControl", true); AzToolsFramework::SourceControlConnectionRequestBus::Broadcast( - &AzToolsFramework::SourceControlConnectionRequests::EnableSourceControl, true); + &AzToolsFramework::SourceControlConnectionRequests::EnableSourceControl, enableSourceControl); if (!AZ::RPI::RPISystemInterface::Get()->IsInitialized()) { diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp index 4270cb87fe..8394efa46f 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -103,8 +104,12 @@ namespace AtomToolsFramework { const AZStd::vector entries = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets(); - const int multiSelectPromptThreshold = 10; - if (entries.size() >= multiSelectPromptThreshold) + const bool promptToOpenMultipleFiles = + GetSettingOrDefault("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFiles", true); + const AZ::u64 promptToOpenMultipleFilesThreshold = + GetSettingOrDefault("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFilesThreshold", 10); + + if (promptToOpenMultipleFiles && promptToOpenMultipleFilesThreshold <= entries.size()) { QMessageBox::StandardButton result = QMessageBox::question( QApplication::activeWindow(), diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp index c05bb56391..329bc1b1b3 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -35,8 +34,6 @@ namespace AtomToolsFramework void AtomToolsDocumentSystemComponent::Reflect(AZ::ReflectContext* context) { - AtomToolsDocumentSystemSettings::Reflect(context); - if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() @@ -113,7 +110,6 @@ namespace AtomToolsFramework void AtomToolsDocumentSystemComponent::Activate() { m_documentMap.clear(); - m_settings = AZ::UserSettings::CreateFind(AZ_CRC_CE("AtomToolsDocumentSystemSettings"), AZ::UserSettings::CT_GLOBAL); AtomToolsDocumentSystemRequestBus::Handler::BusConnect(); AtomToolsDocumentNotificationBus::Handler::BusConnect(); } @@ -178,6 +174,17 @@ namespace AtomToolsFramework void AtomToolsDocumentSystemComponent::ReopenDocuments() { + const bool enableHotReload = GetSettingOrDefault("/O3DE/AtomToolsFramework/DocumentSystem/EnableHotReload", true); + if (!enableHotReload) + { + m_documentIdsWithDependencyChanges.clear(); + m_documentIdsWithExternalChanges.clear(); + m_queueReopenDocuments = false; + } + + const bool enableHotReloadPrompts = + GetSettingOrDefault("/O3DE/AtomToolsFramework/DocumentSystem/EnableHotReloadPrompts", true); + for (const AZ::Uuid& documentId : m_documentIdsWithExternalChanges) { m_documentIdsWithDependencyChanges.erase(documentId); @@ -185,7 +192,7 @@ namespace AtomToolsFramework AZStd::string documentPath; AtomToolsDocumentRequestBus::EventResult(documentPath, documentId, &AtomToolsDocumentRequestBus::Events::GetAbsolutePath); - if (m_settings->m_showReloadDocumentPrompt && + if (enableHotReloadPrompts && (QMessageBox::question(QApplication::activeWindow(), QString("Document was externally modified"), QString("Would you like to reopen the document:\n%1?").arg(documentPath.c_str()), @@ -212,7 +219,7 @@ namespace AtomToolsFramework AZStd::string documentPath; AtomToolsDocumentRequestBus::EventResult(documentPath, documentId, &AtomToolsDocumentRequestBus::Events::GetAbsolutePath); - if (m_settings->m_showReloadDocumentPrompt && + if (enableHotReloadPrompts && (QMessageBox::question(QApplication::activeWindow(), QString("Document dependencies have changed"), QString("Would you like to update the document with these changes:\n%1?").arg(documentPath.c_str()), diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h index 5c7454e5c7..5eb531ef25 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h @@ -15,7 +15,6 @@ #include #include #include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include @@ -79,7 +78,6 @@ namespace AtomToolsFramework AZ::Uuid OpenDocumentImpl(AZStd::string_view sourcePath, bool checkIfAlreadyOpen); - AZStd::intrusive_ptr m_settings; AZStd::function m_documentCreator; AZStd::unordered_map> m_documentMap; AZStd::unordered_set m_documentIdsWithExternalChanges; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemSettings.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemSettings.cpp deleted file mode 100644 index 94af43e524..0000000000 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemSettings.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include - -namespace AtomToolsFramework -{ - void AtomToolsDocumentSystemSettings::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("showReloadDocumentPrompt", &AtomToolsDocumentSystemSettings::m_showReloadDocumentPrompt) - ; - - if (auto editContext = serializeContext->GetEditContext()) - { - editContext->Class( - "AtomToolsDocumentSystemSettings", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &AtomToolsDocumentSystemSettings::m_showReloadDocumentPrompt, "Show Reload Document Prompt", "") - ; - } - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->Class("AtomToolsDocumentSystemSettings") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "atomtools") - ->Constructor() - ->Constructor() - ->Property("showReloadDocumentPrompt", BehaviorValueProperty(&AtomToolsDocumentSystemSettings::m_showReloadDocumentPrompt)) - ; - } - } -} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index b7f9882e92..041e6e1807 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -17,7 +17,6 @@ set(FILES Include/AtomToolsFramework/Document/AtomToolsDocument.h Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h Include/AtomToolsFramework/Document/AtomToolsDocumentMainWindow.h - Include/AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h Include/AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h Include/AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h Include/AtomToolsFramework/Document/AtomToolsDocumentRequestBus.h @@ -54,7 +53,6 @@ set(FILES Source/Document/AtomToolsDocument.cpp Source/Document/AtomToolsDocumentApplication.cpp Source/Document/AtomToolsDocumentMainWindow.cpp - Source/Document/AtomToolsDocumentSystemSettings.cpp Source/Document/AtomToolsDocumentSystemComponent.cpp Source/Document/AtomToolsDocumentSystemComponent.h Source/DynamicProperty/DynamicProperty.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp index 357dfc37e0..8bf4191432 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp @@ -14,8 +14,6 @@ namespace MaterialEditor SettingsWidget::SettingsWidget(QWidget* parent) : AtomToolsFramework::InspectorWidget(parent) { - m_documentSystemSettings = AZ::UserSettings::CreateFind( - AZ_CRC_CE("AtomToolsDocumentSystemSettings"), AZ::UserSettings::CT_GLOBAL); } SettingsWidget::~SettingsWidget() @@ -26,23 +24,9 @@ namespace MaterialEditor void SettingsWidget::Populate() { AddGroupsBegin(); - AddDocumentSystemSettingsGroup(); AddGroupsEnd(); } - void SettingsWidget::AddDocumentSystemSettingsGroup() - { - const AZStd::string groupName = "documentSystemSettings"; - const AZStd::string groupDisplayName = "Document System Settings"; - const AZStd::string groupDescription = "Document System Settings"; - - const AZ::Crc32 saveStateKey(AZStd::string::format("SettingsWidget::DocumentSystemSettingsGroup")); - AddGroup( - groupName, groupDisplayName, groupDescription, - new AtomToolsFramework::InspectorPropertyGroupWidget( - m_documentSystemSettings.get(), nullptr, m_documentSystemSettings->TYPEINFO_Uuid(), nullptr, this, saveStateKey)); - } - void SettingsWidget::Reset() { AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h index 2642d9d55e..9a222b39c1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h @@ -9,7 +9,6 @@ #pragma once #if !defined(Q_MOC_RUN) -#include #include #include #endif @@ -30,11 +29,7 @@ namespace MaterialEditor void Populate(); private: - void AddDocumentSystemSettingsGroup(); - // AtomToolsFramework::InspectorRequestBus::Handler overrides... void Reset() override; - - AZStd::intrusive_ptr m_documentSystemSettings; }; } // namespace MaterialEditor From d4df57e9106edccadeccb3a846d3d9cad3cbf810 Mon Sep 17 00:00:00 2001 From: scspaldi Date: Mon, 7 Feb 2022 15:56:24 -0800 Subject: [PATCH 08/24] Applied PR feedback. Signed-off-by: scspaldi --- Tools/LyTestTools/tests/integ/sanity_tests.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Tools/LyTestTools/tests/integ/sanity_tests.py b/Tools/LyTestTools/tests/integ/sanity_tests.py index f1d39891d3..481349dfda 100755 --- a/Tools/LyTestTools/tests/integ/sanity_tests.py +++ b/Tools/LyTestTools/tests/integ/sanity_tests.py @@ -64,23 +64,15 @@ class TestAutomatedTestingProject(object): process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) def test_StartServerLauncher_Sanity(self, project): - """ - The `test_StartServerLauncher_Sanity` test function verifies that the O3DE game client launches successfully. - Start the test by utilizing the `kill_processes_named` function to close any open O3DE processes that may - interfere with the test. The Workspace object emulates the O3DE package by locating the engine and project - directories. The Launcher object controls the O3DE game client and requires a Workspace object for - initialization. Add the `-rhi=Null` arg to the executable call to disable GPU rendering. This allows the - test to run on instances without a GPU. We launch the game client executable and wait for the process to exist. - A try/finally block ensures proper test cleanup if issues occur during the test. - """ # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) try: - # Create the Workspace object + # Create the Workspace object, this locates the engine and project workspace = helpers.create_builtin_workspace(project=project) - # Create the Launcher object and add args + # Create the Launcher object and add args, such as `-rhi=Null` which disables GPU rendering and allows the + # test to run on nodes without a GPU launcher = launcher_helper.create_dedicated_launcher(workspace) launcher.args.extend(['-rhi=Null']) From 5b8176e99bba504a8c11488deac0f06f7a5b67b1 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 7 Feb 2022 16:01:29 -0800 Subject: [PATCH 09/24] Address some review feedback Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp | 18 +++++++++--------- Code/Framework/AzCore/AzCore/DOM/DomPatch.h | 8 +++++--- .../AzCore/Tests/DOM/DomPathBenchmarks.cpp | 12 ++++++------ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp index 44c16baa16..f89cb313e7 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp @@ -14,21 +14,21 @@ namespace AZ::Dom { PatchOperation::PatchOperation(Path destinationPath, Type type, Value value) - : m_domPath(destinationPath) + : m_domPath(AZStd::move(destinationPath)) , m_type(type) - , m_value(value) + , m_value(AZStd::move(value)) { } PatchOperation::PatchOperation(Path destinationPath, Type type, Path sourcePath) - : m_domPath(destinationPath) + : m_domPath(AZStd::move(destinationPath)) , m_type(type) - , m_value(sourcePath) + , m_value(AZStd::move(sourcePath)) { } PatchOperation::PatchOperation(Path destinationPath, Type type) - : m_domPath(destinationPath) + : m_domPath(AZStd::move(destinationPath)) , m_type(type) { } @@ -690,22 +690,22 @@ namespace AZ::Dom auto Patch::begin() const -> OperationsContainer::const_iterator { - return m_operations.cbegin(); + return m_operations.begin(); } auto Patch::end() const -> OperationsContainer::const_iterator { - return m_operations.cend(); + return m_operations.end(); } auto Patch::cbegin() const -> OperationsContainer::const_iterator { - return m_operations.cbegin(); + return m_operations.begin(); } auto Patch::cend() const -> OperationsContainer::const_iterator { - return m_operations.cend(); + return m_operations.end(); } size_t Patch::size() const diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h index 633a611c73..40ef725b57 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h @@ -10,6 +10,7 @@ #include #include +#include namespace AZ::Dom { @@ -108,12 +109,12 @@ namespace AZ::Dom //! The current state of a Patch application operation. struct PatchApplicationState { + //! The outcome of the last operation, may be overridden to produce a different failure outcome. + PatchOperation::PatchOutcome m_outcome; //! The patch being applied. const Patch* m_patch = nullptr; //! The last operation attempted. const PatchOperation* m_lastOperation = nullptr; - //! The outcome of the last operation, may be overridden to produce a different failure outcome. - PatchOperation::PatchOutcome m_outcome; //! The current state of the value being patched, will be returned if the patch operation succeeds. Value* m_currentState = nullptr; //! If set to false, the patch operation should halt. @@ -134,7 +135,7 @@ namespace AZ::Dom { public: using StrategyFunctor = AZStd::function; - using OperationsContainer = AZStd::vector; + using OperationsContainer = AZStd::deque; Patch() = default; Patch(const Patch&) = default; @@ -193,6 +194,7 @@ namespace AZ::Dom struct DeltaPatchGenerationParameters { static constexpr size_t NoReplace = AZStd::numeric_limits::max(); + static constexpr size_t AlwaysFullReplace = 0; //! The threshold of changed values in a node or array which, if exceeded, will cause the generation to create an //! entire "replace" oepration instead. If set to NoReplace, no replacement will occur. diff --git a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp index c3c8139f6c..4741900aa1 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp @@ -106,12 +106,12 @@ namespace AZ::Dom::Benchmark for (auto _ : state) { - name == name; - name == index; - name == endOfArray; - index == index; - index == endOfArray; - endOfArray == endOfArray; + benchmark::DoNotOptimize(name == name); + benchmark::DoNotOptimize(name == index); + benchmark::DoNotOptimize(name == endOfArray); + benchmark::DoNotOptimize(index == index); + benchmark::DoNotOptimize(index == endOfArray); + benchmark::DoNotOptimize(endOfArray == endOfArray); } state.SetItemsProcessed(6 * state.iterations()); From 3a426344dd6707a4801028b1de1aa7820615e162 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 8 Feb 2022 00:51:03 -0800 Subject: [PATCH 10/24] Updated all of the .material files in AutomatedTesting and Atom/TestData to use the new flat list format. The conversion was done using local changes with a script that opens and re-saves every .material file in a given folder (those WIP changes are on a branch here: Atom/santorac/UpgradeMaterialScript). Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- ..._Sponza_Material_Conversion_black.material | 50 ++-- ..._Sponza_Material_Conversion_green.material | 50 ++-- ...onza_Material_Conversion_mat_arch.material | 68 ++--- ...za_Material_Conversion_mat_bricks.material | 76 ++---- ...nza_Material_Conversion_mat_floor.material | 72 ++---- ...onza_Material_Conversion_mat_roof.material | 60 ++--- ...Sponza_Material_Conversion_phong5.material | 50 ++-- ...st_Sponza_Material_Conversion_red.material | 50 ++-- ..._Sponza_Material_Conversion_white.material | 22 +- .../objects/lightBlocker_lambert1.material | 24 +- .../Assets/objects/sponza_mat_arch.material | 52 ++-- .../objects/sponza_mat_background.material | 60 ++--- .../Assets/objects/sponza_mat_bricks.material | 60 ++--- .../objects/sponza_mat_ceiling.material | 48 ++-- .../Assets/objects/sponza_mat_chain.material | 46 ++-- .../objects/sponza_mat_columna.material | 60 ++--- .../objects/sponza_mat_columnb.material | 60 ++--- .../objects/sponza_mat_columnc.material | 60 ++--- .../objects/sponza_mat_curtainblue.material | 74 ++---- .../objects/sponza_mat_curtaingreen.material | 48 ++-- .../objects/sponza_mat_curtainred.material | 56 ++-- .../objects/sponza_mat_details.material | 48 +--- .../objects/sponza_mat_fabricblue.material | 50 ++-- .../objects/sponza_mat_fabricgreen.material | 50 ++-- .../objects/sponza_mat_fabricred.material | 50 ++-- .../objects/sponza_mat_flagpole.material | 60 ++--- .../Assets/objects/sponza_mat_floor.material | 58 ++--- .../Assets/objects/sponza_mat_leaf.material | 58 ++--- .../Assets/objects/sponza_mat_lion.material | 48 ++-- .../Assets/objects/sponza_mat_roof.material | 64 ++--- .../Assets/objects/sponza_mat_vase.material | 60 ++--- .../objects/sponza_mat_vasehanging.material | 56 ++-- .../objects/sponza_mat_vaseplant.material | 52 ++-- .../objects/sponza_mat_vaseround.material | 66 ++--- .../PbrMaterialChart/materials/basic.material | 50 ++-- .../materials/basic_m00_r00.material | 14 +- .../materials/basic_m00_r01.material | 14 +- .../materials/basic_m00_r02.material | 14 +- .../materials/basic_m00_r03.material | 14 +- .../materials/basic_m00_r04.material | 14 +- .../materials/basic_m00_r05.material | 14 +- .../materials/basic_m00_r06.material | 14 +- .../materials/basic_m00_r07.material | 14 +- .../materials/basic_m00_r08.material | 14 +- .../materials/basic_m00_r09.material | 14 +- .../materials/basic_m00_r10.material | 14 +- .../materials/basic_m10_r00.material | 14 +- .../materials/basic_m10_r01.material | 14 +- .../materials/basic_m10_r02.material | 14 +- .../materials/basic_m10_r03.material | 14 +- .../materials/basic_m10_r04.material | 14 +- .../materials/basic_m10_r05.material | 14 +- .../materials/basic_m10_r06.material | 14 +- .../materials/basic_m10_r07.material | 14 +- .../materials/basic_m10_r08.material | 14 +- .../materials/basic_m10_r09.material | 14 +- .../materials/basic_m10_r10.material | 14 +- .../Materials/DefaultPBR.material | 2 +- .../Materials/DefaultPBRTransparent.material | 9 +- .../Materials/MinimalBlue.material | 20 +- AutomatedTesting/Materials/UVs.material | 2 +- .../Materials/basic_grey.material | 50 ++-- .../decal/airship_symbol_decal.material | 46 ++-- .../DisplayWrinkleMaskBlendValues.material | 14 +- .../Materials/AutoBrick/Brick.material | 46 ++-- .../Materials/AutoBrick/Tile.material | 52 ++-- .../TestData/Materials/ParallaxRock.material | 43 +--- .../001_hermanubis_regression_test.material | 90 +++---- .../002_wrinkle_regression_test.material | 102 ++++---- .../001_ManyFeatures.material | 242 +++++++----------- .../001_ManyFeatures_Layer2Off.material | 9 +- .../001_ManyFeatures_Layer3Off.material | 9 +- .../002_ParallaxPdo.material | 74 ++---- .../003_Debug_BlendMask.material | 11 +- .../003_Debug_BlendWeights.material | 11 +- .../003_Debug_Displacement.material | 11 +- .../004_UseVertexColors.material | 13 +- .../005_UseDisplacement.material | 114 +++------ .../005_UseDisplacement_Layer2Off.material | 9 +- .../005_UseDisplacement_Layer3Off.material | 9 +- ...isplacement_With_BlendMaskTexture.material | 13 +- ...th_BlendMaskTexture_AllSameHeight.material | 27 +- ...ith_BlendMaskTexture_NoHeightmaps.material | 23 +- ...cement_With_BlendMaskVertexColors.material | 15 +- .../001_DefaultWhite.material | 2 - .../002_BaseColorLerp.material | 24 +- .../002_BaseColorLinearLight.material | 26 +- .../002_BaseColorMultiply.material | 24 +- .../003_MetalMatte.material | 28 +- .../003_MetalPolished.material | 28 +- .../004_MetalMap.material | 30 +-- .../005_RoughnessMap.material | 34 +-- .../006_SpecularF0Map.material | 28 +- ...07_MultiscatteringCompensationOff.material | 34 +-- ...007_MultiscatteringCompensationOn.material | 34 +-- .../008_NormalMap.material | 28 +- .../008_NormalMap_Bevels.material | 12 +- .../009_Opacity_Blended.material | 32 +-- ...ty_Blended_Alpha_Affects_Specular.material | 34 +-- ...ty_Cutout_PackedAlpha_DoubleSided.material | 18 +- ...ity_Cutout_SplitAlpha_DoubleSided.material | 16 +- ...ity_Cutout_SplitAlpha_SingleSided.material | 14 +- .../009_Opacity_Opaque_DoubleSided.material | 12 +- .../009_Opacity_TintedTransparent.material | 30 +-- .../010_AmbientOcclusion.material | 13 +- .../010_BothOcclusion.material | 15 +- .../010_OcclusionBase.material | 30 +-- .../010_SpecularOcclusion.material | 11 +- .../011_Emissive.material | 29 +-- .../012_Parallax_POM.material | 19 +- .../012_Parallax_POM_Cutout.material | 36 +-- .../013_SpecularAA_Off.material | 19 +- .../013_SpecularAA_On.material | 23 +- .../014_ClearCoat.material | 36 +-- .../014_ClearCoat_NormalMap.material | 44 ++-- .../014_ClearCoat_NormalMap_2ndUv.material | 52 ++-- .../014_ClearCoat_RoughnessMap.material | 42 ++- .../015_SubsurfaceScattering.material | 28 +- ...SubsurfaceScattering_Transmission.material | 18 +- ...rfaceScattering_Transmission_Thin.material | 40 ++- .../100_UvTiling_AmbientOcclusion.material | 11 +- .../100_UvTiling_BaseColor.material | 11 +- .../100_UvTiling_Emissive.material | 31 +-- .../100_UvTiling_Metallic.material | 17 +- .../100_UvTiling_Normal.material | 11 +- ...100_UvTiling_Normal_Dome_Rotate20.material | 26 +- ...100_UvTiling_Normal_Dome_Rotate90.material | 26 +- ...0_UvTiling_Normal_Dome_ScaleOnlyU.material | 26 +- ...0_UvTiling_Normal_Dome_ScaleOnlyV.material | 26 +- ...UvTiling_Normal_Dome_ScaleUniform.material | 26 +- ...UvTiling_Normal_Dome_TransformAll.material | 36 ++- .../100_UvTiling_Opacity.material | 17 +- .../100_UvTiling_Parallax_A.material | 53 ++-- .../100_UvTiling_Parallax_B.material | 53 ++-- .../100_UvTiling_Roughness.material | 15 +- .../100_UvTiling_SpecularF0.material | 31 +-- .../101_DetailMaps_BaseNoDetailMaps.material | 40 +-- .../102_DetailMaps_All.material | 60 ++--- .../103_DetailMaps_BaseColor.material | 21 +- .../103_DetailMaps_BaseColorWithMask.material | 15 +- .../104_DetailMaps_Normal.material | 23 +- .../104_DetailMaps_NormalWithMask.material | 13 +- ...etailMaps_BlendMaskUsingDetailUVs.material | 58 ++--- .../UvTilingBase.material | 28 +- .../DisplayVertexColor.material | 22 +- 145 files changed, 1802 insertions(+), 3127 deletions(-) diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material index d15aa620c7..04766a23e1 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material @@ -1,35 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "irradiance": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "opacity": { - "factor": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "irradiance.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "opacity.factor": 1.0 } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material index 579359b085..02440cce7a 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material @@ -1,35 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.0, - 1.0, - 0.0, - 1.0 - ] - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "irradiance": { - "color": [ - 0.0, - 1.0, - 0.0, - 1.0 - ] - }, - "opacity": { - "factor": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.0, + 1.0, + 0.0, + 1.0 + ], + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "irradiance.color": [ + 0.0, + 1.0, + 0.0, + 1.0 + ], + "opacity.factor": 1.0 } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material index 88d5fc0fc6..e91c35fa8b 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material @@ -1,49 +1,29 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.800000011920929, - 0.800000011920929, - 0.800000011920929, - 1.0 - ], - "textureMap": "Textures/arch_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.885053813457489, - 0.801281750202179, - 1.0 - ] - }, - "metallic": { - "textureMap": "Textures/arch_1k_metallic.png" - }, - "normal": { - "textureMap": "Textures/arch_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "Textures/arch_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.050999999046325687, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "Textures/arch_1k_roughness.png" - } + "propertyValues": { + "baseColor.color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "baseColor.textureMap": "Textures/arch_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.885053813457489, + 0.801281750202179, + 1.0 + ], + "metallic.textureMap": "Textures/arch_1k_metallic.png", + "normal.textureMap": "Textures/arch_1k_normal.jpg", + "occlusion.diffuseTextureMap": "Textures/arch_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.050999999046325684, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "Textures/arch_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material index 7244397ee9..aa23f2e97c 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material @@ -1,54 +1,32 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.800000011920929, - 0.800000011920929, - 0.800000011920929, - 1.0 - ], - "textureMap": "Textures/bricks_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "Textures/bricks_1k_normal.jpg", - "roughness": 0.5 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.9703211784362793, - 0.9703211784362793, - 1.0 - ] - }, - "metallic": { - "textureMap": "Textures/bricks_1k_metallic.png" - }, - "normal": { - "textureMap": "Textures/bricks_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "Textures/bricks_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "algorithm": "ContactRefinement", - "factor": 0.03500000014901161, - "quality": "Medium", - "useTexture": false - }, - "roughness": { - "textureMap": "Textures/bricks_1k_roughness.png" - } + "propertyValues": { + "baseColor.color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "baseColor.textureMap": "Textures/bricks_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "Textures/bricks_1k_normal.jpg", + "clearCoat.roughness": 0.5, + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.9703211784362793, + 0.9703211784362793, + 1.0 + ], + "metallic.textureMap": "Textures/bricks_1k_metallic.png", + "normal.textureMap": "Textures/bricks_1k_normal.jpg", + "occlusion.diffuseTextureMap": "Textures/bricks_1k_ao.png", + "opacity.factor": 1.0, + "parallax.algorithm": "ContactRefinement", + "parallax.factor": 0.03500000014901161, + "parallax.quality": "Medium", + "parallax.useTexture": false, + "roughness.textureMap": "Textures/bricks_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material index 8a3f289c26..a49327a710 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material @@ -1,51 +1,31 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.800000011920929, - 0.800000011920929, - 0.800000011920929, - 1.0 - ], - "textureMap": "Textures/floor_1k_basecolor.png" - }, - "clearCoat": { - "enable": true, - "influenceMap": "Textures/floor_1k_ao.png", - "normalMap": "Textures/floor_1k_normal.png", - "roughness": 0.25 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.9404135346412659, - 0.8688944578170776, - 1.0 - ] - }, - "normal": { - "textureMap": "Textures/floor_1k_normal.png" - }, - "occlusion": { - "diffuseTextureMap": "Textures/floor_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.012000000104308129, - "pdo": true, - "useTexture": false - }, - "roughness": { - "textureMap": "Textures/floor_1k_roughness.png" - } + "propertyValues": { + "baseColor.color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "baseColor.textureMap": "Textures/floor_1k_basecolor.png", + "clearCoat.enable": true, + "clearCoat.influenceMap": "Textures/floor_1k_ao.png", + "clearCoat.normalMap": "Textures/floor_1k_normal.png", + "clearCoat.roughness": 0.25, + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.9404135346412659, + 0.8688944578170776, + 1.0 + ], + "normal.textureMap": "Textures/floor_1k_normal.png", + "occlusion.diffuseTextureMap": "Textures/floor_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.012000000104308128, + "parallax.pdo": true, + "parallax.useTexture": false, + "roughness.textureMap": "Textures/floor_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material index 7bc193978f..4f6b6bae92 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material @@ -1,44 +1,26 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.800000011920929, - 0.800000011920929, - 0.800000011920929, - 1.0 - ], - "textureBlendMode": "Lerp", - "textureMap": "Textures/roof_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "metallic": { - "useTexture": false - }, - "normal": { - "factor": 0.5, - "flipY": true, - "textureMap": "Textures/roof_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "Textures/roof_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "algorithm": "ContactRefinement", - "factor": 0.019999999552965165, - "quality": "Medium", - "useTexture": false - }, - "roughness": { - "textureMap": "Textures/roof_1k_roughness.png" - } + "propertyValues": { + "baseColor.color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "baseColor.textureBlendMode": "Lerp", + "baseColor.textureMap": "Textures/roof_1k_basecolor.png", + "general.applySpecularAA": true, + "metallic.useTexture": false, + "normal.factor": 0.5, + "normal.flipY": true, + "normal.textureMap": "Textures/roof_1k_normal.jpg", + "occlusion.diffuseTextureMap": "Textures/roof_1k_ao.png", + "opacity.factor": 1.0, + "parallax.algorithm": "ContactRefinement", + "parallax.factor": 0.019999999552965164, + "parallax.quality": "Medium", + "parallax.useTexture": false, + "roughness.textureMap": "Textures/roof_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material index a53cbef4e4..e801b4d095 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material @@ -1,35 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.0, - 0.0, - 1.0, - 1.0 - ] - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "irradiance": { - "color": [ - 0.0, - 0.0, - 1.0, - 1.0 - ] - }, - "opacity": { - "factor": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.0, + 0.0, + 1.0, + 1.0 + ], + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "irradiance.color": [ + 0.0, + 0.0, + 1.0, + 1.0 + ], + "opacity.factor": 1.0 } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material index 6ddb645319..ea364bab34 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material @@ -1,35 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.800000011920929, - 0.0, - 0.0, - 1.0 - ] - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "irradiance": { - "color": [ - 1.0, - 0.0, - 0.0, - 1.0 - ] - }, - "opacity": { - "factor": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.800000011920929, + 0.0, + 0.0, + 1.0 + ], + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "irradiance.color": [ + 1.0, + 0.0, + 0.0, + 1.0 + ], + "opacity.factor": 1.0 } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material index e3d310cd15..0f90de5e13 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material @@ -1,19 +1,13 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "opacity": { - "factor": 1.0 - } + "propertyValues": { + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "opacity.factor": 1.0 } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material index 35677a81c6..0f90de5e13 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material @@ -1,19 +1,13 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "opacity": { - "factor": 1.0 - } + "propertyValues": { + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "opacity.factor": 1.0 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material index 6518091265..21f63885a9 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material @@ -1,40 +1,22 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/arch_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.2663614749908447, - 0.2383916974067688, - 0.18117037415504456, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/arch_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/arch_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.050999999046325684, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/arch_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/arch_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.2663614749908447, + 0.2383916974067688, + 0.18117037415504456, + 1.0 + ], + "normal.textureMap": "../Textures/arch_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/arch_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.050999999046325684, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/arch_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material index 2fd7ed39cc..7d5edb86e8 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material @@ -1,45 +1,25 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/background_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "../Textures/background_1k_normal.jpg", - "roughness": 0.4000000059604645 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.19806210696697235, - 0.1746547669172287, - 0.16513313353061676, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/background_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/background_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.03099999949336052, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/background_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/background_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "../Textures/background_1k_normal.jpg", + "clearCoat.roughness": 0.4000000059604645, + "general.applySpecularAA": true, + "irradiance.color": [ + 0.19806210696697235, + 0.1746547669172287, + 0.16513313353061676, + 1.0 + ], + "normal.textureMap": "../Textures/background_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/background_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.03099999949336052, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/background_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material index 52fdf9e3a2..9e7a01d573 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material @@ -1,45 +1,25 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/bricks_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "../Textures/bricks_1k_normal.jpg", - "roughness": 0.5 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.27467766404151917, - 0.27467766404151917, - 0.270496666431427, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/bricks_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/bricks_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "algorithm": "ContactRefinement", - "factor": 0.03500000014901161, - "quality": "Medium", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/bricks_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/bricks_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "../Textures/bricks_1k_normal.jpg", + "clearCoat.roughness": 0.5, + "general.applySpecularAA": true, + "irradiance.color": [ + 0.27467766404151917, + 0.27467766404151917, + 0.270496666431427, + 1.0 + ], + "normal.textureMap": "../Textures/bricks_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/bricks_1k_ao.png", + "opacity.factor": 1.0, + "parallax.algorithm": "ContactRefinement", + "parallax.factor": 0.03500000014901161, + "parallax.quality": "Medium", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/bricks_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material index 10f5a01a8e..b9bc4e3dcb 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material @@ -1,36 +1,22 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/ceiling_1k_basecolor.png" - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "irradiance": { - "color": [ - 0.29176774621009827, - 0.27888914942741394, - 0.2501564025878906, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/ceiling_1k_normal.png" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/ceiling_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/ceiling_1k_basecolor.png", + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "irradiance.color": [ + 0.29176774621009827, + 0.27888914942741394, + 0.2501564025878906, + 1.0 + ], + "normal.textureMap": "../Textures/ceiling_1k_normal.png", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/ceiling_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material index caf03bd3ce..5b553b5113 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material @@ -1,35 +1,21 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureBlendMode": "Lerp", - "textureMap": "../Textures/chain_basecolor.png" - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "general": { - "doubleSided": true - }, - "metallic": { - "factor": 0.8899999856948853 - }, - "normal": { - "textureMap": "../Textures/chain_normal.jpg" - }, - "opacity": { - "alphaSource": "Split", - "factor": 1.0, - "mode": "Cutout", - "textureMap": "../Textures/chain_alpha.png" - } + "propertyValues": { + "baseColor.textureBlendMode": "Lerp", + "baseColor.textureMap": "../Textures/chain_basecolor.png", + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "general.doubleSided": true, + "metallic.factor": 0.8899999856948853, + "normal.textureMap": "../Textures/chain_normal.jpg", + "opacity.alphaSource": "Split", + "opacity.factor": 1.0, + "opacity.mode": "Cutout", + "opacity.textureMap": "../Textures/chain_alpha.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material index 15c3fec349..5e8b17d959 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material @@ -1,45 +1,25 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/columnA_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "../Textures/columnA_1k_normal.jpg", - "roughness": 0.30000001192092896 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.8964369893074036, - 0.8264744281768799, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/columnA_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/columnA_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.017000000923871994, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/columnA_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/columnA_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "../Textures/columnA_1k_normal.jpg", + "clearCoat.roughness": 0.30000001192092896, + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.8964369893074036, + 0.8264744281768799, + 1.0 + ], + "normal.textureMap": "../Textures/columnA_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/columnA_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.017000000923871994, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/columnA_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material index e13f96b2bb..4f24f4d61b 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material @@ -1,45 +1,25 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/columnB_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "../Textures/columnB_1k_normal.jpg", - "roughness": 0.30000001192092896 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.41788357496261597, - 0.40723279118537903, - 0.4286869466304779, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/columnB_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/columnB_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.020999999716877937, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/columnB_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/columnB_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "../Textures/columnB_1k_normal.jpg", + "clearCoat.roughness": 0.30000001192092896, + "general.applySpecularAA": true, + "irradiance.color": [ + 0.41788357496261597, + 0.40723279118537903, + 0.4286869466304779, + 1.0 + ], + "normal.textureMap": "../Textures/columnB_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/columnB_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.020999999716877937, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/columnB_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material index 479692848a..e7c9401091 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material @@ -1,45 +1,25 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/columnC_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "../Textures/columnC_1k_normal.jpg", - "roughness": 0.30000001192092896 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.32314029335975647, - 0.29176774621009827, - 0.24228274822235107, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/columnC_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/columnC_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.014000000432133675, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/columnC_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/columnC_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "../Textures/columnC_1k_normal.jpg", + "clearCoat.roughness": 0.30000001192092896, + "general.applySpecularAA": true, + "irradiance.color": [ + 0.32314029335975647, + 0.29176774621009827, + 0.24228274822235107, + 1.0 + ], + "normal.textureMap": "../Textures/columnC_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/columnC_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.014000000432133675, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/columnC_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material index 50fd968956..8b2167e4ac 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material @@ -1,52 +1,32 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "color": [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - "textureMap": "../Textures/curtainBlue_1k_basecolor.png" - }, - "emissive": { - "color": [ - 1.0, - 1.0, - 1.0, - 1.0 - ] - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.0, - 0.14901961386203766, - 1.0, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/curtain_metallic.png" - }, - "normal": { - "factor": 0.5, - "textureMap": "../Textures/curtain_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/curtain_ao.png" - }, - "roughness": { - "textureMap": "../Textures/curtain_roughness.png" - }, - "specularF0": { - "enableMultiScatterCompensation": true - } + "propertyValues": { + "baseColor.color": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "baseColor.textureMap": "../Textures/curtainBlue_1k_basecolor.png", + "emissive.color": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "general.applySpecularAA": true, + "irradiance.color": [ + 0.0, + 0.14901961386203766, + 1.0, + 1.0 + ], + "metallic.textureMap": "../Textures/curtain_metallic.png", + "normal.factor": 0.5, + "normal.textureMap": "../Textures/curtain_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/curtain_ao.png", + "roughness.textureMap": "../Textures/curtain_roughness.png", + "specularF0.enableMultiScatterCompensation": true } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material index 6e70a42d24..5e6233ab04 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material @@ -1,38 +1,20 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/curtainGreen_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.0, - 0.15294118225574493, - 0.0, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/curtain_metallic.png" - }, - "normal": { - "factor": 0.5, - "textureMap": "../Textures/curtain_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/curtain_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/curtain_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/curtainGreen_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.0, + 0.15294118225574493, + 0.0, + 1.0 + ], + "metallic.textureMap": "../Textures/curtain_metallic.png", + "normal.factor": 0.5, + "normal.textureMap": "../Textures/curtain_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/curtain_ao.png", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/curtain_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material index 8233633310..86122d274f 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material @@ -1,43 +1,23 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/curtainRed_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.41960784792900085, - 0.003921568859368563, - 0.003921568859368563, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/curtain_metallic.png" - }, - "normal": { - "textureMap": "../Textures/curtain_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/curtain_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/curtain_roughness.png" - }, - "uv": { - "center": [ - 16.0, - 0.0 - ] - } + "propertyValues": { + "baseColor.textureMap": "../Textures/curtainRed_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.41960784792900085, + 0.003921568859368563, + 0.003921568859368563, + 1.0 + ], + "metallic.textureMap": "../Textures/curtain_metallic.png", + "normal.textureMap": "../Textures/curtain_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/curtain_ao.png", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/curtain_roughness.png", + "uv.center": [ + 16.0, + 0.0 + ] } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material index b66d8fa679..1a8588e749 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material @@ -1,39 +1,19 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/details_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "normalMap": "../Textures/details_1k_normal.png", - "roughness": 0.25 - }, - "general": { - "applySpecularAA": true - }, - "metallic": { - "textureMap": "../Textures/details_1k_metallic.png" - }, - "normal": { - "textureMap": "../Textures/details_1k_normal.png" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/details_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.02500000037252903, - "pdo": true, - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/details_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/details_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.normalMap": "../Textures/details_1k_normal.png", + "clearCoat.roughness": 0.25, + "general.applySpecularAA": true, + "metallic.textureMap": "../Textures/details_1k_metallic.png", + "normal.textureMap": "../Textures/details_1k_normal.png", + "occlusion.diffuseTextureMap": "../Textures/details_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.02500000037252903, + "parallax.pdo": true, + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/details_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material index 19ce3a6839..4cb149b1dc 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material @@ -1,39 +1,21 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/fabricBlue_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.0, - 0.15049973130226135, - 1.0, - 1.0 - ], - "factor": 0.30000001192092896 - }, - "metallic": { - "textureMap": "../Textures/fabric_metallic.png" - }, - "normal": { - "factor": 0.5, - "textureMap": "../Textures/fabric_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/fabric_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/fabric_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/fabricBlue_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.0, + 0.15049973130226135, + 1.0, + 1.0 + ], + "irradiance.factor": 0.30000001192092896, + "metallic.textureMap": "../Textures/fabric_metallic.png", + "normal.factor": 0.5, + "normal.textureMap": "../Textures/fabric_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/fabric_ao.png", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/fabric_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material index 94b8270fef..9a6746ba12 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material @@ -1,39 +1,21 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/fabricGreen_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.0, - 0.15292592346668243, - 0.0012207217514514923, - 1.0 - ], - "factor": 0.30000001192092896 - }, - "metallic": { - "textureMap": "../Textures/fabric_metallic.png" - }, - "normal": { - "factor": 0.5, - "textureMap": "../Textures/fabric_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/fabric_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/fabric_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/fabricGreen_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.0, + 0.15292592346668243, + 0.0012207217514514923, + 1.0 + ], + "irradiance.factor": 0.30000001192092896, + "metallic.textureMap": "../Textures/fabric_metallic.png", + "normal.factor": 0.5, + "normal.textureMap": "../Textures/fabric_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/fabric_ao.png", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/fabric_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material index 7bd2ecddd0..85cd0e1650 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material @@ -1,39 +1,21 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/fabricRed_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.42040130496025085, - 0.004654001910239458, - 0.0037232013419270515, - 1.0 - ], - "factor": 0.30000001192092896 - }, - "metallic": { - "textureMap": "../Textures/fabric_metallic.png" - }, - "normal": { - "factor": 0.5, - "textureMap": "../Textures/fabric_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/fabric_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/fabric_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/fabricRed_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.42040130496025085, + 0.004654001910239458, + 0.0037232013419270515, + 1.0 + ], + "irradiance.factor": 0.30000001192092896, + "metallic.textureMap": "../Textures/fabric_metallic.png", + "normal.factor": 0.5, + "normal.textureMap": "../Textures/fabric_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/fabric_ao.png", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/fabric_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material index aca6c05d29..53f78ac390 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material @@ -1,46 +1,24 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/flagpole_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.6520485281944275, - 0.7122911214828491, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/flagpole_1k_metallic.png" - }, - "normal": { - "textureMap": "../Textures/flagpole_1k_normal.png" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/flagpole_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.014000000432133675, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/flagpole_1k_roughness.png" - }, - "specularF0": { - "enableMultiScatterCompensation": true - } + "propertyValues": { + "baseColor.textureMap": "../Textures/flagpole_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.6520485281944275, + 0.7122911214828491, + 1.0 + ], + "metallic.textureMap": "../Textures/flagpole_1k_metallic.png", + "normal.textureMap": "../Textures/flagpole_1k_normal.png", + "occlusion.diffuseTextureMap": "../Textures/flagpole_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.014000000432133675, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/flagpole_1k_roughness.png", + "specularF0.enableMultiScatterCompensation": true } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material index b75143326d..29aed982e7 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material @@ -1,44 +1,24 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/floor_1k_basecolor.png" - }, - "clearCoat": { - "influenceMap": "../Textures/floor_1k_ao.png", - "normalMap": "../Textures/floor_1k_normal.png", - "roughness": 0.25 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.9404135346412659, - 0.8688944578170776, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/floor_1k_normal.png" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/floor_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.012000000104308128, - "pdo": true, - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/floor_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/floor_1k_basecolor.png", + "clearCoat.influenceMap": "../Textures/floor_1k_ao.png", + "clearCoat.normalMap": "../Textures/floor_1k_normal.png", + "clearCoat.roughness": 0.25, + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.9404135346412659, + 0.8688944578170776, + 1.0 + ], + "normal.textureMap": "../Textures/floor_1k_normal.png", + "occlusion.diffuseTextureMap": "../Textures/floor_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.012000000104308128, + "parallax.pdo": true, + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/floor_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material index 51638d6d94..50c2a119ef 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material @@ -1,43 +1,25 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/thorn_basecolor.png" - }, - "clearCoat": { - "factor": 0.05000000074505806, - "normalMap": "../Textures/thorn_normal.jpg", - "roughness": 0.10000000149011612 - }, - "general": { - "applySpecularAA": true, - "doubleSided": true - }, - "irradiance": { - "color": [ - 0.46506446599960327, - 1.0, - 0.3944609761238098, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/thorn_normal.jpg" - }, - "opacity": { - "alphaSource": "Split", - "factor": 0.20000000298023224, - "mode": "Cutout", - "textureMap": "../Textures/thorn_alpha.png" - }, - "parallax": { - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/thorn_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/thorn_basecolor.png", + "clearCoat.factor": 0.05000000074505806, + "clearCoat.normalMap": "../Textures/thorn_normal.jpg", + "clearCoat.roughness": 0.10000000149011612, + "general.applySpecularAA": true, + "general.doubleSided": true, + "irradiance.color": [ + 0.46506446599960327, + 1.0, + 0.3944609761238098, + 1.0 + ], + "normal.textureMap": "../Textures/thorn_normal.jpg", + "opacity.alphaSource": "Split", + "opacity.factor": 0.20000000298023224, + "opacity.mode": "Cutout", + "opacity.textureMap": "../Textures/thorn_alpha.png", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/thorn_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material index eee41e9c13..97dbaa7f18 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material @@ -1,36 +1,22 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/lion_1k_basecolor.png" - }, - "emissive": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "irradiance": { - "color": [ - 0.5583428740501404, - 0.496940553188324, - 0.4125429093837738, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/lion_1k_normal.jpg" - }, - "opacity": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "../Textures/lion_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/lion_1k_basecolor.png", + "emissive.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "irradiance.color": [ + 0.5583428740501404, + 0.496940553188324, + 0.4125429093837738, + 1.0 + ], + "normal.textureMap": "../Textures/lion_1k_normal.jpg", + "opacity.factor": 1.0, + "roughness.textureMap": "../Textures/lion_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material index fec7bb1e34..6416ee2b55 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material @@ -1,47 +1,27 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureBlendMode": "Lerp", - "textureMap": "../Textures/roof_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.29613184928894043, - 0.3324483036994934, - 0.45078203082084656, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/roof_1k_metallic.png", - "useTexture": false - }, - "normal": { - "factor": 0.5, - "flipY": true, - "textureMap": "../Textures/roof_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/roof_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "algorithm": "ContactRefinement", - "factor": 0.019999999552965164, - "quality": "Medium", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/roof_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureBlendMode": "Lerp", + "baseColor.textureMap": "../Textures/roof_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.29613184928894043, + 0.3324483036994934, + 0.45078203082084656, + 1.0 + ], + "metallic.textureMap": "../Textures/roof_1k_metallic.png", + "metallic.useTexture": false, + "normal.factor": 0.5, + "normal.flipY": true, + "normal.textureMap": "../Textures/roof_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/roof_1k_ao.png", + "opacity.factor": 1.0, + "parallax.algorithm": "ContactRefinement", + "parallax.factor": 0.019999999552965164, + "parallax.quality": "Medium", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/roof_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material index da7a9de3a8..4722c4a2ff 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material @@ -1,46 +1,24 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/vase_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 1.0, - 0.8713664412498474, - 0.6021667718887329, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/vase_1k_metallic.png" - }, - "normal": { - "textureMap": "../Textures/vase_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/vase_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.027000000700354576, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/vase_1k_roughness.png" - }, - "specularF0": { - "enableMultiScatterCompensation": true - } + "propertyValues": { + "baseColor.textureMap": "../Textures/vase_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 1.0, + 0.8713664412498474, + 0.6021667718887329, + 1.0 + ], + "metallic.textureMap": "../Textures/vase_1k_metallic.png", + "normal.textureMap": "../Textures/vase_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/vase_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.027000000700354576, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/vase_1k_roughness.png", + "specularF0.enableMultiScatterCompensation": true } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material index bda7aad38c..31ac0bd369 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material @@ -1,43 +1,23 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/vaseHanging_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.765606164932251, - 1.0, - 0.7052567601203918, - 1.0 - ] - }, - "metallic": { - "textureMap": "../Textures/vaseHanging_1k_metallic.png" - }, - "normal": { - "textureMap": "../Textures/vaseHanging_1k_normal.png" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/vaseHanging_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.04600000008940697, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/vaseHanging_1k_roughness.png" - } + "propertyValues": { + "baseColor.textureMap": "../Textures/vaseHanging_1k_basecolor.png", + "general.applySpecularAA": true, + "irradiance.color": [ + 0.765606164932251, + 1.0, + 0.7052567601203918, + 1.0 + ], + "metallic.textureMap": "../Textures/vaseHanging_1k_metallic.png", + "normal.textureMap": "../Textures/vaseHanging_1k_normal.png", + "occlusion.diffuseTextureMap": "../Textures/vaseHanging_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.04600000008940697, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/vaseHanging_1k_roughness.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material index 5546daa0e0..fc92f7beca 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material @@ -1,36 +1,26 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "color": [ - 0.800000011920929, - 0.800000011920929, - 0.800000011920929, - 1.0 - ], - "textureBlendMode": "Lerp", - "textureMap": "../Textures/vasePlant_1k_basecolor.png" - }, - "general": { - "applySpecularAA": true, - "doubleSided": true - }, - "irradiance": { - "color": [ - 0.09086747467517853, - 0.4111391007900238, - 0.0474097803235054, - 1.0 - ] - }, - "opacity": { - "alphaSource": "Split", - "factor": 0.23999999463558197, - "mode": "Cutout", - "textureMap": "../Textures/vasePlant_1k_alpha.png" - } + "propertyValues": { + "baseColor.color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "baseColor.textureBlendMode": "Lerp", + "baseColor.textureMap": "../Textures/vasePlant_1k_basecolor.png", + "general.applySpecularAA": true, + "general.doubleSided": true, + "irradiance.color": [ + 0.09086747467517853, + 0.4111391007900238, + 0.0474097803235054, + 1.0 + ], + "opacity.alphaSource": "Split", + "opacity.factor": 0.23999999463558197, + "opacity.mode": "Cutout", + "opacity.textureMap": "../Textures/vasePlant_1k_alpha.png" } } \ No newline at end of file diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material index 268e3ab613..049859e37e 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material @@ -1,49 +1,27 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "../Textures/vaseRound_1k_basecolor.png" - }, - "clearCoat": { - "factor": 0.5, - "influenceMap": "../Textures/vaseRound_1k_ao.png", - "normalMap": "../Textures/vaseRound_1k_normal.jpg", - "roughness": 0.25 - }, - "general": { - "applySpecularAA": true - }, - "irradiance": { - "color": [ - 0.46933698654174805, - 0.3824063539505005, - 0.47861447930336, - 1.0 - ] - }, - "normal": { - "textureMap": "../Textures/vaseRound_1k_normal.jpg" - }, - "occlusion": { - "diffuseTextureMap": "../Textures/vaseRound_1k_ao.png" - }, - "opacity": { - "factor": 1.0 - }, - "parallax": { - "factor": 0.019999999552965164, - "pdo": true, - "quality": "High", - "useTexture": false - }, - "roughness": { - "textureMap": "../Textures/vaseRound_1k_roughness.png" - }, - "specularF0": { - "enableMultiScatterCompensation": true - } + "propertyValues": { + "baseColor.textureMap": "../Textures/vaseRound_1k_basecolor.png", + "clearCoat.factor": 0.5, + "clearCoat.influenceMap": "../Textures/vaseRound_1k_ao.png", + "clearCoat.normalMap": "../Textures/vaseRound_1k_normal.jpg", + "clearCoat.roughness": 0.25, + "general.applySpecularAA": true, + "irradiance.color": [ + 0.46933698654174805, + 0.3824063539505005, + 0.47861447930336, + 1.0 + ], + "normal.textureMap": "../Textures/vaseRound_1k_normal.jpg", + "occlusion.diffuseTextureMap": "../Textures/vaseRound_1k_ao.png", + "opacity.factor": 1.0, + "parallax.factor": 0.019999999552965164, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.useTexture": false, + "roughness.textureMap": "../Textures/vaseRound_1k_roughness.png", + "specularF0.enableMultiScatterCompensation": true } } \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material index 6af3ceb0c1..7fbdfd2e4e 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material @@ -1,32 +1,26 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "baseColor": { - "color": [ 1.0, 1.0, 1.0 ], - "factor": 0.75, - "useTexture": false, - "textureMap": "" - }, - "metallic": { - "factor": 0.0, - "useTexture": false, - "textureMap": "" - }, - "roughness": { - "factor": 0.0, - "useTexture": false, - "textureMap": "" - }, - "specularF0": { - "factor": 0.5, - "useTexture": false, - "textureMap": "" - }, - "normal": { - "factor": 1.0, - "useTexture": false, - "textureMap": "" - } + "propertyValues": { + "baseColor.color": [ + 1.0, + 1.0, + 1.0 + ], + "baseColor.factor": 0.75, + "baseColor.textureMap": "", + "baseColor.useTexture": false, + "metallic.factor": 0.0, + "metallic.textureMap": "", + "metallic.useTexture": false, + "normal.factor": 1.0, + "normal.textureMap": "", + "normal.useTexture": false, + "roughness.factor": 0.0, + "roughness.textureMap": "", + "roughness.useTexture": false, + "specularF0.factor": 0.5, + "specularF0.textureMap": "", + "specularF0.useTexture": false } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material index 541bd83981..0a84ea1a7f 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.0 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.0 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material index 19691258e0..2eca4d2cee 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.1 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.10000000149011612 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material index 46fda2aab1..3bd1791d7c 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.2 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.20000000298023224 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material index 79cf4bf401..15f7e5895d 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.3 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.30000001192092896 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material index 9aabf3e158..e33d6a9e8f 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.4 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.4000000059604645 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material index 8b02f225fc..d7f663fefc 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.5 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material index 5b089da4bd..7a3be6c791 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.6 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.6000000238418579 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material index 25741cf689..ad59f0bc0a 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.7 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.699999988079071 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material index 04103273f2..ed24021dce 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.8 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.800000011920929 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material index 74eb68da99..34d75d2d03 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 0.9 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 0.8999999761581421 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material index 3533ca6676..d540e239a0 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 0.0 - }, - "roughness": { - "factor": 1.0 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 0.0, + "roughness.factor": 1.0 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material index d2ce0fadc9..b3ac239778 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.0 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.0 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material index 8d96ea6217..fc1b49c65a 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.1 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.10000000149011612 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material index e8feb87283..5058b2f562 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.2 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.20000000298023224 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material index c14591bd52..f1395484c8 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.3 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.30000001192092896 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material index 60a3167f02..87d741f0bc 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.4 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.4000000059604645 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material index d71ff06961..128b1a45f2 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.5 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material index 6fa8cfe1a6..00c7864af4 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.6 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.6000000238418579 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material index 773cc66f03..74e26c35e4 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.7 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.699999988079071 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material index 6971597d1d..6f8140338c 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.8 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.800000011920929 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material index c2d8cc47bd..bbfaca32a1 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.9 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 0.8999999761581421 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material index 906879b0ea..5c375fde88 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material @@ -1,13 +1,9 @@ { - "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 1.0 - } + "parentMaterial": "./basic.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.factor": 1.0 } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Materials/DefaultPBR.material b/AutomatedTesting/Materials/DefaultPBR.material index f0990f148c..918af4b939 100644 --- a/AutomatedTesting/Materials/DefaultPBR.material +++ b/AutomatedTesting/Materials/DefaultPBR.material @@ -1,4 +1,4 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/Presets/PBR/default_grid.material" -} +} \ No newline at end of file diff --git a/AutomatedTesting/Materials/DefaultPBRTransparent.material b/AutomatedTesting/Materials/DefaultPBRTransparent.material index a7000d5371..9a0c3ba360 100644 --- a/AutomatedTesting/Materials/DefaultPBRTransparent.material +++ b/AutomatedTesting/Materials/DefaultPBRTransparent.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "Materials/Presets/PBR/default_grid.material", "materialTypeVersion": 3, - "properties": { - "opacity": { - "mode": "Blended" - } + "parentMaterial": "Materials/Presets/PBR/default_grid.material", + "propertyValues": { + "opacity.mode": "Blended" } } \ No newline at end of file diff --git a/AutomatedTesting/Materials/MinimalBlue.material b/AutomatedTesting/Materials/MinimalBlue.material index 7310a90250..62d4659a96 100644 --- a/AutomatedTesting/Materials/MinimalBlue.material +++ b/AutomatedTesting/Materials/MinimalBlue.material @@ -1,17 +1,13 @@ { - "description": "", - "parentMaterial": "", "materialType": "TestData/Materials/Types/MinimalPBR.materialtype", "materialTypeVersion": 3, - "properties": { - "settings": { - "color": [ - 0.08522164076566696, - 0.11898985505104065, - 1.0, - 1.0 - ], - "roughness": 0.33000001311302185 - } + "propertyValues": { + "settings.color": [ + 0.08522164076566696, + 0.11898985505104065, + 1.0, + 1.0 + ], + "settings.roughness": 0.33000001311302185 } } \ No newline at end of file diff --git a/AutomatedTesting/Materials/UVs.material b/AutomatedTesting/Materials/UVs.material index bd66df622e..4515b7c234 100644 --- a/AutomatedTesting/Materials/UVs.material +++ b/AutomatedTesting/Materials/UVs.material @@ -1,3 +1,3 @@ { "materialType": "UVs.materialtype" -} +} \ No newline at end of file diff --git a/AutomatedTesting/Materials/basic_grey.material b/AutomatedTesting/Materials/basic_grey.material index 6ecc1e029a..740a17b163 100644 --- a/AutomatedTesting/Materials/basic_grey.material +++ b/AutomatedTesting/Materials/basic_grey.material @@ -1,32 +1,26 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 1, - "properties": { - "baseColor": { - "color": [ 0.18, 0.18, 0.18 ], - "factor": 1.0, - "useTexture": false, - "textureMap": "" - }, - "metallic": { - "factor": 0.0, - "useTexture": false, - "textureMap": "" - }, - "roughness": { - "factor": 1.0, - "useTexture": false, - "textureMap": "" - }, - "specularF0": { - "factor": 0.5, - "useTexture": false, - "textureMap": "" - }, - "normal": { - "factor": 1.0, - "useTexture": false, - "textureMap": "" - } + "propertyValues": { + "baseColor.color": [ + 0.18000000715255737, + 0.18000000715255737, + 0.18000000715255737 + ], + "baseColor.factor": 1.0, + "baseColor.textureMap": "", + "baseColor.useTexture": false, + "metallic.factor": 0.0, + "metallic.textureMap": "", + "metallic.useTexture": false, + "normal.factor": 1.0, + "normal.textureMap": "", + "normal.useTexture": false, + "roughness.factor": 1.0, + "roughness.textureMap": "", + "roughness.useTexture": false, + "specularF0.factor": 0.5, + "specularF0.textureMap": "", + "specularF0.useTexture": false } -} +} \ No newline at end of file diff --git a/AutomatedTesting/Materials/decal/airship_symbol_decal.material b/AutomatedTesting/Materials/decal/airship_symbol_decal.material index 40060aafeb..f1faca6105 100644 --- a/AutomatedTesting/Materials/decal/airship_symbol_decal.material +++ b/AutomatedTesting/Materials/decal/airship_symbol_decal.material @@ -1,36 +1,20 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "textureMap": "Materials/decal/airship_symbol_decal.tif" - }, - "general": { - "doubleSided": true - }, - "metallic": { - "useTexture": false - }, - "normal": { - "useTexture": false - }, - "opacity": { - "alphaSource": "Split", - "factor": 0.6899999976158142, - "mode": "Cutout", - "textureMap": "Materials/decal/airship_symbol_decal.tif" - }, - "roughness": { - "useTexture": false - }, - "specularF0": { - "useTexture": false - }, - "uv": { - "center": [ - 0.0, - 1.0 - ] - } + "propertyValues": { + "baseColor.textureMap": "Materials/decal/airship_symbol_decal.tif", + "general.doubleSided": true, + "metallic.useTexture": false, + "normal.useTexture": false, + "opacity.alphaSource": "Split", + "opacity.factor": 0.6899999976158142, + "opacity.mode": "Cutout", + "opacity.textureMap": "Materials/decal/airship_symbol_decal.tif", + "roughness.useTexture": false, + "specularF0.useTexture": false, + "uv.center": [ + 0.0, + 1.0 + ] } } \ No newline at end of file diff --git a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material index 52c323b454..a918ef45be 100644 --- a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material +++ b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material @@ -1,13 +1,9 @@ { - "description": "", "materialType": "Materials/Types/Skin.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "wrinkleLayers": { - "count": 3, - "enable": true, - "showBlendValues": true - } + "propertyValues": { + "wrinkleLayers.count": 3, + "wrinkleLayers.enable": true, + "wrinkleLayers.showBlendValues": true } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material index 061510d4c2..4312a91ffe 100644 --- a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material +++ b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material @@ -1,30 +1,24 @@ { - "description": "", "materialType": "TestData/Materials/Types/AutoBrick.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "appearance": { - "ao": 0.5252525210380554, - "brickColor": [ - 0.3013504147529602, - 0.0032501716632395984, - 0.0032501716632395984, - 1.0 - ], - "brickColorBleed": 0.5050504803657532, - "brickColorNoise": 0.20202019810676576, - "lineColor": [ - 0.08339055627584458, - 0.07264820486307144, - 0.05905241519212723, - 1.0 - ], - "lineColorNoise": 0.35353541374206545 - }, - "shape": { - "brickWidth": 0.16660000383853913, - "lineDepth": 0.005454500205814838 - } + "propertyValues": { + "appearance.ao": 0.5252525210380554, + "appearance.brickColor": [ + 0.3013504147529602, + 0.0032501716632395983, + 0.0032501716632395983, + 1.0 + ], + "appearance.brickColorBleed": 0.5050504803657532, + "appearance.brickColorNoise": 0.20202019810676575, + "appearance.lineColor": [ + 0.08339055627584457, + 0.07264820486307144, + 0.05905241519212723, + 1.0 + ], + "appearance.lineColorNoise": 0.35353541374206543, + "shape.brickWidth": 0.16660000383853912, + "shape.lineDepth": 0.005454500205814838 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material index b81ff4110b..c4fbe58477 100644 --- a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material +++ b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material @@ -1,33 +1,27 @@ { - "description": "", "materialType": "TestData/Materials/Types/AutoBrick.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "appearance": { - "ao": 0.010100999847054482, - "brickColor": [ - 0.4612802267074585, - 0.6926985383033752, - 0.6798046827316284, - 1.0 - ], - "brickColorBleed": 0.5050504803657532, - "brickColorNoise": 0.05000000074505806, - "lineColor": [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - "lineColorNoise": 0.0 - }, - "shape": { - "brickHeight": 0.16660000383853913, - "brickOffset": 0.0, - "brickWidth": 0.16660000383853913, - "lineDepth": 0.0012121000327169896, - "lineWidth": 0.01030299998819828 - } + "propertyValues": { + "appearance.ao": 0.010100999847054482, + "appearance.brickColor": [ + 0.4612802267074585, + 0.6926985383033752, + 0.6798046827316284, + 1.0 + ], + "appearance.brickColorBleed": 0.5050504803657532, + "appearance.brickColorNoise": 0.05000000074505806, + "appearance.lineColor": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "appearance.lineColorNoise": 0.0, + "shape.brickHeight": 0.16660000383853912, + "shape.brickOffset": 0.0, + "shape.brickWidth": 0.16660000383853912, + "shape.lineDepth": 0.0012121000327169895, + "shape.lineWidth": 0.01030299998819828 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material b/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material index 1e140b9cf7..4348318fbd 100644 --- a/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material +++ b/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material @@ -1,33 +1,18 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "Materials/Presets/PBR/default_grid.material", "materialTypeVersion": 3, - "properties": { - "occlusion": { - "diffuseTextureMap": "TestData/Textures/cc0/Rock030_2K_AmbientOcclusion.jpg" - }, - "baseColor": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Color.jpg" - }, - "metallic": { - "useTexture": false - }, - "normal": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg" - }, - "parallax": { - "algorithm": "POM", - "factor": 0.03, - "quality": "High", - "textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg", - "pdo": true - }, - "roughness": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Roughness.jpg" - }, - "specularF0": { - "useTexture": false - } + "parentMaterial": "Materials/Presets/PBR/default_grid.material", + "propertyValues": { + "baseColor.textureMap": "TestData/Textures/cc0/Rock030_2K_Color.jpg", + "metallic.useTexture": false, + "normal.textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg", + "occlusion.diffuseTextureMap": "TestData/Textures/cc0/Rock030_2K_AmbientOcclusion.jpg", + "parallax.algorithm": "POM", + "parallax.factor": 0.029999999329447746, + "parallax.pdo": true, + "parallax.quality": "High", + "parallax.textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg", + "roughness.textureMap": "TestData/Textures/cc0/Rock030_2K_Roughness.jpg", + "specularF0.useTexture": false } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material index be607e7721..f5f52bbf7e 100644 --- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material +++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material @@ -1,55 +1,43 @@ { - "description": "", "materialType": "Materials/Types/Skin.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.1277027577161789, - 0.174273282289505, - 0.29372090101242068, - 1.0 - ], - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", - "useTexture": false - }, - "detailLayerGroup": { - "baseColorDetailBlend": 0.4300000071525574, - "baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", - "enableBaseColor": true, - "enableDetailLayer": true, - "enableNormals": true, - "normalDetailFlipY": true, - "normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", - "normalDetailStrength": 0.25999999046325686, - "textureMapUv": "Tiled" - }, - "detailUV": { - "scale": 5.0 - }, - "normal": { - "flipY": true, - "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png" - }, - "subsurfaceScattering": { - "enableSubsurfaceScattering": true, - "influenceMap": "Objects/Hermanubis/Hermanubis_thickness.tif", - "scatterDistance": 15.0, - "subsurfaceScatterFactor": 0.4300000071525574, - "thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif", - "transmissionAttenuation": 15.0, - "transmissionDistortion": 0.3499999940395355, - "transmissionMode": "ThickObject", - "transmissionPower": 16.399999618530275, - "transmissionScale": 0.10000000149011612, - "transmissionTint": [ - 1.0, - 0.3182879388332367, - 0.16388189792633058, - 1.0 - ], - "useInfluenceMap": false - } + "propertyValues": { + "baseColor.color": [ + 0.1277027577161789, + 0.174273282289505, + 0.29372090101242065, + 1.0 + ], + "baseColor.textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", + "baseColor.useTexture": false, + "detailLayerGroup.baseColorDetailBlend": 0.4300000071525574, + "detailLayerGroup.baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", + "detailLayerGroup.enableBaseColor": true, + "detailLayerGroup.enableDetailLayer": true, + "detailLayerGroup.enableNormals": true, + "detailLayerGroup.normalDetailFlipY": true, + "detailLayerGroup.normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", + "detailLayerGroup.normalDetailStrength": 0.25999999046325684, + "detailLayerGroup.textureMapUv": "Tiled", + "detailUV.scale": 5.0, + "normal.flipY": true, + "normal.textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", + "subsurfaceScattering.enableSubsurfaceScattering": true, + "subsurfaceScattering.influenceMap": "Objects/Hermanubis/Hermanubis_thickness.tif", + "subsurfaceScattering.scatterDistance": 15.0, + "subsurfaceScattering.subsurfaceScatterFactor": 0.4300000071525574, + "subsurfaceScattering.thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif", + "subsurfaceScattering.transmissionAttenuation": 15.0, + "subsurfaceScattering.transmissionDistortion": 0.3499999940395355, + "subsurfaceScattering.transmissionMode": "ThickObject", + "subsurfaceScattering.transmissionPower": 16.399999618530273, + "subsurfaceScattering.transmissionScale": 0.10000000149011612, + "subsurfaceScattering.transmissionTint": [ + 1.0, + 0.3182879388332367, + 0.16388189792633057, + 1.0 + ], + "subsurfaceScattering.useInfluenceMap": false } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material index 4222108b5e..3e3fe338c5 100644 --- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material +++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material @@ -1,63 +1,49 @@ { - "description": "", "materialType": "Materials/Types/Skin.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.2847791314125061, - 0.45421531796455386, - 0.9392080307006836, - 1.0 - ], - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png" - }, - "detailLayerGroup": { - "baseColorDetailBlend": 0.4300000071525574, - "baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", - "enableBaseColor": true, - "enableDetailLayer": true, - "enableNormals": true, - "normalDetailFlipY": true, - "normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", - "normalDetailStrength": 1.5, - "textureMapUv": "Tiled" - }, - "detailUV": { - "scale": 5.0 - }, - "normal": { - "flipY": true, - "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png" - }, - "subsurfaceScattering": { - "enableSubsurfaceScattering": true, - "influenceMap": "TestData/Textures/checker8x8_gray_512.png", - "scatterDistance": 15.0, - "subsurfaceScatterFactor": 0.4300000071525574, - "thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif", - "transmissionAttenuation": 15.0, - "transmissionDistortion": 0.3499999940395355, - "transmissionMode": "ThickObject", - "transmissionPower": 16.399999618530275, - "transmissionScale": 0.10000000149011612, - "transmissionTint": [ - 1.0, - 0.3182879388332367, - 0.16388189792633058, - 1.0 - ] - }, - "wrinkleLayers": { - "baseColorMap1": "TestData/Textures/cc0/Lava004_1K_Color.jpg", - "baseColorMap3": "TestData/Textures/checker8x8_gray_512.png", - "count": 3, - "enable": true, - "enableBaseColor": true, - "enableNormal": true, - "normalMap1": "TestData/Textures/cc0/Lava004_1K_Normal.jpg", - "normalMap2": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png" - } + "propertyValues": { + "baseColor.color": [ + 0.2847791314125061, + 0.45421531796455383, + 0.9392080307006836, + 1.0 + ], + "baseColor.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png", + "detailLayerGroup.baseColorDetailBlend": 0.4300000071525574, + "detailLayerGroup.baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", + "detailLayerGroup.enableBaseColor": true, + "detailLayerGroup.enableDetailLayer": true, + "detailLayerGroup.enableNormals": true, + "detailLayerGroup.normalDetailFlipY": true, + "detailLayerGroup.normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", + "detailLayerGroup.normalDetailStrength": 1.5, + "detailLayerGroup.textureMapUv": "Tiled", + "detailUV.scale": 5.0, + "normal.flipY": true, + "normal.textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", + "subsurfaceScattering.enableSubsurfaceScattering": true, + "subsurfaceScattering.influenceMap": "TestData/Textures/checker8x8_gray_512.png", + "subsurfaceScattering.scatterDistance": 15.0, + "subsurfaceScattering.subsurfaceScatterFactor": 0.4300000071525574, + "subsurfaceScattering.thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif", + "subsurfaceScattering.transmissionAttenuation": 15.0, + "subsurfaceScattering.transmissionDistortion": 0.3499999940395355, + "subsurfaceScattering.transmissionMode": "ThickObject", + "subsurfaceScattering.transmissionPower": 16.399999618530273, + "subsurfaceScattering.transmissionScale": 0.10000000149011612, + "subsurfaceScattering.transmissionTint": [ + 1.0, + 0.3182879388332367, + 0.16388189792633057, + 1.0 + ], + "wrinkleLayers.baseColorMap1": "TestData/Textures/cc0/Lava004_1K_Color.jpg", + "wrinkleLayers.baseColorMap3": "TestData/Textures/checker8x8_gray_512.png", + "wrinkleLayers.count": 3, + "wrinkleLayers.enable": true, + "wrinkleLayers.enableBaseColor": true, + "wrinkleLayers.enableNormal": true, + "wrinkleLayers.normalMap1": "TestData/Textures/cc0/Lava004_1K_Normal.jpg", + "wrinkleLayers.normalMap2": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material index f683ad052d..29c5cd2cbe 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material @@ -1,156 +1,96 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "blend": { - "enableLayer2": true, - "enableLayer3": true - }, - "layer1_baseColor": { - "color": [ - 0.3495536744594574, - 0.2659952640533447, - 0.12039368599653244, - 1.0 - ], - "textureMap": "TestData/Textures/cc0/bark1_col.jpg" - }, - "layer1_emissive": { - "color": [ - 0.8521705865859985, - 0.029510948807001115, - 0.029510948807001115, - 1.0 - ], - "intensity": 0.8199999928474426 - }, - "layer1_normal": { - "factor": 0.4444443881511688, - "flipY": true, - "textureMap": "TestData/Textures/cc0/bark1_norm.jpg" - }, - "layer1_occlusion": { - "diffuseFactor": 1.6399999856948853, - "diffuseTextureMap": "TestData/Textures/cc0/bark1_disp.jpg" - }, - "layer1_parallax": { - "factor": 0.02500000037252903, - "textureMap": "TestData/Textures/cc0/bark1_disp.jpg" - }, - "layer1_roughness": { - "lowerBound": 0.010100999847054482, - "textureMap": "TestData/Textures/cc0/bark1_roughness.jpg" - }, - "layer1_specularF0": { - "factor": 0.5099999904632568, - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "layer1_uv": { - "center": [ - 0.75, - 0.75 - ], - "offsetU": 0.5, - "offsetV": 0.25 - }, - "layer2_baseColor": { - "textureMap": "TestData/Textures/cc0/Lava004_1K_Color.jpg" - }, - "layer2_clearCoat": { - "enable": true, - "influenceMap": "TestData/Textures/checker8x8_512.png", - "normalMap": "TestData/Objects/cube/cube_norm.tif", - "normalStrength": 0.5400000214576721, - "roughness": 0.10000000149011612 - }, - "layer2_emissive": { - "enable": true, - "intensity": 2.140000104904175, - "textureMap": "TestData/Textures/cc0/Lava004_1K_Emission.jpg" - }, - "layer2_normal": { - "flipY": true, - "textureMap": "TestData/Textures/cc0/Lava004_1K_Normal.jpg" - }, - "layer2_occlusion": { - "specularFactor": 2.0, - "specularTextureMap": "TestData/Textures/cc0/Tiles009_1K_Displacement.jpg" - }, - "layer2_parallax": { - "factor": 0.01600000075995922, - "textureMap": "TestData/Textures/cc0/Lava004_1K_Displacement.jpg" - }, - "layer2_roughness": { - "textureMap": "TestData/Textures/cc0/Lava004_1K_Roughness.jpg" - }, - "layer2_uv": { - "center": [ - 0.0, - 0.0 - ], - "offsetU": 0.5, - "offsetV": 0.25 - }, - "layer3_baseColor": { - "color": [ - 0.6315556764602661, - 1.0, - 0.9451438188552856, - 1.0 - ], - "textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Color.jpg" - }, - "layer3_clearCoat": { - "influenceMap": "TestData/Textures/checker8x8_512.png" - }, - "layer3_emissive": { - "intensity": -0.9399999976158142 - }, - "layer3_metallic": { - "factor": 1.0, - "textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Metalness.jpg" - }, - "layer3_normal": { - "textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Normal.jpg" - }, - "layer3_occlusion": { - "diffuseFactor": 1.0399999618530274, - "diffuseTextureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Displacement.jpg" - }, - "layer3_parallax": { - "factor": 0.004999999888241291, - "textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Displacement.jpg" - }, - "layer3_roughness": { - "lowerBound": 0.07999999821186066, - "textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Roughness.jpg", - "upperBound": 0.75 - }, - "layer3_specularF0": { - "factor": 0.47474750876426699 - }, - "layer3_uv": { - "center": [ - 0.0, - 0.0 - ], - "offsetU": 0.11999999731779099, - "rotateDegrees": -57.599998474121097 - }, - "parallax": { - "quality": "Medium" - }, - "uv": { - "center": [ - 0.10000000149011612, - 0.20000000298023225 - ], - "offsetU": 0.23000000417232514, - "offsetV": -0.23999999463558198, - "rotateDegrees": 39.599998474121097, - "scale": 1.100000023841858 - } + "propertyValues": { + "blend.enableLayer2": true, + "blend.enableLayer3": true, + "layer1_baseColor.color": [ + 0.3495536744594574, + 0.2659952640533447, + 0.12039368599653244, + 1.0 + ], + "layer1_baseColor.textureMap": "TestData/Textures/cc0/bark1_col.jpg", + "layer1_emissive.color": [ + 0.8521705865859985, + 0.029510948807001114, + 0.029510948807001114, + 1.0 + ], + "layer1_emissive.intensity": 0.8199999928474426, + "layer1_normal.factor": 0.4444443881511688, + "layer1_normal.flipY": true, + "layer1_normal.textureMap": "TestData/Textures/cc0/bark1_norm.jpg", + "layer1_occlusion.diffuseFactor": 1.6399999856948853, + "layer1_occlusion.diffuseTextureMap": "TestData/Textures/cc0/bark1_disp.jpg", + "layer1_parallax.factor": 0.02500000037252903, + "layer1_parallax.textureMap": "TestData/Textures/cc0/bark1_disp.jpg", + "layer1_roughness.lowerBound": 0.010100999847054482, + "layer1_roughness.textureMap": "TestData/Textures/cc0/bark1_roughness.jpg", + "layer1_specularF0.factor": 0.5099999904632568, + "layer1_specularF0.textureMap": "TestData/Textures/checker8x8_512.png", + "layer1_uv.center": [ + 0.75, + 0.75 + ], + "layer1_uv.offsetU": 0.5, + "layer1_uv.offsetV": 0.25, + "layer2_baseColor.textureMap": "TestData/Textures/cc0/Lava004_1K_Color.jpg", + "layer2_clearCoat.enable": true, + "layer2_clearCoat.influenceMap": "TestData/Textures/checker8x8_512.png", + "layer2_clearCoat.normalMap": "TestData/Objects/cube/cube_norm.tif", + "layer2_clearCoat.normalStrength": 0.5400000214576721, + "layer2_clearCoat.roughness": 0.10000000149011612, + "layer2_emissive.enable": true, + "layer2_emissive.intensity": 2.140000104904175, + "layer2_emissive.textureMap": "TestData/Textures/cc0/Lava004_1K_Emission.jpg", + "layer2_normal.flipY": true, + "layer2_normal.textureMap": "TestData/Textures/cc0/Lava004_1K_Normal.jpg", + "layer2_occlusion.specularFactor": 2.0, + "layer2_occlusion.specularTextureMap": "TestData/Textures/cc0/Tiles009_1K_Displacement.jpg", + "layer2_parallax.factor": 0.01600000075995922, + "layer2_parallax.textureMap": "TestData/Textures/cc0/Lava004_1K_Displacement.jpg", + "layer2_roughness.textureMap": "TestData/Textures/cc0/Lava004_1K_Roughness.jpg", + "layer2_uv.center": [ + 0.0, + 0.0 + ], + "layer2_uv.offsetU": 0.5, + "layer2_uv.offsetV": 0.25, + "layer3_baseColor.color": [ + 0.6315556764602661, + 1.0, + 0.9451438188552856, + 1.0 + ], + "layer3_baseColor.textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Color.jpg", + "layer3_clearCoat.influenceMap": "TestData/Textures/checker8x8_512.png", + "layer3_emissive.intensity": -0.9399999976158142, + "layer3_metallic.factor": 1.0, + "layer3_metallic.textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Metalness.jpg", + "layer3_normal.textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Normal.jpg", + "layer3_occlusion.diffuseFactor": 1.0399999618530273, + "layer3_occlusion.diffuseTextureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Displacement.jpg", + "layer3_parallax.factor": 0.004999999888241291, + "layer3_parallax.textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Displacement.jpg", + "layer3_roughness.lowerBound": 0.07999999821186066, + "layer3_roughness.textureMap": "TestData/Textures/cc0/PaintedMetal003_1K_Roughness.jpg", + "layer3_roughness.upperBound": 0.75, + "layer3_specularF0.factor": 0.47474750876426697, + "layer3_uv.center": [ + 0.0, + 0.0 + ], + "layer3_uv.offsetU": 0.11999999731779099, + "layer3_uv.rotateDegrees": -57.599998474121094, + "parallax.quality": "Medium", + "uv.center": [ + 0.10000000149011612, + 0.20000000298023224 + ], + "uv.offsetU": 0.23000000417232513, + "uv.offsetV": -0.23999999463558197, + "uv.rotateDegrees": 39.599998474121094, + "uv.scale": 1.100000023841858 } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material index 042f31f3ec..9318469c74 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "enableLayer2": false - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material", + "propertyValues": { + "blend.enableLayer2": false } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material index 59fc168a6c..e6d2da09cc 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "enableLayer3": false - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material", + "propertyValues": { + "blend.enableLayer3": false } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material index a1d3c288ea..cd244f5273 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material @@ -1,55 +1,29 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "blend": { - "enableLayer2": true, - "enableLayer3": true - }, - "layer1_baseColor": { - "textureMap": "TestData/Textures/cc0/bark1_col.jpg" - }, - "layer1_normal": { - "textureMap": "TestData/Textures/cc0/bark1_norm.jpg" - }, - "layer1_parallax": { - "factor": 0.03999999910593033, - "textureMap": "TestData/Textures/cc0/bark1_disp.jpg" - }, - "layer1_roughness": { - "textureMap": "TestData/Textures/cc0/bark1_roughness.jpg" - }, - "layer2_baseColor": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Color.jpg" - }, - "layer2_clearCoat": { - "normalStrength": 0.0 - }, - "layer2_normal": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg" - }, - "layer2_parallax": { - "factor": 0.05299999937415123, - "offset": -0.024000000208616258, - "textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg" - }, - "layer2_roughness": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Roughness.jpg" - }, - "layer3_baseColor": { - "color": [ - 0.4298008680343628, - 0.4298008680343628, - 0.4298008680343628, - 1.0 - ], - "textureMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg" - }, - "parallax": { - "pdo": true, - "quality": "Medium" - } + "propertyValues": { + "blend.enableLayer2": true, + "blend.enableLayer3": true, + "layer1_baseColor.textureMap": "TestData/Textures/cc0/bark1_col.jpg", + "layer1_normal.textureMap": "TestData/Textures/cc0/bark1_norm.jpg", + "layer1_parallax.factor": 0.03999999910593033, + "layer1_parallax.textureMap": "TestData/Textures/cc0/bark1_disp.jpg", + "layer1_roughness.textureMap": "TestData/Textures/cc0/bark1_roughness.jpg", + "layer2_baseColor.textureMap": "TestData/Textures/cc0/Rock030_2K_Color.jpg", + "layer2_clearCoat.normalStrength": 0.0, + "layer2_normal.textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg", + "layer2_parallax.factor": 0.05299999937415123, + "layer2_parallax.offset": -0.024000000208616257, + "layer2_parallax.textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg", + "layer2_roughness.textureMap": "TestData/Textures/cc0/Rock030_2K_Roughness.jpg", + "layer3_baseColor.color": [ + 0.4298008680343628, + 0.4298008680343628, + 0.4298008680343628, + 1.0 + ], + "layer3_baseColor.textureMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", + "parallax.pdo": true, + "parallax.quality": "Medium" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material index b7be8ab18f..9e831e6412 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "debugDrawMode": "BlendMask" - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", + "propertyValues": { + "blend.debugDrawMode": "BlendMask" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material index 99a9c9f382..69877b3025 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "debugDrawMode": "FinalBlendWeights" - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", + "propertyValues": { + "blend.debugDrawMode": "FinalBlendWeights" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material index 6dbee69845..04c921a955 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "debugDrawMode": "Displacement" - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", + "propertyValues": { + "blend.debugDrawMode": "Displacement" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material index b53df9a505..3a55475bcd 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material @@ -1,14 +1,9 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "blendSource": "BlendMaskVertexColors" - }, - "parallax": { - "quality": "Medium" - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", + "propertyValues": { + "blend.blendSource": "BlendMaskVertexColors", + "parallax.quality": "Medium" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material index f313080cce..9bc96f315f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material @@ -1,81 +1,43 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "blend": { - "blendSource": "Displacement", - "displacementBlendDistance": 0.008999999612569809, - "enableLayer2": true, - "enableLayer3": true - }, - "layer1_baseColor": { - "textureMap": "TestData/Textures/cc0/Ground033_1K_Color.jpg" - }, - "layer1_normal": { - "textureMap": "TestData/Textures/cc0/Ground033_1K_Normal.jpg" - }, - "layer1_occlusion": { - "diffuseTextureMap": "TestData/Textures/cc0/Ground033_1K_AmbientOcclusion.jpg" - }, - "layer1_parallax": { - "factor": 0.017000000923871995, - "offset": -0.006000000052154064, - "textureMap": "TestData/Textures/cc0/Ground033_1K_Displacement.jpg" - }, - "layer1_roughness": { - "textureMap": "TestData/Textures/cc0/Ground033_1K_Roughness.jpg" - }, - "layer2_baseColor": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Color.jpg" - }, - "layer2_normal": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg" - }, - "layer2_occlusion": { - "diffuseTextureMap": "TestData/Textures/cc0/Rocks002_1K_AmbientOcclusion.jpg" - }, - "layer2_parallax": { - "factor": 0.03099999949336052, - "offset": 0.0020000000949949028, - "textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg" - }, - "layer2_roughness": { - "textureMap": "TestData/Textures/cc0/Rock030_2K_Roughness.jpg" - }, - "layer2_uv": { - "center": [ - 0.0, - 0.0 - ], - "offsetU": 0.1599999964237213, - "offsetV": 0.07999999821186066, - "rotateDegrees": 90.0 - }, - "layer3_baseColor": { - "textureMap": "TestData/Textures/cc0/Rocks002_1K_Color.jpg" - }, - "layer3_normal": { - "textureMap": "TestData/Textures/cc0/Rocks002_1K_Normal.jpg" - }, - "layer3_parallax": { - "factor": 0.027000000700354577, - "textureMap": "TestData/Textures/cc0/Rocks002_1K_Displacement.jpg" - }, - "layer3_roughness": { - "textureMap": "TestData/Textures/cc0/Rocks002_1K_Roughness.jpg" - }, - "layer3_uv": { - "center": [ - 0.0, - 0.0 - ], - "scale": 3.4999988079071047 - }, - "parallax": { - "algorithm": "Relief", - "pdo": true - } + "propertyValues": { + "blend.blendSource": "Displacement", + "blend.displacementBlendDistance": 0.008999999612569809, + "blend.enableLayer2": true, + "blend.enableLayer3": true, + "layer1_baseColor.textureMap": "TestData/Textures/cc0/Ground033_1K_Color.jpg", + "layer1_normal.textureMap": "TestData/Textures/cc0/Ground033_1K_Normal.jpg", + "layer1_occlusion.diffuseTextureMap": "TestData/Textures/cc0/Ground033_1K_AmbientOcclusion.jpg", + "layer1_parallax.factor": 0.017000000923871994, + "layer1_parallax.offset": -0.006000000052154064, + "layer1_parallax.textureMap": "TestData/Textures/cc0/Ground033_1K_Displacement.jpg", + "layer1_roughness.textureMap": "TestData/Textures/cc0/Ground033_1K_Roughness.jpg", + "layer2_baseColor.textureMap": "TestData/Textures/cc0/Rock030_2K_Color.jpg", + "layer2_normal.textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg", + "layer2_occlusion.diffuseTextureMap": "TestData/Textures/cc0/Rocks002_1K_AmbientOcclusion.jpg", + "layer2_parallax.factor": 0.03099999949336052, + "layer2_parallax.offset": 0.0020000000949949026, + "layer2_parallax.textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg", + "layer2_roughness.textureMap": "TestData/Textures/cc0/Rock030_2K_Roughness.jpg", + "layer2_uv.center": [ + 0.0, + 0.0 + ], + "layer2_uv.offsetU": 0.1599999964237213, + "layer2_uv.offsetV": 0.07999999821186066, + "layer2_uv.rotateDegrees": 90.0, + "layer3_baseColor.textureMap": "TestData/Textures/cc0/Rocks002_1K_Color.jpg", + "layer3_normal.textureMap": "TestData/Textures/cc0/Rocks002_1K_Normal.jpg", + "layer3_parallax.factor": 0.027000000700354576, + "layer3_parallax.textureMap": "TestData/Textures/cc0/Rocks002_1K_Displacement.jpg", + "layer3_roughness.textureMap": "TestData/Textures/cc0/Rocks002_1K_Roughness.jpg", + "layer3_uv.center": [ + 0.0, + 0.0 + ], + "layer3_uv.scale": 3.4999988079071045, + "parallax.algorithm": "Relief", + "parallax.pdo": true } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material index 6f64bcd49f..984fd93cdf 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "enableLayer2": false - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", + "propertyValues": { + "blend.enableLayer2": false } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material index 8b32223c82..491d2ffd89 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "enableLayer3": false - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", + "propertyValues": { + "blend.enableLayer3": false } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material index 023316c5f6..2b91cf8e17 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material @@ -1,14 +1,9 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "blendSource": "Displacement_With_BlendMaskTexture" - }, - "layer1_parallax": { - "offset": -0.004000000189989805 - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", + "propertyValues": { + "blend.blendSource": "Displacement_With_BlendMaskTexture", + "layer1_parallax.offset": -0.004000000189989805 } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material index d88802d4de..89b72f810b 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material @@ -1,23 +1,14 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "displacementBlendDistance": 0.0010000000474974514 - }, - "layer1_parallax": { - "offset": -0.00800000037997961, - "textureMap": "" - }, - "layer2_parallax": { - "offset": -0.00800000037997961, - "textureMap": "" - }, - "layer3_parallax": { - "offset": -0.00800000037997961, - "textureMap": "" - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material", + "propertyValues": { + "blend.displacementBlendDistance": 0.0010000000474974513, + "layer1_parallax.offset": -0.00800000037997961, + "layer1_parallax.textureMap": "", + "layer2_parallax.offset": -0.00800000037997961, + "layer2_parallax.textureMap": "", + "layer3_parallax.offset": -0.00800000037997961, + "layer3_parallax.textureMap": "" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material index 9ba4d20a9a..a431f63112 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material @@ -1,20 +1,13 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material", "materialTypeVersion": 3, - "properties": { - "layer1_parallax": { - "offset": -0.03200000151991844, - "textureMap": "" - }, - "layer2_parallax": { - "offset": -0.00800000037997961, - "textureMap": "" - }, - "layer3_parallax": { - "offset": -0.00800000037997961, - "textureMap": "" - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material", + "propertyValues": { + "layer1_parallax.offset": -0.03200000151991844, + "layer1_parallax.textureMap": "", + "layer2_parallax.offset": -0.00800000037997961, + "layer2_parallax.textureMap": "", + "layer3_parallax.offset": -0.00800000037997961, + "layer3_parallax.textureMap": "" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material index 51219aa180..3a4e16b85e 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material @@ -1,15 +1,10 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", "materialTypeVersion": 3, - "properties": { - "blend": { - "blendSource": "Displacement_With_BlendMaskVertexColors", - "displacementBlendDistance": 0.02387000061571598 - }, - "parallax": { - "enable": false - } + "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", + "propertyValues": { + "blend.blendSource": "Displacement_With_BlendMaskVertexColors", + "blend.displacementBlendDistance": 0.02387000061571598, + "parallax.enable": false } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material index 164b73c892..5b5e902752 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material @@ -1,6 +1,4 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3 } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material index 29329a03a2..c2d6cafb1b 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material @@ -1,19 +1,15 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.2541542649269104, - 0.5271076560020447, - 0.8388037085533142, - 1.0 - ], - "factor": 0.75, - "textureBlendMode": "Lerp", - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_hp_bc.png" - } + "propertyValues": { + "baseColor.color": [ + 0.2541542649269104, + 0.5271076560020447, + 0.8388037085533142, + 1.0 + ], + "baseColor.factor": 0.75, + "baseColor.textureBlendMode": "Lerp", + "baseColor.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_hp_bc.png" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material index 46a8fd70ef..ecad50b541 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material @@ -1,19 +1,15 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.2541542649269104, - 0.5271076560020447, - 0.8388037085533142, - 1.0 - ], - "factor": 0.75, - "textureBlendMode": "LinearLight", - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_hp_bc.png" - } + "propertyValues": { + "baseColor.color": [ + 0.2541542649269104, + 0.5271076560020447, + 0.8388037085533142, + 1.0 + ], + "baseColor.factor": 0.75, + "baseColor.textureBlendMode": "LinearLight", + "baseColor.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_hp_bc.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material index 7abf4ca40c..c76bb9ff90 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material @@ -1,18 +1,14 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.2541542649269104, - 0.5271076560020447, - 0.8388037085533142, - 1.0 - ], - "factor": 0.75, - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_hp_bc.png" - } + "propertyValues": { + "baseColor.color": [ + 0.2541542649269104, + 0.5271076560020447, + 0.8388037085533142, + 1.0 + ], + "baseColor.factor": 0.75, + "baseColor.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_hp_bc.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material index 73ad13e27b..dabedfeb19 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material @@ -1,22 +1,14 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5, - 0.5, - 0.5, - 1.0 - ] - }, - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.33 - } + "propertyValues": { + "baseColor.color": [ + 0.5, + 0.5, + 0.5, + 1.0 + ], + "metallic.factor": 1.0, + "roughness.factor": 0.33000001311302185 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material index 9dea40d6ec..4dfbb4804d 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material @@ -1,22 +1,14 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5, - 0.5, - 0.5, - 1.0 - ] - }, - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.1 - } + "propertyValues": { + "baseColor.color": [ + 0.5, + 0.5, + 0.5, + 1.0 + ], + "metallic.factor": 1.0, + "roughness.factor": 0.10000000149011612 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material index d20e354a53..5c5f7a4bc7 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material @@ -1,23 +1,15 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5093766450881958, - 0.5093766450881958, - 0.5093766450881958, - 1.0 - ] - }, - "metallic": { - "factor": 1.0, - "textureMap": "TestData/Textures/checker8x8_gray_512.png" - }, - "roughness": { - "factor": 0.5 - } + "propertyValues": { + "baseColor.color": [ + 0.5093766450881958, + 0.5093766450881958, + 0.5093766450881958, + 1.0 + ], + "metallic.factor": 1.0, + "metallic.textureMap": "TestData/Textures/checker8x8_gray_512.png", + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material index 283c6ac60b..1cc5d49f0e 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material @@ -1,25 +1,17 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5093766450881958, - 0.5093766450881958, - 0.5093766450881958, - 1.0 - ] - }, - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 0.5353534817695618, - "upperBound": 0.20202019810676576, - "lowerBound": 0.6464645862579346, - "textureMap": "TestData/Textures/checker8x8_gray_512.png" - } + "propertyValues": { + "baseColor.color": [ + 0.5093766450881958, + 0.5093766450881958, + 0.5093766450881958, + 1.0 + ], + "metallic.factor": 1.0, + "roughness.factor": 0.5353534817695618, + "roughness.lowerBound": 0.6464645862579346, + "roughness.textureMap": "TestData/Textures/checker8x8_gray_512.png", + "roughness.upperBound": 0.20202019810676575 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material index 11228e2199..23361702c3 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material @@ -1,22 +1,14 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.3330281674861908, - 0.3330281674861908, - 0.3330281674861908, - 1.0 - ] - }, - "roughness": { - "factor": 0.0 - }, - "specularF0": { - "textureMap": "TestData/Textures/checker8x8_gray_512.png" - } + "propertyValues": { + "baseColor.color": [ + 0.3330281674861908, + 0.3330281674861908, + 0.3330281674861908, + 1.0 + ], + "roughness.factor": 0.0, + "specularF0.textureMap": "TestData/Textures/checker8x8_gray_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material index 3b9779aac1..26d5f1e9e6 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material @@ -1,26 +1,16 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.9764705896377564, - 0.7098039388656616, - 0.125490203499794, - 1.0 - ] - }, - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 1.0 - }, - "specularF0": { - "enableMultiScatterCompensation": false, - "factor": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.9764705896377563, + 0.7098039388656616, + 0.125490203499794, + 1.0 + ], + "metallic.factor": 1.0, + "roughness.factor": 1.0, + "specularF0.enableMultiScatterCompensation": false, + "specularF0.factor": 1.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material index dbbcdc631d..7d7d323b7a 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material @@ -1,26 +1,16 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.9764705896377564, - 0.7098039388656616, - 0.125490203499794, - 1.0 - ] - }, - "metallic": { - "factor": 1.0 - }, - "roughness": { - "factor": 1.0 - }, - "specularF0": { - "enableMultiScatterCompensation": true, - "factor": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.9764705896377563, + 0.7098039388656616, + 0.125490203499794, + 1.0 + ], + "metallic.factor": 1.0, + "roughness.factor": 1.0, + "specularF0.enableMultiScatterCompensation": true, + "specularF0.factor": 1.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material index 4b2842a594..973c6132e7 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material @@ -1,21 +1,15 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5521476864814758, - 0.5521476864814758, - 0.5521476864814758, - 1.0 - ] - }, - "normal": { - "factor": 0.75, - "flipY": true, - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png" - } + "propertyValues": { + "baseColor.color": [ + 0.5521476864814758, + 0.5521476864814758, + 0.5521476864814758, + 1.0 + ], + "normal.factor": 0.75, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material index aec3bbf478..1326ed4317 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material @@ -1,12 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.30000001192092898, - "textureMap": "TestData/Objects/cube/cube_norm.tif" - } + "propertyValues": { + "normal.factor": 0.30000001192092896, + "normal.textureMap": "TestData/Objects/cube/cube_norm.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material index 1528403868..42534744a6 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material @@ -1,23 +1,17 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5906767249107361, - 1.0, - 0.11703670024871826, - 1.0 - ], - "textureMap": "Textures/Default/default_basecolor.tif" - }, - "opacity": { - "alphaSource": "Split", - "factor": 0.75, - "mode": "Blended", - "textureMap": "TestData/Textures/checker8x8_gray_512.png" - } + "propertyValues": { + "baseColor.color": [ + 0.5906767249107361, + 1.0, + 0.11703670024871826, + 1.0 + ], + "baseColor.textureMap": "Textures/Default/default_basecolor.tif", + "opacity.alphaSource": "Split", + "opacity.factor": 0.75, + "opacity.mode": "Blended", + "opacity.textureMap": "TestData/Textures/checker8x8_gray_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material index 20f5ccf098..960a1a42cf 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material @@ -1,24 +1,18 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5906767249107361, - 1.0, - 0.11703670024871826, - 1.0 - ], - "textureMap": "Textures/Default/default_basecolor.tif" - }, - "opacity": { - "alphaSource": "Split", - "factor": 0.75, - "mode": "Blended", - "textureMap": "TestData/Textures/checker8x8_gray_512.png", - "alphaAffectsSpecular": 1.0 - } + "propertyValues": { + "baseColor.color": [ + 0.5906767249107361, + 1.0, + 0.11703670024871826, + 1.0 + ], + "baseColor.textureMap": "Textures/Default/default_basecolor.tif", + "opacity.alphaAffectsSpecular": 1.0, + "opacity.alphaSource": "Split", + "opacity.factor": 0.75, + "opacity.mode": "Blended", + "opacity.textureMap": "TestData/Textures/checker8x8_gray_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material index d8683681c4..9acd51694f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material @@ -1,16 +1,10 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "TestData/Textures/Foliage_Leaves_0_BaseColor.dds" - }, - "opacity": { - "doubleSided": true, - "mode": "Cutout", - "textureMap": "TestData/Textures/checker8x8_512.png" - } + "propertyValues": { + "baseColor.textureMap": "TestData/Textures/Foliage_Leaves_0_BaseColor.dds", + "opacity.doubleSided": true, + "opacity.mode": "Cutout", + "opacity.textureMap": "TestData/Textures/checker8x8_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material index 8e8dad46d8..cad29a9f77 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material @@ -1,14 +1,10 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "opacity": { - "alphaSource": "Split", - "doubleSided": true, - "mode": "Cutout", - "textureMap": "TestData/Textures/checker8x8_512.png" - } + "propertyValues": { + "opacity.alphaSource": "Split", + "opacity.doubleSided": true, + "opacity.mode": "Cutout", + "opacity.textureMap": "TestData/Textures/checker8x8_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material index 2d9b4c514b..9429e31fb6 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material @@ -1,13 +1,9 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "opacity": { - "alphaSource": "Split", - "mode": "Cutout", - "textureMap": "TestData/Textures/checker8x8_512.png" - } + "propertyValues": { + "opacity.alphaSource": "Split", + "opacity.mode": "Cutout", + "opacity.textureMap": "TestData/Textures/checker8x8_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material index f7ac93a7ac..835e19a4f3 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material @@ -1,14 +1,8 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "Textures/Default/checker_uv_basecolor.png" - }, - "general": { - "doubleSided": true - } + "propertyValues": { + "baseColor.textureMap": "Textures/Default/checker_uv_basecolor.png", + "general.doubleSided": true } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material index 9d36d0a7e6..a9e60e7f5e 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material @@ -1,23 +1,17 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.5906767249107361, - 1.0, - 0.11703670024871826, - 1.0 - ], - "textureMap": "Textures/Default/default_basecolor.tif" - }, - "opacity": { - "alphaSource": "Split", - "factor": 0.75, - "mode": "TintedTransparent", - "textureMap": "TestData/Textures/checker8x8_gray_512.png" - } + "propertyValues": { + "baseColor.color": [ + 0.5906767249107361, + 1.0, + 0.11703670024871826, + 1.0 + ], + "baseColor.textureMap": "Textures/Default/default_basecolor.tif", + "opacity.alphaSource": "Split", + "opacity.factor": 0.75, + "opacity.mode": "TintedTransparent", + "opacity.textureMap": "TestData/Textures/checker8x8_gray_512.png" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material index a7fe0d1d4d..8ccf39096a 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material @@ -1,12 +1,9 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "010_OcclusionBase.material", "materialTypeVersion": 3, - "properties": { - "occlusion": { - "diffuseFactor": 2.0, - "diffuseTextureMap": "TestData/Textures/cc0/Tiles009_1K_AmbientOcclusion.jpg" - } + "parentMaterial": "010_OcclusionBase.material", + "propertyValues": { + "occlusion.diffuseFactor": 2.0, + "occlusion.diffuseTextureMap": "TestData/Textures/cc0/Tiles009_1K_AmbientOcclusion.jpg" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material index 1f9c94db47..b2b2b90363 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material @@ -1,14 +1,11 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "010_OcclusionBase.material", "materialTypeVersion": 3, - "properties": { - "occlusion": { - "diffuseFactor": 2.0, - "diffuseTextureMap": "TestData/Textures/cc0/Tiles009_1K_AmbientOcclusion.jpg", - "specularFactor": 2.0, - "specularTextureMap": "TestData/Textures/cc0/Tiles009_1K_Displacement.jpg" - } + "parentMaterial": "010_OcclusionBase.material", + "propertyValues": { + "occlusion.diffuseFactor": 2.0, + "occlusion.diffuseTextureMap": "TestData/Textures/cc0/Tiles009_1K_AmbientOcclusion.jpg", + "occlusion.specularFactor": 2.0, + "occlusion.specularTextureMap": "TestData/Textures/cc0/Tiles009_1K_Displacement.jpg" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material index 534305b68a..170576e20e 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material @@ -1,25 +1,15 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.06784161180257797, - 0.2073090672492981, - 0.29570457339286806, - 1.0 - ] - }, - "clearCoat": { - "enable": true - }, - "normal": { - "textureMap": "TestData/Textures/cc0/Tiles009_1K_Normal.jpg" - }, - "roughness": { - "factor": 0.0 - } + "propertyValues": { + "baseColor.color": [ + 0.06784161180257797, + 0.2073090672492981, + 0.29570457339286804, + 1.0 + ], + "clearCoat.enable": true, + "normal.textureMap": "TestData/Textures/cc0/Tiles009_1K_Normal.jpg", + "roughness.factor": 0.0 } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material index 6403bc5c14..f69a316c59 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material @@ -1,12 +1,9 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "010_OcclusionBase.material", "materialTypeVersion": 3, - "properties": { - "occlusion": { - "specularFactor": 2.0, - "specularTextureMap": "TestData/Textures/cc0/Tiles009_1K_Displacement.jpg" - } + "parentMaterial": "010_OcclusionBase.material", + "propertyValues": { + "occlusion.specularFactor": 2.0, + "occlusion.specularTextureMap": "TestData/Textures/cc0/Tiles009_1K_Displacement.jpg" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material index dc42c0d6b5..7c640b573d 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material @@ -1,21 +1,16 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "Textures/Default/default_basecolor.tif" - }, - "emissive": { - "color": [ - 0.003936827648431063, - 1.0, - 0.0, - 1.0 - ], - "enable": true, - "intensity": 3.0, - "textureMap": "TestData/Textures/checker8x8_gray_512.png" - } + "propertyValues": { + "baseColor.textureMap": "Textures/Default/default_basecolor.tif", + "emissive.color": [ + 0.003936827648431063, + 1.0, + 0.0, + 1.0 + ], + "emissive.enable": true, + "emissive.intensity": 3.0, + "emissive.textureMap": "TestData/Textures/checker8x8_gray_512.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material index fee4a30f77..35f91d0eb1 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material @@ -1,16 +1,11 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png" - }, - "parallax": { - "algorithm": "POM", - "factor": 0.02500000037252903, - "quality": "High", - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_disp.png" - } + "propertyValues": { + "baseColor.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png", + "parallax.algorithm": "POM", + "parallax.factor": 0.02500000037252903, + "parallax.quality": "High", + "parallax.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_disp.png" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material index d69b75285e..bf6907fbd5 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material @@ -1,28 +1,18 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png" - }, - "opacity": { - "alphaSource": "Split", - "mode": "Cutout", - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "parallax": { - "factor": 0.10000000149011612, - "quality": "High", - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_disp.png" - }, - "uv": { - "center": [ - 0.0, - 0.0 - ], - "scale": 0.5 - } + "propertyValues": { + "baseColor.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png", + "opacity.alphaSource": "Split", + "opacity.mode": "Cutout", + "opacity.textureMap": "TestData/Textures/checker8x8_512.png", + "parallax.factor": 0.10000000149011612, + "parallax.quality": "High", + "parallax.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_disp.png", + "uv.center": [ + 0.0, + 0.0 + ], + "uv.scale": 0.5 } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material index a1da93acbb..c266799f26 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material @@ -1,17 +1,10 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "materialTypeVersion": 3, - "properties": { - "metallic": { - "factor": 1.0 - }, - "normal": { - "flipY": true, - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png" - }, - "roughness": { - "factor": 0.13131310045719148 - } + "propertyValues": { + "metallic.factor": 1.0, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png", + "roughness.factor": 0.13131310045719147 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material index 07018e9140..a2d33da506 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material @@ -1,20 +1,11 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "materialTypeVersion": 3, - "properties": { - "general": { - "applySpecularAA": true - }, - "metallic": { - "factor": 1.0 - }, - "normal": { - "flipY": true, - "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png" - }, - "roughness": { - "factor": 0.13131310045719148 - } + "propertyValues": { + "general.applySpecularAA": true, + "metallic.factor": 1.0, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_normal.png", + "roughness.factor": 0.13131310045719147 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material index e02a8b5fc2..2f60fcc9b2 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material @@ -1,27 +1,17 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 1.0, - 0.34190890192985537, - 0.0009155413135886192, - 1.0 - ], - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "clearCoat": { - "enable": true, - "influenceMap": "TestData/Textures/checker8x8_512.png" - }, - "metallic": { - "factor": 0.5 - }, - "roughness": { - "factor": 0.5 - } + "propertyValues": { + "baseColor.color": [ + 1.0, + 0.34190890192985535, + 0.0009155413135886192, + 1.0 + ], + "baseColor.textureMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.enable": true, + "clearCoat.influenceMap": "TestData/Textures/checker8x8_512.png", + "metallic.factor": 0.5, + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material index 56d8515305..0fb6e22664 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material @@ -1,31 +1,21 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 1.0, - 0.34190890192985537, - 0.0009155413135886192, - 1.0 - ], - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "clearCoat": { - "enable": true, - "influenceMap": "TestData/Textures/checker8x8_512.png", - "normalMap": "TestData/Textures/test_dome_normal.tiff", - "roughnessMap": "TestData/Textures/checker8x8_512.png", - "useInfluenceMap": false, - "useRoughnessMap": false - }, - "metallic": { - "factor": 0.5 - }, - "roughness": { - "factor": 0.5 - } + "propertyValues": { + "baseColor.color": [ + 1.0, + 0.34190890192985535, + 0.0009155413135886192, + 1.0 + ], + "baseColor.textureMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.enable": true, + "clearCoat.influenceMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.normalMap": "TestData/Textures/test_dome_normal.tiff", + "clearCoat.roughnessMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.useInfluenceMap": false, + "clearCoat.useRoughnessMap": false, + "metallic.factor": 0.5, + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material index e7575d8bd6..f76ef83485 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material @@ -1,35 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 1.0, - 0.34190890192985537, - 0.0009155413135886192, - 1.0 - ], - "textureMap": "TestData/Textures/checker8x8_512.png", - "textureMapUv": "Unwrapped" - }, - "clearCoat": { - "enable": true, - "influenceMap": "TestData/Textures/checker8x8_512.png", - "influenceMapUv": "Unwrapped", - "normalMap": "TestData/Textures/test_dome_normal.tiff", - "normalMapUv": "Unwrapped", - "roughnessMap": "TestData/Textures/checker8x8_512.png", - "roughnessMapUv": "Unwrapped", - "useInfluenceMap": false, - "useRoughnessMap": false - }, - "metallic": { - "factor": 0.5 - }, - "roughness": { - "factor": 0.5 - } + "propertyValues": { + "baseColor.color": [ + 1.0, + 0.34190890192985535, + 0.0009155413135886192, + 1.0 + ], + "baseColor.textureMap": "TestData/Textures/checker8x8_512.png", + "baseColor.textureMapUv": "Unwrapped", + "clearCoat.enable": true, + "clearCoat.influenceMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.influenceMapUv": "Unwrapped", + "clearCoat.normalMap": "TestData/Textures/test_dome_normal.tiff", + "clearCoat.normalMapUv": "Unwrapped", + "clearCoat.roughnessMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.roughnessMapUv": "Unwrapped", + "clearCoat.useInfluenceMap": false, + "clearCoat.useRoughnessMap": false, + "metallic.factor": 0.5, + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material index 3ccbfeacc1..62e15fe2c5 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material @@ -1,30 +1,20 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 1.0, - 0.34190890192985537, - 0.0009155413135886192, - 1.0 - ], - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "clearCoat": { - "enable": true, - "influenceMap": "TestData/Textures/checker8x8_512.png", - "roughness": 0.5050504803657532, - "roughnessMap": "TestData/Textures/checker8x8_512.png", - "useInfluenceMap": false - }, - "metallic": { - "factor": 0.5 - }, - "roughness": { - "factor": 0.5 - } + "propertyValues": { + "baseColor.color": [ + 1.0, + 0.34190890192985535, + 0.0009155413135886192, + 1.0 + ], + "baseColor.textureMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.enable": true, + "clearCoat.influenceMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.roughness": 0.5050504803657532, + "clearCoat.roughnessMap": "TestData/Textures/checker8x8_512.png", + "clearCoat.useInfluenceMap": false, + "metallic.factor": 0.5, + "roughness.factor": 0.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material index fb3621f056..3f189f5ff5 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material @@ -1,20 +1,16 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "subsurfaceScattering": { - "enableSubsurfaceScattering": true, - "influenceMap": "TestData/Textures/checker8x8_512.png", - "scatterColor": [ - 1.0, - 0.20000000298023225, - 0.07058823853731156, - 1.0 - ], - "scatterDistance": 40.0, - "subsurfaceScatterFactor": 1.0 - } + "propertyValues": { + "subsurfaceScattering.enableSubsurfaceScattering": true, + "subsurfaceScattering.influenceMap": "TestData/Textures/checker8x8_512.png", + "subsurfaceScattering.scatterColor": [ + 1.0, + 0.20000000298023224, + 0.07058823853731155, + 1.0 + ], + "subsurfaceScattering.scatterDistance": 40.0, + "subsurfaceScattering.subsurfaceScatterFactor": 1.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material index eff175be77..5a2373d5eb 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material @@ -1,15 +1,11 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "subsurfaceScattering": { - "enableSubsurfaceScattering": true, - "scatterDistance": 64.6464614868164, - "subsurfaceScatterFactor": 1.0, - "thicknessMap": "TestData/Textures/checker8x8_512.png", - "transmissionMode": "ThickObject" - } + "propertyValues": { + "subsurfaceScattering.enableSubsurfaceScattering": true, + "subsurfaceScattering.scatterDistance": 64.6464614868164, + "subsurfaceScattering.subsurfaceScatterFactor": 1.0, + "subsurfaceScattering.thicknessMap": "TestData/Textures/checker8x8_512.png", + "subsurfaceScattering.transmissionMode": "ThickObject" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission_Thin.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission_Thin.material index ee9bb1f4a5..c8a1401d17 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission_Thin.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission_Thin.material @@ -1,29 +1,21 @@ { - "description": "", - "parentMaterial": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "materialTypeVersion": 4, - "properties": { - "baseColor": { - "color": [ - 0.027664607390761375, - 0.1926604062318802, - 0.013916227966547012, - 1.0 - ] - }, - "general": { - "doubleSided": true - }, - "subsurfaceScattering": { - "thickness": 0.20000000298023224, - "transmissionMode": "ThinObject", - "transmissionTint": [ - 0.009140154346823692, - 0.19806210696697235, - 0.01095597818493843, - 1.0 - ] - } + "propertyValues": { + "baseColor.color": [ + 0.027664607390761375, + 0.1926604062318802, + 0.013916227966547012, + 1.0 + ], + "general.doubleSided": true, + "subsurfaceScattering.thickness": 0.20000000298023224, + "subsurfaceScattering.transmissionMode": "ThinObject", + "subsurfaceScattering.transmissionTint": [ + 0.009140154346823692, + 0.19806210696697235, + 0.01095597818493843, + 1.0 + ] } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material index d88c1f151f..8e68176843 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "occlusion": { - "diffuseTextureMap": "TestData/Objects/cube/cube_diff.tif" - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "occlusion.diffuseTextureMap": "TestData/Objects/cube/cube_diff.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material index 89bd1005a5..565f3bf8e0 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "TestData/Objects/cube/cube_diff.tif" - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "baseColor.textureMap": "TestData/Objects/cube/cube_diff.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material index 564de16cc2..a053737973 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material @@ -1,22 +1,17 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.0, - 0.0, - 0.0, - 1.0 - ] - }, - "emissive": { - "enable": true, - "intensity": 2.0, - "textureMap": "TestData/Objects/cube/cube_diff.tif", - "useTexture": true - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "baseColor.color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "emissive.enable": true, + "emissive.intensity": 2.0, + "emissive.textureMap": "TestData/Objects/cube/cube_diff.tif", + "emissive.useTexture": true } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material index 0eff6198dd..17a13d79cf 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material @@ -1,15 +1,10 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "metallic": { - "factor": 1.0, - "textureMap": "TestData/Objects/cube/cube_diff.tif" - }, - "roughness": { - "factor": 0.0 - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "metallic.factor": 1.0, + "metallic.textureMap": "TestData/Objects/cube/cube_diff.tif", + "roughness.factor": 0.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material index e50c669114..bbdc3c62ec 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material @@ -1,11 +1,8 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "normal": { - "textureMap": "TestData/Objects/cube/cube_diff.tif" - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "normal.textureMap": "TestData/Objects/cube/cube_diff.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material index 0b3d678bdd..b0e6a0a498 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material @@ -1,20 +1,14 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.15000000596046449, - "flipY": true, - "textureMap": "TestData/Textures/test_dome_normal.tiff" - }, - "uv": { - "center": [ - 0.5, - 0.5 - ], - "rotateDegrees": 20.0 - } + "propertyValues": { + "normal.factor": 0.15000000596046448, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/test_dome_normal.tiff", + "uv.center": [ + 0.5, + 0.5 + ], + "uv.rotateDegrees": 20.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material index 4a7ade8b30..0e72deebbc 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material @@ -1,20 +1,14 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.15000000596046449, - "flipY": true, - "textureMap": "TestData/Textures/test_dome_normal.tiff" - }, - "uv": { - "center": [ - 0.5, - 0.5 - ], - "rotateDegrees": 90.0 - } + "propertyValues": { + "normal.factor": 0.15000000596046448, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/test_dome_normal.tiff", + "uv.center": [ + 0.5, + 0.5 + ], + "uv.rotateDegrees": 90.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material index c0477ac5cf..7d87e24938 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material @@ -1,20 +1,14 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.15000000596046449, - "flipY": true, - "textureMap": "TestData/Textures/test_dome_normal.tiff" - }, - "uv": { - "center": [ - 0.5, - 0.5 - ], - "tileU": 2.0 - } + "propertyValues": { + "normal.factor": 0.15000000596046448, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/test_dome_normal.tiff", + "uv.center": [ + 0.5, + 0.5 + ], + "uv.tileU": 2.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material index b088a0c090..a589741097 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material @@ -1,20 +1,14 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.15000000596046449, - "flipY": true, - "textureMap": "TestData/Textures/test_dome_normal.tiff" - }, - "uv": { - "center": [ - 0.5, - 0.5 - ], - "tileV": 2.0 - } + "propertyValues": { + "normal.factor": 0.15000000596046448, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/test_dome_normal.tiff", + "uv.center": [ + 0.5, + 0.5 + ], + "uv.tileV": 2.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material index c7c3fac87f..6d687bfc45 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material @@ -1,20 +1,14 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.15000000596046449, - "flipY": true, - "textureMap": "TestData/Textures/test_dome_normal.tiff" - }, - "uv": { - "center": [ - 0.5, - 0.5 - ], - "scale": 3.0 - } + "propertyValues": { + "normal.factor": 0.15000000596046448, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/test_dome_normal.tiff", + "uv.center": [ + 0.5, + 0.5 + ], + "uv.scale": 3.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material index 849e926031..2e916fbb33 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material @@ -1,25 +1,19 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "normal": { - "factor": 0.15000000596046449, - "flipY": true, - "textureMap": "TestData/Textures/test_dome_normal.tiff" - }, - "uv": { - "center": [ - 0.25, - 0.5 - ], - "offsetU": 0.3737373948097229, - "offsetV": -0.4545454978942871, - "rotateDegrees": 110.0, - "scale": 2.0, - "tileU": 0.5, - "tileV": 1.5 - } + "propertyValues": { + "normal.factor": 0.15000000596046448, + "normal.flipY": true, + "normal.textureMap": "TestData/Textures/test_dome_normal.tiff", + "uv.center": [ + 0.25, + 0.5 + ], + "uv.offsetU": 0.3737373948097229, + "uv.offsetV": -0.4545454978942871, + "uv.rotateDegrees": 110.0, + "uv.scale": 2.0, + "uv.tileU": 0.5, + "uv.tileV": 1.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material index b203ec5318..ec056b8459 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material @@ -1,14 +1,11 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "opacity": { - "alphaSource": "Split", - "factor": 0.9, - "mode": "Cutout", - "textureMap": "TestData/Objects/cube/cube_diff.tif" - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "opacity.alphaSource": "Split", + "opacity.factor": 0.8999999761581421, + "opacity.mode": "Cutout", + "opacity.textureMap": "TestData/Objects/cube/cube_diff.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material index ad2e27063b..2e0eadb40f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material @@ -1,36 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "TestData/Objects/cube/cube_diff.tif" - }, - "metallic": { - "factor": 1.0, - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "parallax": { - "algorithm": "POM", - "factor": 0.10000000149011612, - "quality": "High", - "textureMap": "TestData/Objects/cube/cube_diff.tif" - }, - "roughness": { - "textureMap": "TestData/Textures/checker8x8_flip_512.png" - }, - "uv": { - "center": [ - 0.25, - 0.5 - ], - "offsetU": -0.6767677068710327, - "offsetV": 0.19191919267177583, - "rotateDegrees": 63.6363639831543, - "scale": 0.800000011920929, - "tileU": 0.699999988079071, - "tileV": 1.5 - } + "parentMaterial": "TestData/Materials/StandardPbrTestCases/UvTilingBase.material", + "propertyValues": { + "baseColor.textureMap": "TestData/Objects/cube/cube_diff.tif", + "metallic.factor": 1.0, + "metallic.textureMap": "TestData/Textures/checker8x8_512.png", + "parallax.algorithm": "POM", + "parallax.factor": 0.10000000149011612, + "parallax.quality": "High", + "parallax.textureMap": "TestData/Objects/cube/cube_diff.tif", + "roughness.textureMap": "TestData/Textures/checker8x8_flip_512.png", + "uv.center": [ + 0.25, + 0.5 + ], + "uv.offsetU": -0.6767677068710327, + "uv.offsetV": 0.19191919267177582, + "uv.rotateDegrees": 63.6363639831543, + "uv.scale": 0.800000011920929, + "uv.tileU": 0.699999988079071, + "uv.tileV": 1.5 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material index 75646e5191..9e368f8be0 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material @@ -1,36 +1,25 @@ { - "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "TestData/Objects/cube/cube_diff.tif" - }, - "metallic": { - "factor": 1.0, - "textureMap": "TestData/Textures/checker8x8_512.png" - }, - "parallax": { - "algorithm": "POM", - "factor": 0.05000000074505806, - "quality": "High", - "textureMap": "TestData/Objects/cube/cube_diff.tif" - }, - "roughness": { - "textureMap": "TestData/Textures/checker8x8_flip_512.png" - }, - "uv": { - "center": [ - 0.5, - 0.25 - ], - "offsetU": 1.0, - "offsetV": -1.0, - "rotateDegrees": 90.0, - "scale": 1.2000000476837159, - "tileU": 0.699999988079071, - "tileV": 1.7999999523162842 - } + "parentMaterial": "TestData/Materials/StandardPbrTestCases/UvTilingBase.material", + "propertyValues": { + "baseColor.textureMap": "TestData/Objects/cube/cube_diff.tif", + "metallic.factor": 1.0, + "metallic.textureMap": "TestData/Textures/checker8x8_512.png", + "parallax.algorithm": "POM", + "parallax.factor": 0.05000000074505806, + "parallax.quality": "High", + "parallax.textureMap": "TestData/Objects/cube/cube_diff.tif", + "roughness.textureMap": "TestData/Textures/checker8x8_flip_512.png", + "uv.center": [ + 0.5, + 0.25 + ], + "uv.offsetU": 1.0, + "uv.offsetV": -1.0, + "uv.rotateDegrees": 90.0, + "uv.scale": 1.2000000476837158, + "uv.tileU": 0.699999988079071, + "uv.tileV": 1.7999999523162842 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material index 49ff9555f1..35a7dc6ad4 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material @@ -1,14 +1,9 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "metallic": { - "factor": 1.0 - }, - "roughness": { - "textureMap": "TestData/Objects/cube/cube_diff.tif" - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "metallic.factor": 1.0, + "roughness.textureMap": "TestData/Objects/cube/cube_diff.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material index a750e30d80..43b0aacde4 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material @@ -1,23 +1,16 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "color": [ - 0.11546501517295838, - 0.11546501517295838, - 0.11546501517295838, - 1.0 - ] - }, - "roughness": { - "factor": 0.0 - }, - "specularF0": { - "factor": 1.0, - "textureMap": "TestData/Objects/cube/cube_diff.tif" - } + "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", + "propertyValues": { + "baseColor.color": [ + 0.11546501517295837, + 0.11546501517295837, + 0.11546501517295837, + 1.0 + ], + "roughness.factor": 0.0, + "specularF0.factor": 1.0, + "specularF0.textureMap": "TestData/Objects/cube/cube_diff.tif" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material index 30959fc972..a299d17479 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material @@ -1,31 +1,19 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", - "textureMapUv": "Unwrapped" - }, - "detailUV": { - "center": [ - 0.0, - 0.0 - ] - }, - "metallic": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", - "textureMapUv": "Unwrapped" - }, - "normal": { - "flipY": true, - "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", - "textureMapUv": "Unwrapped" - }, - "roughness": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", - "textureMapUv": "Unwrapped" - } + "propertyValues": { + "baseColor.textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", + "baseColor.textureMapUv": "Unwrapped", + "detailUV.center": [ + 0.0, + 0.0 + ], + "metallic.textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", + "metallic.textureMapUv": "Unwrapped", + "normal.flipY": true, + "normal.textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", + "normal.textureMapUv": "Unwrapped", + "roughness.textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", + "roughness.textureMapUv": "Unwrapped" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material index 2cb14b490e..4f1247d7c0 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material @@ -1,42 +1,28 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", - "textureMapUv": "Unwrapped" - }, - "detailLayerGroup": { - "baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", - "blendDetailMask": "Objects/Hermanubis/Hermanubis_ao.tif", - "blendDetailMaskUv": "Unwrapped", - "enableBaseColor": true, - "enableDetailLayer": true, - "enableNormals": true, - "normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", - "normalDetailStrength": 1.5 - }, - "detailUV": { - "center": [ - 0.0, - 0.0 - ], - "scale": 10.0 - }, - "metallic": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", - "textureMapUv": "Unwrapped" - }, - "normal": { - "flipY": true, - "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", - "textureMapUv": "Unwrapped" - }, - "roughness": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", - "textureMapUv": "Unwrapped" - } + "propertyValues": { + "baseColor.textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", + "baseColor.textureMapUv": "Unwrapped", + "detailLayerGroup.baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", + "detailLayerGroup.blendDetailMask": "Objects/Hermanubis/Hermanubis_ao.tif", + "detailLayerGroup.blendDetailMaskUv": "Unwrapped", + "detailLayerGroup.enableBaseColor": true, + "detailLayerGroup.enableDetailLayer": true, + "detailLayerGroup.enableNormals": true, + "detailLayerGroup.normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", + "detailLayerGroup.normalDetailStrength": 1.5, + "detailUV.center": [ + 0.0, + 0.0 + ], + "detailUV.scale": 10.0, + "metallic.textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", + "metallic.textureMapUv": "Unwrapped", + "normal.flipY": true, + "normal.textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", + "normal.textureMapUv": "Unwrapped", + "roughness.textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", + "roughness.textureMapUv": "Unwrapped" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material index 826ae2d737..ff3e4d63b8 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material @@ -1,17 +1,12 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", "materialTypeVersion": 3, - "properties": { - "detailLayerGroup": { - "baseColorDetailBlend": 0.800000011920929, - "baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", - "enableBaseColor": true, - "enableDetailLayer": true - }, - "detailUV": { - "scale": 20.0 - } + "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", + "propertyValues": { + "detailLayerGroup.baseColorDetailBlend": 0.800000011920929, + "detailLayerGroup.baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", + "detailLayerGroup.enableBaseColor": true, + "detailLayerGroup.enableDetailLayer": true, + "detailUV.scale": 20.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material index 1c2214a031..09cc883efd 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material @@ -1,13 +1,10 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material", "materialTypeVersion": 3, - "properties": { - "detailLayerGroup": { - "baseColorDetailBlend": 1.0, - "blendDetailMask": "TestData/Textures/checker8x8_flip_512.png", - "blendDetailMaskUv": "Unwrapped" - } + "parentMaterial": "TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material", + "propertyValues": { + "detailLayerGroup.baseColorDetailBlend": 1.0, + "detailLayerGroup.blendDetailMask": "TestData/Textures/checker8x8_flip_512.png", + "detailLayerGroup.blendDetailMaskUv": "Unwrapped" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material index 9a80cfaaa0..81de9e0bce 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material @@ -1,18 +1,13 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", "materialTypeVersion": 3, - "properties": { - "detailLayerGroup": { - "enableDetailLayer": true, - "enableNormals": true, - "normalDetailFlipY": true, - "normalDetailMap": "TestData/Textures/test_dome_normal.tiff", - "normalDetailStrength": 0.30000001192092898 - }, - "detailUV": { - "scale": 40.0 - } + "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", + "propertyValues": { + "detailLayerGroup.enableDetailLayer": true, + "detailLayerGroup.enableNormals": true, + "detailLayerGroup.normalDetailFlipY": true, + "detailLayerGroup.normalDetailMap": "TestData/Textures/test_dome_normal.tiff", + "detailLayerGroup.normalDetailStrength": 0.30000001192092896, + "detailUV.scale": 40.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material index 0ee81633ae..477da12807 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material @@ -1,12 +1,9 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material", "materialTypeVersion": 3, - "properties": { - "detailLayerGroup": { - "blendDetailMask": "TestData/Textures/checker8x8_gray_512.png", - "blendDetailMaskUv": "Unwrapped" - } + "parentMaterial": "TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material", + "propertyValues": { + "detailLayerGroup.blendDetailMask": "TestData/Textures/checker8x8_gray_512.png", + "detailLayerGroup.blendDetailMaskUv": "Unwrapped" } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material index b2747ead21..d9c7a42c41 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material @@ -1,41 +1,27 @@ { - "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "baseColor": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", - "textureMapUv": "Unwrapped" - }, - "detailLayerGroup": { - "baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", - "blendDetailMask": "TestData/Textures/checker2x2_128.png", - "enableBaseColor": true, - "enableDetailLayer": true, - "enableNormals": true, - "normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", - "normalDetailStrength": 1.5 - }, - "detailUV": { - "center": [ - 0.0, - 0.0 - ], - "scale": 10.0 - }, - "metallic": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", - "textureMapUv": "Unwrapped" - }, - "normal": { - "flipY": true, - "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", - "textureMapUv": "Unwrapped" - }, - "roughness": { - "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", - "textureMapUv": "Unwrapped" - } + "propertyValues": { + "baseColor.textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", + "baseColor.textureMapUv": "Unwrapped", + "detailLayerGroup.baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", + "detailLayerGroup.blendDetailMask": "TestData/Textures/checker2x2_128.png", + "detailLayerGroup.enableBaseColor": true, + "detailLayerGroup.enableDetailLayer": true, + "detailLayerGroup.enableNormals": true, + "detailLayerGroup.normalDetailMap": "TestData/Textures/cc0/Concrete019_1K_Normal.jpg", + "detailLayerGroup.normalDetailStrength": 1.5, + "detailUV.center": [ + 0.0, + 0.0 + ], + "detailUV.scale": 10.0, + "metallic.textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", + "metallic.textureMapUv": "Unwrapped", + "normal.flipY": true, + "normal.textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", + "normal.textureMapUv": "Unwrapped", + "roughness.textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", + "roughness.textureMapUv": "Unwrapped" } } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material index be607db929..6927d51ecf 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material @@ -1,20 +1,16 @@ { - "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "uv": { - "center": [ - 0.5, - 0.5 - ], - "offsetU": 0.10000000149011612, - "offsetV": 0.15000000596046449, - "rotateDegrees": 38.181819915771487, - "scale": 1.5, - "tileU": 0.5, - "tileV": 2.0 - } + "propertyValues": { + "uv.center": [ + 0.5, + 0.5 + ], + "uv.offsetU": 0.10000000149011612, + "uv.offsetV": 0.15000000596046448, + "uv.rotateDegrees": 38.181819915771484, + "uv.scale": 1.5, + "uv.tileU": 0.5, + "uv.tileV": 2.0 } -} +} \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material b/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material index 8a2f45260a..669efe2339 100644 --- a/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material +++ b/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material @@ -1,18 +1,12 @@ { - "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", - "parentMaterial": "", "materialTypeVersion": 3, - "properties": { - "blend": { - "blendSource": "BlendMaskVertexColors", - "debugDrawMode": "FinalBlendWeights", - "enableLayer2": true, - "enableLayer3": true, - "textureMap": "" - }, - "parallax": { - "enable": false - } + "propertyValues": { + "blend.blendSource": "BlendMaskVertexColors", + "blend.debugDrawMode": "FinalBlendWeights", + "blend.enableLayer2": true, + "blend.enableLayer3": true, + "blend.textureMap": "", + "parallax.enable": false } -} +} \ No newline at end of file From ddab03d6785e66d425fada619dad1d2f9b95fe78 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 8 Feb 2022 11:18:17 -0800 Subject: [PATCH 11/24] Reponse to code review feedback. The main change is making GetPropertyValues return by const ref. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Include/Atom/RPI.Edit/Material/MaterialSourceData.h | 2 +- .../Code/Source/RPI.Edit/Material/MaterialSourceData.cpp | 6 +++--- .../RPI/Code/Tests/Material/MaterialSourceDataTests.cpp | 8 ++++---- .../Code/Source/Document/MaterialDocument.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h index b8c613fd12..8819cbc78b 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h @@ -75,7 +75,7 @@ namespace AZ void SetPropertyValue(const Name& propertyId, const MaterialPropertyValue& value); const MaterialPropertyValue& GetPropertyValue(const Name& propertyId) const; - PropertyValueMap GetPropertyValues() const; + const PropertyValueMap& GetPropertyValues() const; bool HasPropertyValue(const Name& propertyId) const; void RemovePropertyValue(const Name& propertyId); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index e5092b5480..fe6ec415a3 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -100,7 +100,7 @@ namespace AZ m_propertyValues.erase(propertyId); } - MaterialSourceData::PropertyValueMap MaterialSourceData::GetPropertyValues() const + const MaterialSourceData::PropertyValueMap& MaterialSourceData::GetPropertyValues() const { return m_propertyValues; } @@ -112,9 +112,9 @@ namespace AZ void MaterialSourceData::ConvertToNewDataFormat() { - for (auto& [groupName, propertyList] : m_propertiesOld) + for (const auto& [groupName, propertyList] : m_propertiesOld) { - for (auto& [propertyName, propertyValue] : propertyList) + for (const auto& [propertyName, propertyValue] : propertyList) { SetPropertyValue(MaterialPropertyId{groupName, propertyName}, propertyValue); } diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index 362d7d8b6d..7676772389 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -357,7 +357,7 @@ namespace UnitTest return fixupType(a.GetTypeId()) == fixupType(targetTypeId) && fixupType(b.GetTypeId()) == fixupType(targetTypeId); } - void CheckEqual(MaterialSourceData& a, MaterialSourceData& b) + void CheckEqual(const MaterialSourceData& a, const MaterialSourceData& b) { EXPECT_STREQ(a.m_materialType.c_str(), b.m_materialType.c_str()); EXPECT_STREQ(a.m_description.c_str(), b.m_description.c_str()); @@ -1091,15 +1091,15 @@ namespace UnitTest MaterialSourceData sourceDataLevel3 = MaterialUtils::LoadMaterialSourceData("@exefolder@/Temp/m3.material").TakeValue(); auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); - EXPECT_TRUE(materialAssetLevel1.IsSuccess()); + ASSERT_TRUE(materialAssetLevel1.IsSuccess()); EXPECT_TRUE(materialAssetLevel1.GetValue()->WasPreFinalized()); auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); - EXPECT_TRUE(materialAssetLevel2.IsSuccess()); + ASSERT_TRUE(materialAssetLevel2.IsSuccess()); EXPECT_TRUE(materialAssetLevel2.GetValue()->WasPreFinalized()); auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAssetFromSourceData(Uuid::CreateRandom()); - EXPECT_TRUE(materialAssetLevel3.IsSuccess()); + ASSERT_TRUE(materialAssetLevel3.IsSuccess()); EXPECT_TRUE(materialAssetLevel3.GetValue()->WasPreFinalized()); auto layout = materialAssetLevel1.GetValue()->GetMaterialPropertiesLayout(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp index 6f576c9e02..8db8ee1eeb 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp @@ -677,7 +677,7 @@ namespace MaterialEditor if (!loadResult) { AZ_Error("MaterialDocument", false, "Material source data could not be loaded: '%s'.", m_absolutePath.c_str()); - return OpenFailed(); + return false; } m_materialSourceData = loadResult.TakeValue(); From 48313cd6dee676e90775b744e0625e54837a9b34 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Tue, 8 Feb 2022 12:40:10 -0800 Subject: [PATCH 12/24] Remove const reference to prevent issues in nightly builds. (#7491) Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- .../AzToolsFramework/Prefab/PrefabFocusHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp index 62c6518d4c..800464a336 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp @@ -292,7 +292,7 @@ namespace AzToolsFramework::Prefab return false; } - const InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); + InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); if (!instance.has_value()) { return false; @@ -308,7 +308,7 @@ namespace AzToolsFramework::Prefab return false; } - InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); + InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); while (instance.has_value()) { if (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath) From c46c55803860cec45f2bb197c159116e90604ec6 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 8 Feb 2022 15:00:19 -0600 Subject: [PATCH 13/24] Switched Gradient Surface benchmarks to use actual surface components. (#7468) * Switched Gradient Surface benchmarks to use actual surface components. The gradient unit tests and benchmarks were previously using a mock surface data system, which led to misleading benchmark results. Now, the actual SurfaceData system gets constructed, and the tests use a mock provider, but the benchmarks use actual shape providers for more realistic benchmarking. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed unit tests to have better query ranges. Half of each previous range was querying outside the surface provider's data. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- Gems/FastNoise/Code/Tests/FastNoiseTest.cpp | 2 +- .../Code/Tests/GradientSignalBenchmarks.cpp | 9 --- .../Tests/GradientSignalGetValuesTests.cpp | 43 +++++----- .../Tests/GradientSignalReferencesTests.cpp | 63 +++++++++------ .../Code/Tests/GradientSignalSurfaceTests.cpp | 7 +- .../Code/Tests/GradientSignalTestFixtures.cpp | 80 +++++++++++-------- .../Code/Tests/GradientSignalTestFixtures.h | 10 +-- .../Code/Tests/GradientSignalTestHelpers.cpp | 6 +- .../Code/Tests/GradientSignalTestHelpers.h | 2 +- .../Code/Tests/GradientSignalTestMocks.h | 61 ++++++++++++++ .../Components/SurfaceDataColliderComponent.h | 0 .../Components/SurfaceDataShapeComponent.h | 0 .../Components}/SurfaceDataSystemComponent.h | 4 + .../SurfaceData/SurfaceDataSystemRequestBus.h | 4 + .../SurfaceData/Tests/SurfaceDataTestMocks.h | 10 +++ .../SurfaceDataColliderComponent.cpp | 2 +- .../Components/SurfaceDataShapeComponent.cpp | 2 +- .../EditorSurfaceDataColliderComponent.h | 2 +- .../Editor/EditorSurfaceDataShapeComponent.h | 2 +- .../Code/Source/SurfaceDataEditorModule.cpp | 2 +- .../Code/Source/SurfaceDataModule.cpp | 6 +- .../Source/SurfaceDataSystemComponent.cpp | 30 ++++++- .../Code/Source/SurfaceDataTypes.cpp | 4 +- .../Code/Tests/SurfaceDataBenchmarks.cpp | 4 +- .../SurfaceDataColliderComponentTest.cpp | 2 +- .../Code/Tests/SurfaceDataTest.cpp | 2 +- .../Code/Tests/SurfaceDataTestFixtures.cpp | 6 +- Gems/SurfaceData/Code/surfacedata_files.cmake | 6 +- Gems/Vegetation/Code/Tests/VegetationMocks.h | 10 +++ 29 files changed, 252 insertions(+), 129 deletions(-) rename Gems/SurfaceData/Code/{Source => Include/SurfaceData}/Components/SurfaceDataColliderComponent.h (100%) rename Gems/SurfaceData/Code/{Source => Include/SurfaceData}/Components/SurfaceDataShapeComponent.h (100%) rename Gems/SurfaceData/Code/{Source => Include/SurfaceData/Components}/SurfaceDataSystemComponent.h (95%) diff --git a/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp b/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp index 1ac5e8ddca..e82409d599 100644 --- a/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp +++ b/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp @@ -102,7 +102,7 @@ TEST_F(FastNoiseTest, FastNoise_VerifyGetValueAndGetValuesMatch) noiseEntity->Activate(); // Create a gradient sampler and run through a series of points to see if they match expectations. - UnitTest::GradientSignalTestHelpers::CompareGetValueAndGetValues(noiseEntity->GetId(), shapeHalfBounds); + UnitTest::GradientSignalTestHelpers::CompareGetValueAndGetValues(noiseEntity->GetId(), -shapeHalfBounds, shapeHalfBounds); } // This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems. diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp index 6ffb4a31c4..d8194dcc9a 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp @@ -140,27 +140,18 @@ namespace UnitTest BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceAltitudeGradient)(benchmark::State& state) { - auto mockSurfaceDataSystem = - CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); - auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds); GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceMaskGradient)(benchmark::State& state) { - auto mockSurfaceDataSystem = - CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); - auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds); GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceSlopeGradient)(benchmark::State& state) { - auto mockSurfaceDataSystem = - CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); - auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds); GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp index f0ad53ee64..e217dbb103 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp @@ -24,31 +24,33 @@ namespace UnitTest TEST_F(GradientSignalGetValuesTestsFixture, ImageGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestImageGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, PerlinGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestPerlinGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, RandomGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestRandomGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, ConstantGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestConstantGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, ShapeAreaFalloffGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + + // Use a query range larger than our shape to ensure that we're getting falloff values within our query bounds. + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), -TestShapeHalfBounds, TestShapeHalfBounds * 3.0f); } TEST_F(GradientSignalGetValuesTestsFixture, DitherGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -56,21 +58,21 @@ namespace UnitTest auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, InvertGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestInvertGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, LevelsGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, MixedGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -78,62 +80,53 @@ namespace UnitTest auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds); auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, PosterizeGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, ReferenceGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, SmoothStepGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, ThresholdGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId()); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, SurfaceAltitudeGradientComponent_VerifyGetValueAndGetValuesMatch) { - auto mockSurfaceDataSystem = - CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); - auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, SurfaceMaskGradientComponent_VerifyGetValueAndGetValuesMatch) { - auto mockSurfaceDataSystem = - CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); - auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } TEST_F(GradientSignalGetValuesTestsFixture, SurfaceSlopeGradientComponent_VerifyGetValueAndGetValuesMatch) { - auto mockSurfaceDataSystem = - CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); - auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds); - GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), 0.0f, TestShapeHalfBounds * 2.0f); } } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp index 6f90c5022f..2e602e8c80 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp @@ -65,7 +65,11 @@ namespace UnitTest float slopeMin, float slopeMax, GradientSignal::SurfaceSlopeGradientConfig::RampType rampType, float falloffMidpoint, float falloffRange, float falloffStrength) { - MockSurfaceDataSystem mockSurfaceDataSystem; + auto surfaceEntity = CreateEntity(); + auto mockSurface = surfaceEntity->CreateComponent(); + mockSurface->m_bounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(aznumeric_cast(dataSize))); + mockSurface->m_tags.emplace_back("test_mask"); + AzFramework::SurfaceData::SurfacePoint point; // Fill our mock surface with the correct normal value for each point based on our test angle set. @@ -75,9 +79,10 @@ namespace UnitTest { float angle = AZ::DegToRad(inputAngles[(y * dataSize) + x]); point.m_normal = AZ::Vector3(sinf(angle), 0.0f, cosf(angle)); - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = { { point } }; + mockSurface->m_surfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = { { point } }; } } + ActivateEntity(surfaceEntity.get()); GradientSignal::SurfaceSlopeGradientConfig config; config.m_slopeMin = slopeMin; @@ -538,11 +543,14 @@ namespace UnitTest mockShapeComponentHandler.m_GetEncompassingAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3::CreateZero(), AZ::Vector3(10.0f)); // Set a different altitude for each point we're going to test. We'll use 0, 2, 5, 10 to test various points along the range. - MockSurfaceDataSystem mockSurfaceDataSystem; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() } }; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() } }; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() } }; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() } }; + auto surfaceEntity = CreateEntity(); + auto mockSurface = surfaceEntity->CreateComponent(); + mockSurface->m_bounds = mockShapeComponentHandler.m_GetEncompassingAabb; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() } }; + ActivateEntity(surfaceEntity.get()); // We set the min/max to values other than 0-10 to help validate that they aren't used in the case of the pinned shape. GradientSignal::SurfaceAltitudeGradientConfig config; @@ -572,11 +580,14 @@ namespace UnitTest auto entityShape = CreateEntity(); // Set a different altitude for each point we're going to test. We'll use 0, 2, 5, 10 to test various points along the range. - MockSurfaceDataSystem mockSurfaceDataSystem; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() } }; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() } }; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() } }; - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() } }; + auto surfaceEntity = CreateEntity(); + auto mockSurface = surfaceEntity->CreateComponent(); + mockSurface->m_bounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(1.0f)); + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() } }; + ActivateEntity(surfaceEntity.get()); // We set the min/max to 0-10, but don't set a shape. GradientSignal::SurfaceAltitudeGradientConfig config; @@ -603,9 +614,6 @@ namespace UnitTest auto entityShape = CreateEntity(); - // Don't set any points. - MockSurfaceDataSystem mockSurfaceDataSystem; - // We set the min/max to -5 - 15 so that a height of 0 would produce a non-zero value. GradientSignal::SurfaceAltitudeGradientConfig config; config.m_altitudeMin = -5.0f; @@ -631,16 +639,18 @@ namespace UnitTest auto entityShape = CreateEntity(); - MockSurfaceDataSystem mockSurfaceDataSystem; - + auto surfaceEntity = CreateEntity(); + auto mockSurface = surfaceEntity->CreateComponent(); + mockSurface->m_bounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(1.0f)); // Altitude value below min - should result in 0.0f. - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, -10.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, -10.0f), AZ::Vector3::CreateZero() } }; // Altitude value at exactly min - should result in 0.0f. - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, -5.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, -5.0f), AZ::Vector3::CreateZero() } }; // Altitude value at exactly max - should result in 1.0f. - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 15.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 15.0f), AZ::Vector3::CreateZero() } }; // Altitude value above max - should result in 1.0f. - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 20.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 20.0f), AZ::Vector3::CreateZero() } }; + ActivateEntity(surfaceEntity.get()); // We set the min/max to -5 - 15. By using a range without 0 at either end, and not having 0 as the midpoint, // it should be easier to verify that we're successfully clamping to 0 and 1. @@ -667,7 +677,11 @@ namespace UnitTest 0.5f, 1.0f, }; - MockSurfaceDataSystem mockSurfaceDataSystem; + auto surfaceEntity = CreateEntity(); + auto mockSurface = surfaceEntity->CreateComponent(); + mockSurface->m_bounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(aznumeric_cast(dataSize))); + mockSurface->m_tags.emplace_back("test_mask"); + AzFramework::SurfaceData::SurfacePoint point; // Fill our mock surface with the test_mask set and the expected gradient value at each point. @@ -677,9 +691,10 @@ namespace UnitTest { point.m_surfaceTags.clear(); point.m_surfaceTags.emplace_back(AZ_CRC_CE("test_mask"), expectedOutput[(y * dataSize) + x]); - mockSurfaceDataSystem.m_GetSurfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = { { point } }; + mockSurface->m_surfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = { { point } }; } } + ActivateEntity(surfaceEntity.get()); GradientSignal::SurfaceMaskGradientConfig config; config.m_surfaceTagList.push_back(AZ_CRC("test_mask", 0x7a16e9ff)); @@ -706,8 +721,6 @@ namespace UnitTest 0.0f, 0.0f, }; - MockSurfaceDataSystem mockSurfaceDataSystem; - GradientSignal::SurfaceMaskGradientConfig config; config.m_surfaceTagList.push_back(AZ_CRC("test_mask", 0x7a16e9ff)); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp index 9f4346e09e..4ab4c76d56 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp @@ -67,9 +67,6 @@ namespace UnitTest const AzFramework::SurfaceData::SurfacePoint& input, const AzFramework::SurfaceData::SurfacePoint& expectedOutput) { - // This lets our component register with surfaceData successfully. - MockSurfaceDataSystem mockSurfaceDataSystem; - // Create a mock shape entity in case our gradient test uses shape constraints. // The mock shape is a cube that goes from -0.5 to 0.5 in space. auto mockShapeEntity = CreateTestEntity(0.5f); @@ -105,7 +102,9 @@ namespace UnitTest ActivateEntity(entity.get()); // Get our registered modifier handle (and verify that it's valid) - auto modifierHandle = mockSurfaceDataSystem.GetSurfaceModifierHandle(entity->GetId()); + SurfaceData::SurfaceDataRegistryHandle modifierHandle = SurfaceData::InvalidSurfaceDataRegistryHandle; + SurfaceData::SurfaceDataSystemRequestBus::BroadcastResult( + modifierHandle, &SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfaceDataModifierHandle, entity->GetId()); EXPECT_TRUE(modifierHandle != SurfaceData::InvalidSurfaceDataRegistryHandle); // Call ModifySurfacePoints and verify the results diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp index 402438ee88..3ca145b7c3 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include // Base gradient components #include @@ -40,7 +43,7 @@ namespace UnitTest { void GradientSignalTestEnvironment::AddGemsAndComponents() { - AddDynamicModulePaths({ "LmbrCentral" }); + AddDynamicModulePaths({ "LmbrCentral", "SurfaceData" }); AddComponentDescriptors({ AzFramework::TransformComponent::CreateDescriptor(), @@ -65,6 +68,7 @@ namespace UnitTest GradientSignal::ThresholdGradientComponent::CreateDescriptor(), MockShapeComponent::CreateDescriptor(), + MockSurfaceProviderComponent::CreateDescriptor(), }); } @@ -82,35 +86,6 @@ namespace UnitTest AzFramework::LegacyAssetEventBus::ClearQueuedEvents(); } - AZStd::unique_ptr GradientSignalBaseFixture::CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox) - { - AzFramework::SurfaceData::SurfacePoint point; - AZStd::unique_ptr mockSurfaceDataSystem = AZStd::make_unique(); - - // Give the mock surface data a bunch of fake point values to return. - for (float y = spawnerBox.GetMin().GetY(); y < spawnerBox.GetMax().GetY(); y+= 1.0f) - { - for (float x = spawnerBox.GetMin().GetX(); x < spawnerBox.GetMax().GetX(); x += 1.0f) - { - // Use our x distance into the spawnerBox as an arbitrary percentage value that we'll use to calculate - // our other arbitrary values below. - float arbitraryPercentage = AZStd::abs(x / spawnerBox.GetExtents().GetX()); - - // Create a position that's between min and max Z of the box. - point.m_position = AZ::Vector3(x, y, AZ::Lerp(spawnerBox.GetMin().GetZ(), spawnerBox.GetMax().GetZ(), arbitraryPercentage)); - // Create an arbitrary normal value. - point.m_normal = point.m_position.GetNormalized(); - // Create an arbitrary surface value. - point.m_surfaceTags.clear(); - point.m_surfaceTags.emplace_back(AZ_CRC_CE("test_mask"), arbitraryPercentage); - - mockSurfaceDataSystem->m_GetSurfacePoints[AZStd::make_pair(x, y)] = { { point } }; - } - } - - return mockSurfaceDataSystem; - } - AZStd::unique_ptr GradientSignalBaseFixture::CreateTestEntity(float shapeHalfBounds) { // Create the base entity @@ -120,7 +95,7 @@ namespace UnitTest auto boxComponent = testEntity->CreateComponent(LmbrCentral::AxisAlignedBoxShapeComponentTypeId); boxComponent->SetConfiguration(boxConfig); - // Create a transform that locates our gradient in the center of our desired mock Shape. + // Create a transform that locates our gradient in the center of our desired Shape. auto transform = testEntity->CreateComponent(); transform->SetLocalTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); transform->SetWorldTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); @@ -128,6 +103,23 @@ namespace UnitTest return testEntity; } + AZStd::unique_ptr GradientSignalBaseFixture::CreateTestSphereEntity(float shapeRadius) + { + // Create the base entity + AZStd::unique_ptr testEntity = CreateEntity(); + + LmbrCentral::SphereShapeConfig sphereConfig(shapeRadius); + auto sphereComponent = testEntity->CreateComponent(LmbrCentral::SphereShapeComponentTypeId); + sphereComponent->SetConfiguration(sphereConfig); + + // Create a transform that locates our gradient in the center of our desired Shape. + auto transform = testEntity->CreateComponent(); + transform->SetLocalTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeRadius))); + transform->SetWorldTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeRadius))); + + return testEntity; + } + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestConstantGradient(float shapeHalfBounds) { // Create a Constant Gradient Component with arbitrary parameters. @@ -349,12 +341,18 @@ namespace UnitTest AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSurfaceAltitudeGradient(float shapeHalfBounds) { // Create a Surface Altitude Gradient Component with arbitrary parameters. - auto entity = CreateTestEntity(shapeHalfBounds); + auto entity = CreateTestSphereEntity(shapeHalfBounds); GradientSignal::SurfaceAltitudeGradientConfig config; config.m_altitudeMin = -5.0f; - config.m_altitudeMax = 15.0f; + config.m_altitudeMax = 15.0f + (shapeHalfBounds * 2.0f); entity->CreateComponent(config); + // Create a SurfaceDataShape component to provide surface points from this component. + SurfaceData::SurfaceDataShapeConfig shapeConfig; + shapeConfig.m_providerTags.emplace_back("test_mask"); + auto surfaceShapeComponent = entity->CreateComponent(azrtti_typeid()); + surfaceShapeComponent->SetConfiguration(shapeConfig); + ActivateEntity(entity.get()); return entity; } @@ -362,11 +360,17 @@ namespace UnitTest AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSurfaceMaskGradient(float shapeHalfBounds) { // Create a Surface Mask Gradient Component with arbitrary parameters. - auto entity = CreateTestEntity(shapeHalfBounds); + auto entity = CreateTestSphereEntity(shapeHalfBounds); GradientSignal::SurfaceMaskGradientConfig config; config.m_surfaceTagList.push_back(AZ_CRC_CE("test_mask")); entity->CreateComponent(config); + // Create a SurfaceDataShape component to provide surface points from this component. + SurfaceData::SurfaceDataShapeConfig shapeConfig; + shapeConfig.m_providerTags.emplace_back("test_mask"); + auto surfaceShapeComponent = entity->CreateComponent(azrtti_typeid()); + surfaceShapeComponent->SetConfiguration(shapeConfig); + ActivateEntity(entity.get()); return entity; } @@ -374,7 +378,7 @@ namespace UnitTest AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSurfaceSlopeGradient(float shapeHalfBounds) { // Create a Surface Slope Gradient Component with arbitrary parameters. - auto entity = CreateTestEntity(shapeHalfBounds); + auto entity = CreateTestSphereEntity(shapeHalfBounds); GradientSignal::SurfaceSlopeGradientConfig config; config.m_slopeMin = 5.0f; config.m_slopeMax = 50.0f; @@ -384,6 +388,12 @@ namespace UnitTest config.m_smoothStep.m_falloffStrength = 0.25f; entity->CreateComponent(config); + // Create a SurfaceDataShape component to provide surface points from this component. + SurfaceData::SurfaceDataShapeConfig shapeConfig; + shapeConfig.m_providerTags.emplace_back("test_mask"); + auto surfaceShapeComponent = entity->CreateComponent(azrtti_typeid()); + surfaceShapeComponent->SetConfiguration(shapeConfig); + ActivateEntity(entity.get()); return entity; } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h index 5fda88ea27..9a173e7df1 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h @@ -60,14 +60,14 @@ namespace UnitTest entity->Activate(); } - // Create a mock SurfaceDataSystem that will respond to requests for surface points with mock responses for points inside - // the given input box. - AZStd::unique_ptr CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox); - - // Create an entity with a mock shape and a transform. It won't be activated yet though, because we expect a gradient component + // Create an entity with a box shape and a transform. It won't be activated yet though, because we expect a gradient component // to also get added to it first before activation. AZStd::unique_ptr CreateTestEntity(float shapeHalfBounds); + // Create an entity with a sphere shape and a transform. It won't be activated yet though, because we expect a gradient component + // to also get added to it first before activation. + AZStd::unique_ptr CreateTestSphereEntity(float shapeRadius); + // Create and activate an entity with a gradient component of the requested type, initialized with test data. AZStd::unique_ptr BuildTestConstantGradient(float shapeHalfBounds); AZStd::unique_ptr BuildTestImageGradient(float shapeHalfBounds); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp index 46cc3475e8..0b5432abe9 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp @@ -13,11 +13,11 @@ namespace UnitTest { - void GradientSignalTestHelpers::CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds) + void GradientSignalTestHelpers::CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float queryMin, float queryMax) { // Create a gradient sampler and run through a series of points to see if they match expectations. - const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-shapeHalfBounds), AZ::Vector3(shapeHalfBounds)); + const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(queryMin), AZ::Vector3(queryMax)); const AZ::Vector2 stepSize(1.0f, 1.0f); GradientSignal::GradientSampler gradientSampler; @@ -118,6 +118,7 @@ namespace UnitTest AZStd::vector results(totalQueryPoints); GradientSignal::GradientRequestBus::Event( gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results); + benchmark::DoNotOptimize(results); } } @@ -174,6 +175,7 @@ namespace UnitTest // Query and get the results. AZStd::vector results(totalQueryPoints); gradientSampler.GetValues(positions, results); + benchmark::DoNotOptimize(results); } } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h index 8a175939ee..15b436105e 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h @@ -17,7 +17,7 @@ namespace UnitTest class GradientSignalTestHelpers { public: - static void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds); + static void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float queryMin, float queryMax); #ifdef HAVE_BENCHMARK // We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h index 30f262d9b4..f436045b4e 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -162,4 +163,64 @@ namespace UnitTest bool m_constrainToShape; }; + // Mock out a SurfaceProvider component so that we can control exactly what surface weights get returned + // at which points for our unit tests. + struct MockSurfaceProviderComponent + : public AZ::Component + , public SurfaceData::SurfaceDataProviderRequestBus::Handler + { + public: + AZ_COMPONENT(MockSurfaceProviderComponent, "{18C71877-DB29-4CEC-B34C-B4B44E05203D}", AZ::Component); + + void Activate() override + { + SurfaceData::SurfaceDataRegistryEntry providerRegistryEntry; + providerRegistryEntry.m_entityId = GetEntityId(); + providerRegistryEntry.m_bounds = m_bounds; + providerRegistryEntry.m_tags = m_tags; + + SurfaceData::SurfaceDataSystemRequestBus::BroadcastResult( + m_providerHandle, &SurfaceData::SurfaceDataSystemRequestBus::Events::RegisterSurfaceDataProvider, providerRegistryEntry); + SurfaceData::SurfaceDataProviderRequestBus::Handler::BusConnect(m_providerHandle); + } + + void Deactivate() override + { + SurfaceData::SurfaceDataSystemRequestBus::Broadcast( + &SurfaceData::SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle); + m_providerHandle = SurfaceData::InvalidSurfaceDataRegistryHandle; + SurfaceData::SurfaceDataProviderRequestBus::Handler::BusDisconnect(); + } + + static void Reflect([[maybe_unused]] AZ::ReflectContext* reflect) + { + } + + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("SurfaceDataProviderService")); + } + + void GetSurfacePoints(const AZ::Vector3& inPosition, SurfaceData::SurfacePointList& surfacePointList) const override + { + auto surfacePoints = m_surfacePoints.find(AZStd::make_pair(inPosition.GetX(), inPosition.GetY())); + + if (surfacePoints != m_surfacePoints.end()) + { + surfacePointList = surfacePoints->second; + } + } + + // m_surfacePoints is a mapping of locations to surface tags / weights that should be returned. + AZStd::unordered_map, SurfaceData::SurfacePointList> m_surfacePoints; + + // m_bounds is the AABB to use for our mock surface provider. + AZ::Aabb m_bounds; + + // m_tags are the possible set of tags that this provider will return. + SurfaceData::SurfaceTagVector m_tags; + + SurfaceData::SurfaceDataRegistryHandle m_providerHandle = SurfaceData::InvalidSurfaceDataRegistryHandle; + }; + } diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.h b/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataColliderComponent.h similarity index 100% rename from Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.h rename to Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataColliderComponent.h diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.h b/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataShapeComponent.h similarity index 100% rename from Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.h rename to Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataShapeComponent.h diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.h b/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h similarity index 95% rename from Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.h rename to Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h index bb554cec78..3e1291e524 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h @@ -57,6 +57,10 @@ namespace SurfaceData void UpdateSurfaceDataModifier(const SurfaceDataRegistryHandle& handle, const SurfaceDataRegistryEntry& entry) override; void RefreshSurfaceData(const AZ::Aabb& dirtyArea) override; + + SurfaceDataRegistryHandle GetSurfaceDataProviderHandle(const AZ::EntityId& providerEntityId) override; + SurfaceDataRegistryHandle GetSurfaceDataModifierHandle(const AZ::EntityId& modifierEntityId) override; + private: SurfaceDataRegistryHandle RegisterSurfaceDataProviderInternal(const SurfaceDataRegistryEntry& entry); SurfaceDataRegistryEntry UnregisterSurfaceDataProviderInternal(const SurfaceDataRegistryHandle& handle); diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h index 616f069184..d4e84c5974 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h @@ -58,6 +58,10 @@ namespace SurfaceData // Notify any dependent systems that they need to refresh their surface data for the provided area. virtual void RefreshSurfaceData(const AZ::Aabb& dirtyArea) = 0; + + // Get the SurfaceDataRegistryHandle for a given entityId. + virtual SurfaceDataRegistryHandle GetSurfaceDataProviderHandle(const AZ::EntityId& providerEntityId) = 0; + virtual SurfaceDataRegistryHandle GetSurfaceDataModifierHandle(const AZ::EntityId& modifierEntityId) = 0; }; typedef AZ::EBus SurfaceDataSystemRequestBus; diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h b/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h index 82a321756d..bafe215402 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h @@ -250,6 +250,16 @@ namespace UnitTest { } + SurfaceData::SurfaceDataRegistryHandle GetSurfaceDataProviderHandle(const AZ::EntityId& providerEntityId) override + { + return GetSurfaceProviderHandle(providerEntityId); + } + + SurfaceData::SurfaceDataRegistryHandle GetSurfaceDataModifierHandle(const AZ::EntityId& modifierEntityId) override + { + return GetSurfaceModifierHandle(modifierEntityId); + } + SurfaceData::SurfaceDataRegistryHandle GetSurfaceProviderHandle(AZ::EntityId id) { return GetEntryHandle(id, m_providers); diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp b/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp index 86a165b7d8..35f377bfe0 100644 --- a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp +++ b/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp @@ -6,7 +6,7 @@ * */ -#include "SurfaceDataColliderComponent.h" +#include #include #include diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp b/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp index 481372b7dc..973fca232a 100644 --- a/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp +++ b/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp @@ -6,7 +6,7 @@ * */ -#include "SurfaceDataShapeComponent.h" +#include #include #include diff --git a/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataColliderComponent.h b/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataColliderComponent.h index 211d819b4d..a25061c245 100644 --- a/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataColliderComponent.h +++ b/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataColliderComponent.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include namespace SurfaceData diff --git a/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataShapeComponent.h b/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataShapeComponent.h index 79218b9317..202511c4c7 100644 --- a/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataShapeComponent.h +++ b/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataShapeComponent.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include namespace SurfaceData diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataEditorModule.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataEditorModule.cpp index 936cac5954..5f1ead9873 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataEditorModule.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataEditorModule.cpp @@ -7,7 +7,7 @@ */ #include -#include +#include #include #include #include diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataModule.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataModule.cpp index 35064bf4a4..36b8936e23 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataModule.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataModule.cpp @@ -7,9 +7,9 @@ */ #include -#include -#include -#include +#include +#include +#include namespace SurfaceData { diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp index 66b8c83a58..7dc6711b72 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp @@ -12,7 +12,7 @@ #include #include -#include "SurfaceDataSystemComponent.h" +#include #include #include #include @@ -175,6 +175,34 @@ namespace SurfaceData SurfaceDataSystemNotificationBus::Broadcast(&SurfaceDataSystemNotificationBus::Events::OnSurfaceChanged, AZ::EntityId(), dirtyBounds, dirtyBounds); } + SurfaceDataRegistryHandle SurfaceDataSystemComponent::GetSurfaceDataProviderHandle(const AZ::EntityId& providerEntityId) + { + AZStd::shared_lock registrationLock(m_registrationMutex); + + for (auto& [providerHandle, providerEntry] : m_registeredSurfaceDataProviders) + { + if (providerEntry.m_entityId == providerEntityId) + { + return providerHandle; + } + } + return {}; + } + + SurfaceDataRegistryHandle SurfaceDataSystemComponent::GetSurfaceDataModifierHandle(const AZ::EntityId& modifierEntityId) + { + AZStd::shared_lock registrationLock(m_registrationMutex); + + for (auto& [modifierHandle, modifierEntry] : m_registeredSurfaceDataModifiers) + { + if (modifierEntry.m_entityId == modifierEntityId) + { + return modifierHandle; + } + } + return {}; + } + void SurfaceDataSystemComponent::GetSurfacePoints(const AZ::Vector3& inPosition, const SurfaceTagVector& desiredTags, SurfacePointList& surfacePointList) const { const bool useTagFilters = HasValidTags(desiredTags); diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp index 04c1ada677..a25273896e 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp @@ -226,9 +226,7 @@ namespace SurfaceData void SurfacePointList::ReserveSpace(size_t maxPointsPerInput) { - AZ_Assert( - m_surfacePositionList.size() < maxPointsPerInput, - "Trying to reserve space on a list that is already using more points than requested."); + AZ_Assert(m_surfacePositionList.empty(), "Trying to reserve space on a list that is already being used."); m_surfaceCreatorIdList.reserve(maxPointsPerInput); m_surfacePositionList.reserve(maxPointsPerInput); diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp index f8b4c675a5..df011113da 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp @@ -21,8 +21,8 @@ #include #include #include -#include -#include +#include +#include namespace UnitTest { diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp index 884c831393..aca5a53f4d 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp index f4ff0cb04c..8500e557bf 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataTestFixtures.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataTestFixtures.cpp index 2ec531d2e4..28f7ea6b03 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataTestFixtures.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataTestFixtures.cpp @@ -11,9 +11,9 @@ #include #include -#include -#include -#include +#include +#include +#include namespace UnitTest diff --git a/Gems/SurfaceData/Code/surfacedata_files.cmake b/Gems/SurfaceData/Code/surfacedata_files.cmake index 1c36ca43a0..8e7435abb3 100644 --- a/Gems/SurfaceData/Code/surfacedata_files.cmake +++ b/Gems/SurfaceData/Code/surfacedata_files.cmake @@ -7,6 +7,9 @@ # set(FILES + Include/SurfaceData/Components/SurfaceDataColliderComponent.h + Include/SurfaceData/Components/SurfaceDataShapeComponent.h + Include/SurfaceData/Components/SurfaceDataSystemComponent.h Include/SurfaceData/SurfaceDataConstants.h Include/SurfaceData/SurfaceDataTypes.h Include/SurfaceData/SurfaceDataSystemRequestBus.h @@ -18,12 +21,9 @@ set(FILES Include/SurfaceData/SurfaceTag.h Include/SurfaceData/Utility/SurfaceDataUtility.h Source/SurfaceDataSystemComponent.cpp - Source/SurfaceDataSystemComponent.h Source/SurfaceDataTypes.cpp Source/SurfaceTag.cpp Source/Components/SurfaceDataColliderComponent.cpp - Source/Components/SurfaceDataColliderComponent.h Source/Components/SurfaceDataShapeComponent.cpp - Source/Components/SurfaceDataShapeComponent.h Source/SurfaceDataUtility.cpp ) diff --git a/Gems/Vegetation/Code/Tests/VegetationMocks.h b/Gems/Vegetation/Code/Tests/VegetationMocks.h index d77862d578..33a320b03e 100644 --- a/Gems/Vegetation/Code/Tests/VegetationMocks.h +++ b/Gems/Vegetation/Code/Tests/VegetationMocks.h @@ -384,6 +384,16 @@ namespace UnitTest { ++m_count; } + + SurfaceData::SurfaceDataRegistryHandle GetSurfaceDataProviderHandle([[maybe_unused]] const AZ::EntityId& providerEntityId) override + { + return {}; + } + + SurfaceData::SurfaceDataRegistryHandle GetSurfaceDataModifierHandle([[maybe_unused]] const AZ::EntityId& modifierEntityId) override + { + return {}; + } }; struct MockMeshAsset From 742ea34d442ceefe14a8219119a8612b9c704c64 Mon Sep 17 00:00:00 2001 From: rgba16f <82187279+rgba16f@users.noreply.github.com> Date: Tue, 8 Feb 2022 15:24:37 -0600 Subject: [PATCH 14/24] Add a function to get the internal data for a disk light from it's feature processor (#7450) * Add a function to get the internal data for a disk light from it's feature processor Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> * Address PR comments. Fixed assert message, made function const. Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> --- .../CoreLights/DiskLightFeatureProcessorInterface.h | 3 ++- .../Code/Source/CoreLights/DiskLightFeatureProcessor.cpp | 7 +++++++ .../Code/Source/CoreLights/DiskLightFeatureProcessor.h | 1 + .../RPI/Code/Include/Atom/RPI.Public/AuxGeom/AuxGeomDraw.h | 4 ++-- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h index 98220fae15..9622b5aa40 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h @@ -100,7 +100,8 @@ namespace AZ //! Sets all of the the disk data for the provided LightHandle. virtual void SetDiskData(LightHandle handle, const DiskLightData& data) = 0; - + //! Get a read only copy of a disk lights data, useful for debug rendering + virtual const DiskLightData& GetDiskData(LightHandle handle) const = 0; }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp index 168a7ea00a..9c626fccd8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp @@ -255,6 +255,13 @@ namespace AZ UpdateShadow(handle); } + const DiskLightData& DiskLightFeatureProcessor::GetDiskData(LightHandle handle) const + { + AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to DiskLightFeatureProcessor::GetDiskData()."); + + return m_diskLightData.GetData(handle.GetIndex()); + } + const Data::Instance DiskLightFeatureProcessor::GetLightBuffer()const { return m_lightBufferHandler.GetBuffer(); diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h index bafddacc65..d742b1fbc0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h @@ -58,6 +58,7 @@ namespace AZ void SetEsmExponent(LightHandle handle, float esmExponent) override; void SetDiskData(LightHandle handle, const DiskLightData& data) override; + const DiskLightData& GetDiskData(LightHandle handle) const override; const Data::Instance GetLightBuffer()const; uint32_t GetLightCount()const; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/AuxGeom/AuxGeomDraw.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/AuxGeom/AuxGeomDraw.h index 29b127407e..b3e898c4dd 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/AuxGeom/AuxGeomDraw.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/AuxGeom/AuxGeomDraw.h @@ -184,8 +184,8 @@ namespace AZ virtual void DrawDisk(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0; //! Draw a cone. - //! @param center The center of the base circle. - //! @param direction The direction vector. The tip of the cone will point along this vector. + //! @param center The center of the cone base. + //! @param direction The direction vector. This is the vector from the center of the base to the point at the tip. //! @param radius The radius. //! @param height The height of the cone (the distance from the base center to the tip). //! @param color The color to draw the cone. From d1bb5a0543268ec73223aa24eea093f864a830f4 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 8 Feb 2022 13:44:08 -0800 Subject: [PATCH 15/24] Move DOM delta comparison to its own file, enhance inverting moves Signed-off-by: Nicholas Van Sickle --- .../AzCore/AzCore/DOM/DomComparison.cpp | 178 +++++++++++++++ .../AzCore/AzCore/DOM/DomComparison.h | 37 +++ Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp | 215 ++---------------- Code/Framework/AzCore/AzCore/DOM/DomPatch.h | 26 +-- .../AzCore/AzCore/azcore_files.cmake | 2 + .../AzCore/Tests/DOM/DomPatchTests.cpp | 5 +- 6 files changed, 245 insertions(+), 218 deletions(-) create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomComparison.cpp create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomComparison.h diff --git a/Code/Framework/AzCore/AzCore/DOM/DomComparison.cpp b/Code/Framework/AzCore/AzCore/DOM/DomComparison.cpp new file mode 100644 index 0000000000..dc21761670 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomComparison.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace AZ::Dom +{ + PatchUndoRedoInfo GenerateHierarchicalDeltaPatch( + const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params) + { + PatchUndoRedoInfo patches; + + auto AddPatch = [&patches](PatchOperation op, PatchOperation inverse) + { + patches.m_forwardPatches.PushBack(AZStd::move(op)); + patches.m_inversePatches.PushFront(AZStd::move(inverse)); + }; + + AZStd::function compareValues; + + struct PendingComparison + { + Path m_path; + const Value& m_before; + const Value& m_after; + + PendingComparison(Path path, const Value& before, const Value& after) + : m_path(AZStd::move(path)) + , m_before(before) + , m_after(after) + { + } + }; + AZStd::queue entriesToCompare; + + AZStd::unordered_set desiredKeys; + auto compareObjects = [&](const Path& path, const Value& before, const Value& after) + { + desiredKeys.clear(); + Path subPath = path; + for (auto it = after.MemberBegin(); it != after.MemberEnd(); ++it) + { + desiredKeys.insert(it->first.GetHash()); + subPath.Push(it->first); + auto beforeIt = before.FindMember(it->first); + if (beforeIt == before.MemberEnd()) + { + AddPatch(PatchOperation::AddOperation(subPath, it->second), PatchOperation::RemoveOperation(subPath)); + } + else + { + entriesToCompare.emplace(subPath, beforeIt->second, it->second); + } + subPath.Pop(); + } + + for (auto it = before.MemberBegin(); it != before.MemberEnd(); ++it) + { + if (!desiredKeys.contains(it->first.GetHash())) + { + subPath.Push(it->first); + AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, it->second)); + subPath.Pop(); + } + } + }; + + auto compareArrays = [&](const Path& path, const Value& before, const Value& after) + { + const size_t beforeSize = before.ArraySize(); + const size_t afterSize = after.ArraySize(); + + // If more than replaceThreshold values differ, do a replace operation instead + if (params.m_replaceThreshold != DeltaPatchGenerationParameters::NoReplace) + { + size_t changedValueCount = 0; + const size_t entriesToEnumerate = AZStd::min(beforeSize, afterSize); + for (size_t i = 0; i < entriesToEnumerate; ++i) + { + if (before[i] != after[i]) + { + ++changedValueCount; + if (changedValueCount >= params.m_replaceThreshold) + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + return; + } + } + } + } + + Path subPath = path; + for (size_t i = 0; i < afterSize; ++i) + { + if (i >= beforeSize) + { + subPath.Push(PathEntry(PathEntry::EndOfArrayIndex)); + AddPatch(PatchOperation::AddOperation(subPath, after[i]), PatchOperation::RemoveOperation(subPath)); + subPath.Pop(); + } + else + { + subPath.Push(PathEntry(i)); + entriesToCompare.emplace(subPath, before[i], after[i]); + subPath.Pop(); + } + } + + if (beforeSize > afterSize) + { + subPath.Push(PathEntry(PathEntry::EndOfArrayIndex)); + for (size_t i = beforeSize; i > afterSize; --i) + { + AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, before[i - 1])); + } + } + }; + + auto compareNodes = [&](const Path& path, const Value& before, const Value& after) + { + if (before.GetNodeName() != after.GetNodeName()) + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + } + else + { + compareObjects(path, before, after); + compareArrays(path, before, after); + } + }; + + compareValues = [&](const Path& path, const Value& before, const Value& after) + { + if (before.GetType() != after.GetType()) + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + } + else if (before == after) + { + // If a shallow comparison succeeds we're pointing to an identical value or container + // and don't need to drill down. + return; + } + else if (before.IsObject()) + { + compareObjects(path, before, after); + } + else if (before.IsArray()) + { + compareArrays(path, before, after); + } + else if (before.IsNode()) + { + compareNodes(path, before, after); + } + else + { + AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); + } + }; + + entriesToCompare.emplace(Path(), beforeState, afterState); + while (!entriesToCompare.empty()) + { + PendingComparison& comparison = entriesToCompare.front(); + compareValues(comparison.m_path, comparison.m_before, comparison.m_after); + entriesToCompare.pop(); + } + return patches; + } +} diff --git a/Code/Framework/AzCore/AzCore/DOM/DomComparison.h b/Code/Framework/AzCore/AzCore/DOM/DomComparison.h new file mode 100644 index 0000000000..f882887cba --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomComparison.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +namespace AZ::Dom +{ + //! A set of patches for applying a change and doing the inverse operation. + struct PatchUndoRedoInfo + { + Patch m_forwardPatches; + Patch m_inversePatches; + }; + + //! Parameters for GenerateHierarchicalDeltaPatch. + struct DeltaPatchGenerationParameters + { + static constexpr size_t NoReplace = AZStd::numeric_limits::max(); + static constexpr size_t AlwaysFullReplace = 0; + + //! The threshold of changed values in a node or array which, if exceeded, will cause the generation to create an + //! entire "replace" oepration instead. If set to NoReplace, no replacement will occur. + size_t m_replaceThreshold = 3; + }; + + //! Generates a set of patches such that m_forwardPatches.Apply(beforeState) shall produce a document equivalent to afterState, and + //! a subsequent m_inversePatches.Apply(beforeState) shall produce the original document. This patch generation strategy does a + //! hierarchical comparison and is not guaranteed to create the minimal set of patches required to transform between the two states. + PatchUndoRedoInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params = {}); +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp index f89cb313e7..dc0bff4e7c 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.cpp @@ -8,8 +8,6 @@ #include #include -#include -#include namespace AZ::Dom { @@ -297,7 +295,7 @@ namespace AZ::Dom } } - AZ::Outcome PatchOperation::GetInverse(Value stateBeforeApplication) const + AZ::Outcome, AZStd::string> PatchOperation::GetInverse(Value stateBeforeApplication) const { switch (m_type) { @@ -310,10 +308,10 @@ namespace AZ::Dom const Value* existingValue = stateBeforeApplication.FindChild(m_domPath); if (existingValue != nullptr) { - return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); + return AZ::Success({PatchOperation::ReplaceOperation(m_domPath, *existingValue)}); } } - return AZ::Success(PatchOperation::RemoveOperation(m_domPath)); + return AZ::Success({PatchOperation::RemoveOperation(m_domPath)}); } case Type::Remove: { @@ -325,7 +323,7 @@ namespace AZ::Dom m_domPath.AppendToString(errorMessage); return AZ::Failure(AZStd::move(errorMessage)); } - return AZ::Success(PatchOperation::AddOperation(m_domPath, *existingValue)); + return AZ::Success({PatchOperation::AddOperation(m_domPath, *existingValue)}); } case Type::Replace: { @@ -337,7 +335,7 @@ namespace AZ::Dom m_domPath.AppendToString(errorMessage); return AZ::Failure(AZStd::move(errorMessage)); } - return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); + return AZ::Success({PatchOperation::ReplaceOperation(m_domPath, *existingValue)}); } case Type::Copy: { @@ -349,40 +347,37 @@ namespace AZ::Dom m_domPath.AppendToString(errorMessage); return AZ::Failure(AZStd::move(errorMessage)); } - return AZ::Success(PatchOperation::ReplaceOperation(m_domPath, *existingValue)); + return AZ::Success({PatchOperation::ReplaceOperation(m_domPath, *existingValue)}); } case Type::Move: { - // Move -> Replace, using the common ancestor of the two paths as the replacement - // This is not a minimal inverse, which would be two replace operations at each path - const Path& destPath = m_domPath; - const Path& sourcePath = GetSourcePath(); - - Path commonAncestor; - for (size_t i = 0; i < destPath.Size() && i < sourcePath.Size(); ++i) + const Value* sourceValue = stateBeforeApplication.FindChild(GetSourcePath()); + if (sourceValue == nullptr) { - if (destPath[i] != sourcePath[i]) - { - break; - } - - commonAncestor.Push(destPath[i]); + AZStd::string errorMessage = "Unable to invert DOM copy patch, source path not found: "; + m_domPath.AppendToString(errorMessage); + return AZ::Failure(AZStd::move(errorMessage)); } - const Value* existingValue = stateBeforeApplication.FindChild(commonAncestor); - if (existingValue == nullptr) + // If there was a value at the destination path, invert with an add / replace + const Value* destinationValue = stateBeforeApplication.FindChild(GetDestinationPath()); + if (destinationValue != nullptr) { - AZStd::string errorMessage = "Unable to invert DOM copy patch, common ancestor path not found: "; - commonAncestor.AppendToString(errorMessage); - return AZ::Failure(AZStd::move(errorMessage)); + InversePatches result({PatchOperation::AddOperation(GetSourcePath(), *sourceValue)}); + result.push_back(PatchOperation::ReplaceOperation(GetDestinationPath(), *destinationValue)); + return AZ::Success({ + PatchOperation::AddOperation(GetSourcePath(), *sourceValue), + PatchOperation::ReplaceOperation(GetDestinationPath(), *destinationValue), + }); } - return AZ::Success(PatchOperation::ReplaceOperation(commonAncestor, *existingValue)); + // Otherwise, just do a move + return AZ::Success({PatchOperation::MoveOperation(GetDestinationPath(), GetSourcePath())}); } case Type::Test: { // Test -> Test (no change) // When inverting a sequence of patches, applying them in reverse order should allow the test to continue to succeed - return AZ::Success(*this); + return AZ::Success({*this}); } } return AZ::Failure("Unable to invert DOM patch, unknown type specified"); @@ -801,168 +796,4 @@ namespace AZ::Dom { return PatchOperation(AZStd::move(testPath), PatchOperation::Type::Test, AZStd::move(value)); } - - PatchInfo GenerateHierarchicalDeltaPatch( - const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params) - { - PatchInfo patches; - - auto AddPatch = [&patches](PatchOperation op, PatchOperation inverse) - { - patches.m_forwardPatches.PushBack(AZStd::move(op)); - patches.m_inversePatches.PushFront(AZStd::move(inverse)); - }; - - AZStd::function compareValues; - - struct PendingComparison - { - Path m_path; - const Value& m_before; - const Value& m_after; - - PendingComparison(Path path, const Value& before, const Value& after) - : m_path(AZStd::move(path)) - , m_before(before) - , m_after(after) - { - } - }; - AZStd::queue entriesToCompare; - - AZStd::unordered_set desiredKeys; - auto compareObjects = [&](const Path& path, const Value& before, const Value& after) - { - desiredKeys.clear(); - Path subPath = path; - for (auto it = after.MemberBegin(); it != after.MemberEnd(); ++it) - { - desiredKeys.insert(it->first.GetHash()); - subPath.Push(it->first); - auto beforeIt = before.FindMember(it->first); - if (beforeIt == before.MemberEnd()) - { - AddPatch(PatchOperation::AddOperation(subPath, it->second), PatchOperation::RemoveOperation(subPath)); - } - else - { - entriesToCompare.emplace(subPath, beforeIt->second, it->second); - } - subPath.Pop(); - } - - for (auto it = before.MemberBegin(); it != before.MemberEnd(); ++it) - { - if (!desiredKeys.contains(it->first.GetHash())) - { - subPath.Push(it->first); - AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, it->second)); - subPath.Pop(); - } - } - }; - - auto compareArrays = [&](const Path& path, const Value& before, const Value& after) - { - const size_t beforeSize = before.ArraySize(); - const size_t afterSize = after.ArraySize(); - - // If more than replaceThreshold values differ, do a replace operation instead - if (params.m_replaceThreshold != DeltaPatchGenerationParameters::NoReplace) - { - size_t changedValueCount = 0; - const size_t entriesToEnumerate = AZStd::min(beforeSize, afterSize); - for (size_t i = 0; i < entriesToEnumerate; ++i) - { - if (before[i] != after[i]) - { - ++changedValueCount; - if (changedValueCount >= params.m_replaceThreshold) - { - AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); - return; - } - } - } - } - - Path subPath = path; - for (size_t i = 0; i < afterSize; ++i) - { - if (i >= beforeSize) - { - subPath.Push(PathEntry(PathEntry::EndOfArrayIndex)); - AddPatch(PatchOperation::AddOperation(subPath, after[i]), PatchOperation::RemoveOperation(subPath)); - subPath.Pop(); - } - else - { - subPath.Push(PathEntry(i)); - entriesToCompare.emplace(subPath, before[i], after[i]); - subPath.Pop(); - } - } - - if (beforeSize > afterSize) - { - subPath.Push(PathEntry(PathEntry::EndOfArrayIndex)); - for (size_t i = beforeSize; i > afterSize; --i) - { - AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, before[i - 1])); - } - } - }; - - auto compareNodes = [&](const Path& path, const Value& before, const Value& after) - { - if (before.GetNodeName() != after.GetNodeName()) - { - AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); - } - else - { - compareObjects(path, before, after); - compareArrays(path, before, after); - } - }; - - compareValues = [&](const Path& path, const Value& before, const Value& after) - { - if (before.GetType() != after.GetType()) - { - AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); - } - else if (before == after) - { - // If a shallow comparison succeeds we're pointing to an identical value or container - // and don't need to drill down. - return; - } - else if (before.IsObject()) - { - compareObjects(path, before, after); - } - else if (before.IsArray()) - { - compareArrays(path, before, after); - } - else if (before.IsNode()) - { - compareNodes(path, before, after); - } - else - { - AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before)); - } - }; - - entriesToCompare.emplace(Path(), beforeState, afterState); - while (!entriesToCompare.empty()) - { - PendingComparison& comparison = entriesToCompare.front(); - compareValues(comparison.m_path, comparison.m_before, comparison.m_after); - entriesToCompare.pop(); - } - return patches; - } } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h index 40ef725b57..2d591a8079 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomPatch.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomPatch.h @@ -71,7 +71,8 @@ namespace AZ::Dom Value GetDomRepresentation() const; static AZ::Outcome CreateFromDomRepresentation(Value domValue); - AZ::Outcome GetInverse(Value stateBeforeApplication) const; + using InversePatches = AZStd::fixed_vector; + AZ::Outcome, AZStd::string> GetInverse(Value stateBeforeApplication) const; enum class ExistenceCheckFlags : AZ::u8 { @@ -182,27 +183,4 @@ namespace AZ::Dom private: OperationsContainer m_operations; }; - - //! A set of patches for applying a change and doing the inverse operation (i.e. undoing it). - struct PatchInfo - { - Patch m_forwardPatches; - Patch m_inversePatches; - }; - - //! Parameters for GenerateHierarchicalDeltaPatch. - struct DeltaPatchGenerationParameters - { - static constexpr size_t NoReplace = AZStd::numeric_limits::max(); - static constexpr size_t AlwaysFullReplace = 0; - - //! The threshold of changed values in a node or array which, if exceeded, will cause the generation to create an - //! entire "replace" oepration instead. If set to NoReplace, no replacement will occur. - size_t m_replaceThreshold = 3; - }; - - //! Generates a set of patches such that m_forwardPatches.Apply(beforeState) shall produce a document equivalent to afterState, and - //! a subsequent m_inversePatches.Apply(beforeState) shall produce the original document. This patch generation strategy does a - //! hierarchical comparison and is not guaranteed to create the minimal set of patches required to transform between the two states. - PatchInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params = {}); } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index ad7d7cbdef..b7821f1d65 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -128,6 +128,8 @@ set(FILES DOM/DomValueWriter.h DOM/DomVisitor.cpp DOM/DomVisitor.h + DOM/DomComparison.cpp + DOM/DomComparison.h DOM/Backends/JSON/JsonBackend.h DOM/Backends/JSON/JsonSerializationUtils.cpp DOM/Backends/JSON/JsonSerializationUtils.h diff --git a/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp index a0e4f349a5..b60c09330f 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPatchTests.cpp @@ -7,6 +7,7 @@ */ #include +#include #include namespace AZ::Dom::Tests @@ -45,9 +46,9 @@ namespace AZ::Dom::Tests DomTestFixture::TearDown(); } - PatchInfo GenerateAndVerifyDelta() + PatchUndoRedoInfo GenerateAndVerifyDelta() { - PatchInfo info = GenerateHierarchicalDeltaPatch(m_dataset, m_deltaDataset); + PatchUndoRedoInfo info = GenerateHierarchicalDeltaPatch(m_dataset, m_deltaDataset); auto result = info.m_forwardPatches.Apply(m_dataset); EXPECT_TRUE(result.IsSuccess()); From 61f915366a92a02f57e3a3b53b7f30ada76eddbf Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Fri, 4 Feb 2022 11:53:37 -0700 Subject: [PATCH 16/24] Shader refactor (no functional changes) The purpose of this shader refactor is to split various material type shaders into disparate pieces: 1. The original material type shaders now include an external file with the actual shader entry points and structure of the algorithm (e.g. depth pass, shadow pass, forward pass) but continue to specify the SRGs used 2. Common functionality used across multiple shaders was consolidated into routines implemented in the MaterialFunctions folder (Materials/Types/MaterialFunctions) 3. The implementation shaders rely on common routines to be included/imported prior to inclusion, and by design, make no references to any Draw, Object, or Material SRG. This refactor only includes the Standard and Enhanced material types, and is, for the most part, a non-functional change. However, the Surface definition needed to be augmented to include information needed by lighting later. Modifying the Surface structure enables the lighting loops to avoid any references to the Material SRG. This completes the decoupling needed to support future Material canvas work, as well as a future Material pipeline abstraction (where by the implementation shaders can be injected by the user, customized per platform, and in general, are simply decoupled from the materials themselves). Signed-off-by: Jeremy Ong --- .../Materials/Types/BasePBR_ForwardPass.azsl | 6 +- .../Materials/Types/DepthPass_WithPS.azsl | 124 ++++++ .../Types/EnhancedPBR_DepthPass_WithPS.azsl | 91 +--- .../Types/EnhancedPBR_ForwardPass.azsl | 417 +----------------- .../Types/EnhancedPBR_Shadowmap_WithPS.azsl | 91 +--- .../Types/EnhancedSurface_ForwardPass.azsl | 317 +++++++++++++ .../EnhancedParallaxDepth.azsli | 41 ++ .../EvaluateEnhancedSurface.azsli | 149 +++++++ .../EvaluateStandardSurface.azsli | 95 ++++ .../EvaluateTangentFrame.azsli | 33 ++ .../MultilayerParallaxDepth.azsli | 35 ++ .../MaterialFunctions/ParallaxDepth.azsli | 51 +++ .../MaterialFunctions/StandardGetAlpha.azsli | 17 + .../StandardGetNormalToWorld.azsli | 12 + .../StandardGetObjectToWorld.azsli | 12 + .../MaterialFunctions/StandardMaybeClip.azsli | 14 + .../StandardTransformDetailUvs.azsli | 18 + .../StandardTransformUvs.azsli | 14 + .../Materials/Types/ShadowMap_WithPS.azsl | 127 ++++++ ...tandardMultilayerPBR_DepthPass_WithPS.azsl | 109 +---- .../StandardMultilayerPBR_ForwardPass.azsl | 10 +- ...tandardMultilayerPBR_Shadowmap_WithPS.azsl | 108 +---- .../Types/StandardPBR_DepthPass_WithPS.azsl | 94 +--- .../Types/StandardPBR_ForwardPass.azsl | 340 +------------- .../Types/StandardPBR_Shadowmap_WithPS.azsl | 93 +--- .../Types/StandardSurface_ForwardPass.azsl | 306 +++++++++++++ .../PBR/Surfaces/EnhancedSurface.azsli | 27 +- .../PBR/Surfaces/StandardSurface.azsli | 22 +- .../Types/AutoBrick_ForwardPass.azsl | 16 +- .../Types/MinimalPBR_ForwardPass.azsl | 6 +- 30 files changed, 1492 insertions(+), 1303 deletions(-) create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl index 96318f2284..b887761917 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl @@ -116,19 +116,19 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace) float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; float3 sampledColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor.rgb, o_baseColor_useTexture); - float3 baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); + surface.baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); // ------- Metallic ------- float2 metallicUv = IN.m_uv[MaterialSrg::m_metallicMapUvIndex]; - float metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); + surface.metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); // ------- Specular ------- float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex]; float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); + surface.SetAlbedoAndSpecularF0(specularF0Factor); // ------- Roughness ------- diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl new file mode 100644 index 0000000000..9b017222b1 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl @@ -0,0 +1,124 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +struct VSInput +{ + float3 m_position : POSITION; + float2 m_uv0 : UV0; + float2 m_uv1 : UV1; + + // only used for parallax depth calculation + float3 m_normal : NORMAL; + float4 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + +#ifdef MULTILAYER + // This gets set automatically by the system at runtime only if it's available. + // There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available. + // (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention). + // [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream. + float4 m_optional_blendMask : COLOR0; +#endif +}; + +struct VSDepthOutput +{ + // "centroid" is needed for SV_Depth to compile + precise linear centroid float4 m_position : SV_Position; + float2 m_uv[UvSetCount] : UV1; + + // only used for parallax depth calculation + float3 m_normal : NORMAL; + float3 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + float3 m_worldPosition : UV0; + +#ifdef MULTILAYER + float3 m_blendMask : UV3; +#endif +}; + +VSDepthOutput MainVS(VSInput IN) +{ + VSDepthOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + float2 uvs[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uvs, OUT.m_uv); + + if(ShouldHandleParallaxInDepthShaders()) + { + OUT.m_worldPosition = worldPosition.xyz; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + } + +#ifdef MULTILAYER + if(o_blendMask_isBound) + { + OUT.m_blendMask = IN.m_optional_blendMask.rgb; + } + else + { + OUT.m_blendMask = float3(0,0,0); + } +#endif + + return OUT; +} + +struct PSDepthOutput +{ + precise float m_depth : SV_Depth; +}; + +PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) +{ + PSDepthOutput OUT; + + OUT.m_depth = IN.m_position.z; + + if(ShouldHandleParallaxInDepthShaders()) + { + float3 tangents[UvSetCount] = { IN.m_tangent, IN.m_tangent }; + float3 bitangents[UvSetCount] = { IN.m_bitangent, IN.m_bitangent }; + + for (int i = 0; i != UvSetCount; ++i) + { + EvaluateTangentFrame( + IN.m_normal, + IN.m_worldPosition, + isFrontFace, + IN.m_uv[i], + i, + IN.m_tangent, + IN.m_bitangent, + tangents[i], + bitangents[i]); + } + +#ifdef MULTILAYER + MultilayerSetPixelDepth(IN.m_blendMask, IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); +#else + SetPixelDepth(IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); +#endif + + } + +#ifndef MULTILAYER + float alpha = GetAlpha(IN.m_uv); + MaybeClip(alpha, IN.m_uv); +#endif + + return OUT; +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl index 08642decc0..2f7a5b94f9 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl @@ -8,88 +8,13 @@ #include "./EnhancedPBR_Common.azsli" #include -#include -#include -#include "MaterialInputs/AlphaInput.azsli" -#include "MaterialInputs/ParallaxInput.azsli" +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetAlpha.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/ParallaxDepth.azsli" +#include "MaterialFunctions/StandardMaybeClip.azsli" -struct VSInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; -}; - -struct VSDepthOutput -{ - precise linear centroid float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; -}; - -VSDepthOutput MainVS(VSInput IN) -{ - VSDepthOutput OUT; - - float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); - float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); - - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); - // By design, only UV0 is allowed to apply transforms. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - return OUT; -} - -struct PSDepthOutput -{ - precise float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, OUT.m_depth); - } - - // Clip Alpha - float2 baseColorUV = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; - float2 opacityUV = IN.m_uv[MaterialSrg::m_opacityMapUvIndex]; - float alpha = SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); - CheckClipping(alpha, MaterialSrg::m_opacityFactor); - - return OUT; -} +#include "DepthPass_WithPS.azsl" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 8458ca11a2..bac97fed64 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -10,21 +10,6 @@ // SRGs #include -#include - -// Pass Output -#include - -// Utility -#include -#include - -// Custom Surface & Lighting -#include - -// Decals -#include - // ---------- Material Parameters ---------- @@ -49,397 +34,13 @@ COMMON_OPTIONS_DETAIL_MAPS() #include "MaterialInputs/TransmissionInput.azsli" -// ---------- Vertex Shader ---------- - -struct VSInput -{ - // Base fields (required by the template azsli file)... - float3 m_position : POSITION; - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - - // Extended fields (only referenced in this azsl file)... - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; -}; - -struct VSOutput -{ - // Base fields (required by the template azsli file)... - precise linear centroid float4 m_position : SV_Position; - float3 m_normal: NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; - float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV5; - - // Extended fields (only referenced in this azsl file)... - float2 m_uv[UvSetCount] : UV1; - float2 m_detailUv[UvSetCount] : UV3; -}; - -#include - -VSOutput EnhancedPbr_ForwardPassVS(VSInput IN) -{ - VSOutput OUT; - - float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz; - - // By design, only UV0 is allowed to apply transforms. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - // As seen above our standard practice is to only transform the first UV as that's the one we expect to be used for - // tiling. But for detail maps you could actually use either UV stream for tiling. There is no concern about applying - // the same transform to both UV sets because the detail map feature forces the same UV set to be used for all detail maps. - // Note we might be able to combine these into a single UV similar to what Skin.materialtype does, - // but we would need to address how it works with the parallax code below that indexes into the m_detailUV array. - OUT.m_detailUv[0] = mul(MaterialSrg::m_detailUvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_detailUv[1] = mul(MaterialSrg::m_detailUvMatrix, float3(IN.m_uv1, 1.0)).xy; - - // Shadow coords will be calculated in the pixel shader in this case - bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset; - - VertexHelper(IN, OUT, worldPosition, skipShadowCoords); - - return OUT; -} - - -// ---------- Pixel Shader ---------- - -PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth) -{ - const float3 vertexNormal = normalize(IN.m_normal); - - // ------- Tangents & Bitangets ------- - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - - if ((o_parallax_feature_enabled && !o_enableSubsurfaceScattering) || o_normal_useTexture || (o_clearCoat_enabled && o_clearCoat_normal_useTexture) || o_detail_normal_useTexture) - { - PrepareGeneratedTangent(vertexNormal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - } - - // ------- Depth & Parallax ------- - - depth = IN.m_position.z; - - bool displacementIsClipped = false; - - // Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scatteirng is enabled - if(ShouldHandleParallax()) - { - // GetParallaxInput applies an tangent offset to the UV. We want to apply the same offset to the detailUv (note: this needs to be tested with content) - // The math is: offset = newUv - oldUv; detailUv += offset; - // This is the same as: detailUv -= oldUv; detailUv += newUv; - IN.m_detailUv[MaterialSrg::m_parallaxUvIndex] -= IN.m_uv[MaterialSrg::m_parallaxUvIndex]; - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - GetParallaxInput(vertexNormal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, IN.m_position.w, displacementIsClipped); - - // Apply second part of the offset to the detail UV (see comment above) - IN.m_detailUv[MaterialSrg::m_parallaxUvIndex] -= IN.m_uv[MaterialSrg::m_parallaxUvIndex]; - - // Adjust directional light shadow coorinates for parallax correction - if(o_parallax_enablePixelDepthOffset) - { - const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; - if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) - { - DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, vertexNormal, IN.m_shadowCoords); - } - } - } - - Surface surface; - surface.position = IN.m_worldPosition; - - // ------- Alpha & Clip ------- - - float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; - float2 opacityUv = IN.m_uv[MaterialSrg::m_opacityMapUvIndex]; - float alpha = GetAlphaInputAndClip(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUv, opacityUv, MaterialSrg::m_sampler, MaterialSrg::m_opacityFactor, o_opacity_source); - - // ------- Detail Layer Setup ------- - - const float2 detailUv = IN.m_detailUv[MaterialSrg::m_detail_allMapsUvIndex]; - - // When the detail maps and the detail blend mask are on the same UV, they both use the transformed detail UVs because they are 'attached' to each other - const float2 detailBlendMaskUv = (MaterialSrg::m_detail_blendMask_uvIndex == MaterialSrg::m_detail_allMapsUvIndex) ? - IN.m_detailUv[MaterialSrg::m_detail_blendMask_uvIndex] : - IN.m_uv[MaterialSrg::m_detail_blendMask_uvIndex]; - - const float detailLayerBlendFactor = GetDetailLayerBlendFactor( - MaterialSrg::m_detail_blendMask_texture, - MaterialSrg::m_sampler, - detailBlendMaskUv, - o_detail_blendMask_useTexture, - MaterialSrg::m_detail_blendFactor); - - // ------- Normal ------- - - float2 normalUv = IN.m_uv[MaterialSrg::m_normalMapUvIndex]; - float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms. - float detailLayerNormalFactor = MaterialSrg::m_detail_normal_factor * detailLayerBlendFactor; - surface.vertexNormal = vertexNormal; - surface.normal = GetDetailedNormalInputWS( - isFrontFace, IN.m_normal, - tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_normalFactor, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, uvMatrix, o_normal_useTexture, - tangents[MaterialSrg::m_detail_allMapsUvIndex], bitangents[MaterialSrg::m_detail_allMapsUvIndex], MaterialSrg::m_detail_normal_texture, MaterialSrg::m_sampler, detailUv, detailLayerNormalFactor, MaterialSrg::m_detail_normal_flipX, MaterialSrg::m_detail_normal_flipY, MaterialSrg::m_detailUvMatrix, o_detail_normal_useTexture); - - //--------------------- Base Color ---------------------- - - // [GFX TODO][ATOM-1761] Figure out how we want our base material to expect channels to be encoded, and apply that to the way we pack alpha. - - float detailLayerBaseColorFactor = MaterialSrg::m_detail_baseColor_factor * detailLayerBlendFactor; - - float3 baseColor = GetDetailedBaseColorInput( - MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, o_baseColor_useTexture, MaterialSrg::m_baseColor, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, - MaterialSrg::m_detail_baseColor_texture, MaterialSrg::m_sampler, detailUv, o_detail_baseColor_useTexture, detailLayerBaseColorFactor); - - if(o_parallax_highlightClipping && displacementIsClipped) - { - ApplyParallaxClippingHighlight(baseColor); - } - - // ------- Metallic ------- - - float metallic = 0; - if(!o_enableSubsurfaceScattering) // If subsurface scattering is enabled skip texture lookup for metallic, as this quantity won't be used anyway - { - float2 metallicUv = IN.m_uv[MaterialSrg::m_metallicMapUvIndex]; - metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); - } - - // ------- Specular ------- - - float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex]; - float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - - surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); - - // ------- Roughness ------- - - float2 roughnessUv = IN.m_uv[MaterialSrg::m_roughnessMapUvIndex]; - surface.roughnessLinear = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor, - MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture); - surface.CalculateRoughnessA(); - - // ------- Subsurface ------- - - float2 subsurfaceUv = IN.m_uv[MaterialSrg::m_subsurfaceScatteringInfluenceMapUvIndex]; - float surfaceScatteringFactor = GetSubsurfaceInput(MaterialSrg::m_subsurfaceScatteringInfluenceMap, MaterialSrg::m_sampler, subsurfaceUv, MaterialSrg::m_subsurfaceScatteringFactor); - - // ------- Transmission ------- - - float2 transmissionUv = IN.m_uv[MaterialSrg::m_transmissionThicknessMapUvIndex]; - float4 transmissionTintThickness = GeTransmissionInput(MaterialSrg::m_transmissionThicknessMap, MaterialSrg::m_sampler, transmissionUv, MaterialSrg::m_transmissionTintThickness); - surface.transmission.tint = transmissionTintThickness.rgb; - surface.transmission.thickness = transmissionTintThickness.w; - surface.transmission.transmissionParams = MaterialSrg::m_transmissionParams; - surface.transmission.scatterDistance = MaterialSrg::m_scatterDistance; - - // ------- Anisotropy ------- - - if (o_enableAnisotropy) - { - // Convert the angle from [0..1] = [0 .. 180 degrees] to radians [0 .. PI] - const float anisotropyAngle = MaterialSrg::m_anisotropicAngle * PI; - const float anisotropyFactor = MaterialSrg::m_anisotropicFactor; - surface.anisotropy.Init(surface.normal, IN.m_tangent, IN.m_bitangent, anisotropyAngle, anisotropyFactor, surface.roughnessA); - } - - // ------- Lighting Data ------- - - LightingData lightingData; - - // Light iterator - lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); - lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); - - // Directional light shadow coordinates - lightingData.shadowCoords = IN.m_shadowCoords; - - // ------- Emissive ------- - - float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex]; - lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture); - - // ------- Occlusion ------- - - lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); - lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture); - - // ------- Thin Object Light Transmission ------- - - // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection - lightingData.shrinkFactor = surface.transmission.transmissionParams.x; - - // Angle offset for subsurface scattering through thin objects - lightingData.transmissionNdLBias = surface.transmission.transmissionParams.y; - - // Attenuation applied to hide artifacts due to low-res shadow maps - lightingData.distanceAttenuation = surface.transmission.transmissionParams.z; - - // ------- Clearcoat ------- - - // [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags - if(o_clearCoat_feature_enabled) - { - if(o_clearCoat_enabled) - { - float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, IN.m_uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture, - MaterialSrg::m_clearCoatRoughnessMap, IN.m_uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture, - MaterialSrg::m_clearCoatNormalMap, IN.m_uv[MaterialSrg::m_clearCoatNormalMapUvIndex], IN.m_normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength, - uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex], - MaterialSrg::m_sampler, isFrontFace, - surface.clearCoat.factor, surface.clearCoat.roughness, surface.clearCoat.normal); - } - - // manipulate base layer f0 if clear coat is enabled - // modify base layer's normal incidence reflectance - // for the derivation of the following equation please refer to: - // https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification - float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0)); - surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor); - } - - // Diffuse and Specular response (used in IBL calculations) - lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); - lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; - - if(o_clearCoat_feature_enabled) - { - // Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04 - lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor); - } - - // ------- Multiscatter ------- - - lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation); - - // ------- Lighting Calculation ------- - - // Apply Decals - ApplyDecals(lightingData.tileIterator, surface); - - // Apply Direct Lighting - ApplyDirectLighting(surface, lightingData); - - // Apply Image Based Lighting (IBL) - ApplyIBL(surface, lightingData); - - // Finalize Lighting - lightingData.FinalizeLighting(surface.transmission.tint); - - PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); - - // ------- Opacity ------- - - if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) - { - // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. - // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface - // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor - // values close to 1.0, that indicates the absence of a surface entirely, so this effect should - // not apply. - float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; - alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor); - } - - // Note: lightingOutput rendertargets are not always used as named, particularly m_diffuseColor (target 0) and - // m_specularColor (target 1). Comments below describe the differences when appropriate. - - if (o_opacity_mode == OpacityMode::Blended) - { - // [GFX_TODO ATOM-13187] PbrLighting shouldn't be writing directly to render targets. It's confusing when - // specular is being added to diffuse just because we're calling render target 0 "diffuse". - - // For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular - // to be added on top of the diffuse, but then the diffuse must be pre-multiplied. - // It's done this way because surface transparency doesn't really change specular response (eg, glass). - - lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - - // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. - float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); - lightingOutput.m_diffuseColor.rgb += specular; - - lightingOutput.m_diffuseColor.w = alpha; - } - else if (o_opacity_mode == OpacityMode::TintedTransparent) - { - // See OpacityMode::Blended above for the basic method. TintedTransparent adds onto the above concept by supporting - // colored alpha. This is currently a very basic calculation that uses the baseColor as a multiplier with strength - // determined by the alpha. We'll modify this later to be more physically accurate and allow surface depth, - // absorption, and interior color to be specified. - // - // The technique uses dual source blending to allow two separate sources to be part of the blending equation - // even though ultimately only a single render target is being written to. m_diffuseColor is render target 0 and - // m_specularColor render target 1, and the blend mode is (dest * source1color) + (source * 1.0). - // - // This means that m_specularColor.rgb (source 1) is multiplied against the destination, then - // m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0. - - lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - - // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. - float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); - lightingOutput.m_diffuseColor.rgb += specular; - - lightingOutput.m_specularColor.rgb = baseColor * (1.0 - alpha); - } - else - { - // Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961 - uint factorAndQuality = dot(round(float2(saturate(surfaceScatteringFactor), MaterialSrg::m_subsurfaceScatteringQuality) * 255), float2(256, 1)); - lightingOutput.m_diffuseColor.w = factorAndQuality * (o_enableSubsurfaceScattering ? 1.0 : -1.0); - lightingOutput.m_scatterDistance = MaterialSrg::m_scatterDistance; - } - - return lightingOutput; -} - -ForwardPassOutputWithDepth EnhancedPbr_ForwardPassPS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - ForwardPassOutputWithDepth OUT; - float depth; - - PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); - - OUT.m_diffuseColor = lightingOutput.m_diffuseColor; - OUT.m_specularColor = lightingOutput.m_specularColor; - OUT.m_specularF0 = lightingOutput.m_specularF0; - OUT.m_albedo = lightingOutput.m_albedo; - OUT.m_normal = lightingOutput.m_normal; - OUT.m_scatterDistance = lightingOutput.m_scatterDistance; - OUT.m_depth = depth; - return OUT; -} - -[earlydepthstencil] -ForwardPassOutput EnhancedPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - ForwardPassOutput OUT; - float depth; - - PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); - - OUT.m_diffuseColor = lightingOutput.m_diffuseColor; - OUT.m_specularColor = lightingOutput.m_specularColor; - OUT.m_specularF0 = lightingOutput.m_specularF0; - OUT.m_albedo = lightingOutput.m_albedo; - OUT.m_normal = lightingOutput.m_normal; - OUT.m_scatterDistance = lightingOutput.m_scatterDistance; +#include "MaterialFunctions/EvaluateEnhancedSurface.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/EnhancedParallaxDepth.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardMaybeClip.azsli" +#include "MaterialFunctions/StandardTransformDetailUvs.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" - return OUT; -} +#include "EnhancedSurface_ForwardPass.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl index 0f2457fcd8..6c01a63a7c 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl @@ -16,85 +16,12 @@ #include "MaterialInputs/AlphaInput.azsli" #include "MaterialInputs/ParallaxInput.azsli" -struct VertexInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; -}; - -struct VertexOutput -{ - float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; -}; - -VertexOutput MainVS(VertexInput IN) -{ - const float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); - VertexOutput OUT; - - const float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz; - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0)); - // By design, only UV0 is allowed to apply transforms. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - - return OUT; -} - -struct PSDepthOutput -{ - float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, OUT.m_depth); - - OUT.m_depth += PdoShadowMapBias; - } - - // Clip Alpha - float2 baseColorUV = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; - float2 opacityUV = IN.m_uv[MaterialSrg::m_opacityMapUvIndex]; - float alpha = SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); - CheckClipping(alpha, MaterialSrg::m_opacityFactor); - - return OUT; -} +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetAlpha.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/ParallaxDepth.azsli" +#include "MaterialFunctions/StandardMaybeClip.azsli" + +#include "ShadowMap_WithPS.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl new file mode 100644 index 0000000000..ceb9379f28 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl @@ -0,0 +1,317 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +// SRGs +#include + +// Pass Output +#include + +// Utility +#include + +// Custom Surface & Lighting +#include + +// Decals +#include + +// ---------- Vertex Shader ---------- + +struct VSInput +{ + // Base fields (required by the template azsli file)... + float3 m_position : POSITION; + float3 m_normal : NORMAL; + float4 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + + // Extended fields (only referenced in this azsl file)... + float2 m_uv0 : UV0; + float2 m_uv1 : UV1; +}; + +struct VSOutput +{ + // Base fields (required by the template azsli file)... + precise linear centroid float4 m_position : SV_Position; + float3 m_normal: NORMAL; + float3 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + float3 m_worldPosition : UV0; + float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV5; + + // Extended fields (only referenced in this azsl file)... + float2 m_uv[UvSetCount] : UV1; + float2 m_detailUv[UvSetCount] : UV3; +}; + +VSOutput EnhancedPbr_ForwardPassVS(VSInput IN) +{ + VSOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + OUT.m_worldPosition = worldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + float2 uv[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uv, OUT.m_uv); + + float2 detailUv[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformDetailUvs(detailUv, OUT.m_detailUv); + + // Shadow coords will be calculated in the pixel shader in this case + bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + + // directional light shadow + const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; + if (o_enableShadows && !skipShadowCoords && shadowIndex < SceneSrg::m_directionalLightCount) + { + DirectionalLightShadow::GetShadowCoords( + shadowIndex, + worldPosition, + OUT.m_normal, + OUT.m_shadowCoords); + } + + return OUT; +} + + +// ---------- Pixel Shader ---------- + +PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth) +{ + const float3 vertexNormal = normalize(IN.m_normal); + + // ------- Tangents & Bitangets ------- + float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; + float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; + + if ((o_parallax_feature_enabled && !o_enableSubsurfaceScattering) || o_normal_useTexture || (o_clearCoat_enabled && o_clearCoat_normal_useTexture) || o_detail_normal_useTexture) + { + for (int i = 0; i != UvSetCount; ++i) + { + EvaluateTangentFrame( + IN.m_normal, + IN.m_worldPosition, + isFrontFace, + IN.m_uv[i], + i, + IN.m_tangent, + IN.m_bitangent, + tangents[i], + bitangents[i]); + } + } + + // ------- Depth & Parallax ------- + + depth = IN.m_position.z; + + bool displacementIsClipped = false; + + // Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scatteirng is enabled + if(ShouldHandleParallax()) + { + EnhancedSetPixelDepth( + IN.m_worldPosition, + IN.m_normal, + tangents, + bitangents, + IN.m_uv, + isFrontFace, + IN.m_detailUv, + IN.m_position.w, + depth, + displacementIsClipped); + + // Adjust directional light shadow coorinates for parallax correction + if(o_parallax_enablePixelDepthOffset) + { + const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; + if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) + { + DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, vertexNormal, IN.m_shadowCoords); + } + } + } + + Surface surface; + surface.vertexNormal = vertexNormal; + surface.position = IN.m_worldPosition; + + // ------- Alpha & Clip ------- + // TODO: this often invokes a separate sample of the base color texture which is wasteful + float alpha = GetAlpha(IN.m_uv); + MaybeClip(alpha, IN.m_uv); + + EvaluateEnhancedSurface(IN.m_normal, IN.m_uv, IN.m_detailUv, tangents, bitangents, isFrontFace, displacementIsClipped, surface); + + // ------- Lighting Data ------- + + LightingData lightingData; + + // Light iterator + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); + + // Directional light shadow coordinates + lightingData.shadowCoords = IN.m_shadowCoords; + + lightingData.emissiveLighting = surface.emissiveLighting; + lightingData.diffuseAmbientOcclusion = surface.diffuseAmbientOcclusion; + lightingData.specularOcclusion = surface.specularOcclusion; + + // Diffuse and Specular response (used in IBL calculations) + lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); + lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; + + // ------- Thin Object Light Transmission ------- + + // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection + lightingData.shrinkFactor = surface.transmission.transmissionParams.x; + + // Angle offset for subsurface scattering through thin objects + lightingData.transmissionNdLBias = surface.transmission.transmissionParams.y; + + // Attenuation applied to hide artifacts due to low-res shadow maps + lightingData.distanceAttenuation = surface.transmission.transmissionParams.z; + + if(o_clearCoat_feature_enabled) + { + // Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04 + lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor); + } + + // ------- Multiscatter ------- + + lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation); + + // ------- Lighting Calculation ------- + + // Apply Decals + ApplyDecals(lightingData.tileIterator, surface); + + // Apply Direct Lighting + ApplyDirectLighting(surface, lightingData); + + // Apply Image Based Lighting (IBL) + ApplyIBL(surface, lightingData); + + // Finalize Lighting + lightingData.FinalizeLighting(surface.transmission.tint); + + PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); + + // ------- Opacity ------- + + if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) + { + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; + alpha = lerp(fresnelAlpha, alpha, surface.opacityAffectsSpecularFactor); + } + + // Note: lightingOutput rendertargets are not always used as named, particularly m_diffuseColor (target 0) and + // m_specularColor (target 1). Comments below describe the differences when appropriate. + + if (o_opacity_mode == OpacityMode::Blended) + { + // [GFX_TODO ATOM-13187] PbrLighting shouldn't be writing directly to render targets. It's confusing when + // specular is being added to diffuse just because we're calling render target 0 "diffuse". + + // For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular + // to be added on top of the diffuse, but then the diffuse must be pre-multiplied. + // It's done this way because surface transparency doesn't really change specular response (eg, glass). + + lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; + + lightingOutput.m_diffuseColor.w = alpha; + } + else if (o_opacity_mode == OpacityMode::TintedTransparent) + { + // See OpacityMode::Blended above for the basic method. TintedTransparent adds onto the above concept by supporting + // colored alpha. This is currently a very basic calculation that uses the baseColor as a multiplier with strength + // determined by the alpha. We'll modify this later to be more physically accurate and allow surface depth, + // absorption, and interior color to be specified. + // + // The technique uses dual source blending to allow two separate sources to be part of the blending equation + // even though ultimately only a single render target is being written to. m_diffuseColor is render target 0 and + // m_specularColor render target 1, and the blend mode is (dest * source1color) + (source * 1.0). + // + // This means that m_specularColor.rgb (source 1) is multiplied against the destination, then + // m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0. + + lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; + + lightingOutput.m_specularColor.rgb = surface.baseColor * (1.0 - alpha); + } + else + { + // Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961 + uint factorAndQuality = dot(round(float2(saturate(surface.subsurfaceScatteringFactor), surface.subsurfaceScatteringQuality) * 255), float2(256, 1)); + lightingOutput.m_diffuseColor.w = factorAndQuality * (o_enableSubsurfaceScattering ? 1.0 : -1.0); + lightingOutput.m_scatterDistance = surface.scatterDistance; + } + + return lightingOutput; +} + +ForwardPassOutputWithDepth EnhancedPbr_ForwardPassPS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) +{ + ForwardPassOutputWithDepth OUT; + float depth; + + PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); + + OUT.m_diffuseColor = lightingOutput.m_diffuseColor; + OUT.m_specularColor = lightingOutput.m_specularColor; + OUT.m_specularF0 = lightingOutput.m_specularF0; + OUT.m_albedo = lightingOutput.m_albedo; + OUT.m_normal = lightingOutput.m_normal; + OUT.m_scatterDistance = lightingOutput.m_scatterDistance; + OUT.m_depth = depth; + return OUT; +} + +[earlydepthstencil] +ForwardPassOutput EnhancedPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) +{ + ForwardPassOutput OUT; + float depth; + + PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); + + OUT.m_diffuseColor = lightingOutput.m_diffuseColor; + OUT.m_specularColor = lightingOutput.m_specularColor; + OUT.m_specularF0 = lightingOutput.m_specularF0; + OUT.m_albedo = lightingOutput.m_albedo; + OUT.m_normal = lightingOutput.m_normal; + OUT.m_scatterDistance = lightingOutput.m_scatterDistance; + + return OUT; +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli new file mode 100644 index 0000000000..e89afd6f37 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli @@ -0,0 +1,41 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include "../MaterialInputs/ParallaxInput.azsli" +#include + + void EnhancedSetPixelDepth( + float3 worldPosition, + float3 normal, + float3 tangents[UvSetCount], + float3 bitangents[UvSetCount], + float2 uvs[UvSetCount], + bool isFrontFace, + inout float2 detailUv[UvSetCount], + inout float depthCS, + out float depth, + out bool isClipped) +{ + // GetParallaxInput applies an tangent offset to the UV. We want to apply the same offset to the detailUv (note: this needs to be tested with content) + // The math is: offset = newUv - oldUv; detailUv += offset; + // This is the same as: detailUv -= oldUv; detailUv += newUv; + detailUv[MaterialSrg::m_parallaxUvIndex] -= uvs[MaterialSrg::m_parallaxUvIndex]; + + float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); + + GetParallaxInput( + normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], + MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, + ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, + uvs[MaterialSrg::m_parallaxUvIndex], worldPosition, depth, depthCS, isClipped); + + // Apply second part of the offset to the detail UV (see comment above) + detailUv[MaterialSrg::m_parallaxUvIndex] -= uvs[MaterialSrg::m_parallaxUvIndex]; +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli new file mode 100644 index 0000000000..9cc3e05789 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli @@ -0,0 +1,149 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include "StandardGetAlpha.azsli" + +void EvaluateEnhancedSurface( + float3 normal, + float2 uvs[UvSetCount], + float2 detailUvs[UvSetCount], + float3 tangents[UvSetCount], + float3 bitangents[UvSetCount], + bool isFrontFace, + bool displacementIsClipped, + inout Surface surface) +{ + // ------- Detail Layer Setup ------- + + const float2 detailUv = detailUvs[MaterialSrg::m_detail_allMapsUvIndex]; + + // When the detail maps and the detail blend mask are on the same UV, they both use the transformed detail UVs because they are 'attached' to each other + const float2 detailBlendMaskUv = (MaterialSrg::m_detail_blendMask_uvIndex == MaterialSrg::m_detail_allMapsUvIndex) ? + detailUvs[MaterialSrg::m_detail_blendMask_uvIndex] : + uvs[MaterialSrg::m_detail_blendMask_uvIndex]; + + const float detailLayerBlendFactor = GetDetailLayerBlendFactor( + MaterialSrg::m_detail_blendMask_texture, + MaterialSrg::m_sampler, + detailBlendMaskUv, + o_detail_blendMask_useTexture, + MaterialSrg::m_detail_blendFactor); + + // ------- Normal ------- + + float2 normalUv = uvs[MaterialSrg::m_normalMapUvIndex]; + float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms. + float detailLayerNormalFactor = MaterialSrg::m_detail_normal_factor * detailLayerBlendFactor; + surface.normal = GetDetailedNormalInputWS( + isFrontFace, normal, + tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_normalFactor, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, uvMatrix, o_normal_useTexture, + tangents[MaterialSrg::m_detail_allMapsUvIndex], bitangents[MaterialSrg::m_detail_allMapsUvIndex], MaterialSrg::m_detail_normal_texture, MaterialSrg::m_sampler, detailUv, detailLayerNormalFactor, MaterialSrg::m_detail_normal_flipX, MaterialSrg::m_detail_normal_flipY, MaterialSrg::m_detailUvMatrix, o_detail_normal_useTexture); + + //--------------------- Base Color ---------------------- + + // [GFX TODO][ATOM-1761] Figure out how we want our base material to expect channels to be encoded, and apply that to the way we pack alpha. + + float detailLayerBaseColorFactor = MaterialSrg::m_detail_baseColor_factor * detailLayerBlendFactor; + float2 baseColorUv = uvs[MaterialSrg::m_baseColorMapUvIndex]; + + surface.baseColor = GetDetailedBaseColorInput( + MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, o_baseColor_useTexture, MaterialSrg::m_baseColor, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, + MaterialSrg::m_detail_baseColor_texture, MaterialSrg::m_sampler, detailUv, o_detail_baseColor_useTexture, detailLayerBaseColorFactor); + + if(o_parallax_highlightClipping && displacementIsClipped) + { + ApplyParallaxClippingHighlight(surface.baseColor); + } + + // ------- Metallic ------- + + surface.metallic = 0; + if(!o_enableSubsurfaceScattering) // If subsurface scattering is enabled skip texture lookup for metallic, as this quantity won't be used anyway + { + float2 metallicUv = uvs[MaterialSrg::m_metallicMapUvIndex]; + surface.metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); + } + + // ------- Specular ------- + + float2 specularUv = uvs[MaterialSrg::m_specularF0MapUvIndex]; + float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); + + surface.SetAlbedoAndSpecularF0(specularF0Factor); + + // ------- Roughness ------- + + float2 roughnessUv = uvs[MaterialSrg::m_roughnessMapUvIndex]; + surface.roughnessLinear = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor, + MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture); + surface.CalculateRoughnessA(); + + // ------- Subsurface ------- + + float2 subsurfaceUv = uvs[MaterialSrg::m_subsurfaceScatteringInfluenceMapUvIndex]; + surface.subsurfaceScatteringFactor = GetSubsurfaceInput(MaterialSrg::m_subsurfaceScatteringInfluenceMap, MaterialSrg::m_sampler, subsurfaceUv, MaterialSrg::m_subsurfaceScatteringFactor); + surface.subsurfaceScatteringQuality = MaterialSrg::m_subsurfaceScatteringQuality; + surface.scatterDistance = MaterialSrg::m_scatterDistance; + + // ------- Transmission ------- + + float2 transmissionUv = uvs[MaterialSrg::m_transmissionThicknessMapUvIndex]; + float4 transmissionTintThickness = GeTransmissionInput(MaterialSrg::m_transmissionThicknessMap, MaterialSrg::m_sampler, transmissionUv, MaterialSrg::m_transmissionTintThickness); + surface.transmission.tint = transmissionTintThickness.rgb; + surface.transmission.thickness = transmissionTintThickness.w; + surface.transmission.transmissionParams = MaterialSrg::m_transmissionParams; + surface.transmission.scatterDistance = MaterialSrg::m_scatterDistance; + + // ------- Anisotropy ------- + + if (o_enableAnisotropy) + { + // Convert the angle from [0..1] = [0 .. 180 degrees] to radians [0 .. PI] + const float anisotropyAngle = MaterialSrg::m_anisotropicAngle * PI; + const float anisotropyFactor = MaterialSrg::m_anisotropicFactor; + surface.anisotropy.Init(surface.normal, tangents[0], bitangents[0], anisotropyAngle, anisotropyFactor, surface.roughnessA); + } + + // ------- Emissive ------- + + float2 emissiveUv = uvs[MaterialSrg::m_emissiveMapUvIndex]; + surface.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture); + + // ------- Occlusion ------- + + surface.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvs[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); + surface.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, uvs[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture); + + // ------- Clearcoat ------- + + // [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags + if(o_clearCoat_feature_enabled) + { + if(o_clearCoat_enabled) + { + float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, uvs[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture, + MaterialSrg::m_clearCoatRoughnessMap, uvs[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture, + MaterialSrg::m_clearCoatNormalMap, uvs[MaterialSrg::m_clearCoatNormalMapUvIndex], normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength, + uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex], + MaterialSrg::m_sampler, isFrontFace, + surface.clearCoat.factor, surface.clearCoat.roughness, surface.clearCoat.normal); + } + + // manipulate base layer f0 if clear coat is enabled + // modify base layer's normal incidence reflectance + // for the derivation of the following equation please refer to: + // https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification + float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0)); + surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor); + } + + surface.opacityAffectsSpecularFactor = MaterialSrg::m_opacityAffectsSpecularFactor; +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli new file mode 100644 index 0000000000..54a4a2462a --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli @@ -0,0 +1,95 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include "StandardGetAlpha.azsli" + +void EvaluateStandardSurface( + float3 normal, + float2 uv[UvSetCount], + float3 tangents[UvSetCount], + float3 bitangents[UvSetCount], + bool isFrontFace, + bool displacementIsClipped, + inout Surface surface) +{ + // ------- Normal ------- + + float2 normalUv = uv[MaterialSrg::m_normalMapUvIndex]; + float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms. + surface.normal = GetNormalInputWS(MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, isFrontFace, normal, + tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], uvMatrix, o_normal_useTexture, MaterialSrg::m_normalFactor); + + // ------- Base Color ------- + + float2 baseColorUv = uv[MaterialSrg::m_baseColorMapUvIndex]; + float3 sampledColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor.rgb, o_baseColor_useTexture); + surface.baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); + + if(o_parallax_highlightClipping && displacementIsClipped) + { + ApplyParallaxClippingHighlight(surface.baseColor); + } + + // ------- Metallic ------- + + float2 metallicUv = uv[MaterialSrg::m_metallicMapUvIndex]; + surface.metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); + + // ------- Specular ------- + + float2 specularUv = uv[MaterialSrg::m_specularF0MapUvIndex]; + float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); + + surface.SetAlbedoAndSpecularF0(specularF0Factor); + + // ------- Roughness ------- + + float2 roughnessUv = uv[MaterialSrg::m_roughnessMapUvIndex]; + surface.roughnessLinear = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor, + MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture); + surface.CalculateRoughnessA(); + + // ------- Emissive ------- + + float2 emissiveUv = uv[MaterialSrg::m_emissiveMapUvIndex]; + surface.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture); + + // ------- Occlusion ------- + + surface.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); + surface.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture); + + // ------- Clearcoat ------- + + // [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags + if(o_clearCoat_feature_enabled) + { + if(o_clearCoat_enabled) + { + float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture, + MaterialSrg::m_clearCoatRoughnessMap, uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture, + MaterialSrg::m_clearCoatNormalMap, uv[MaterialSrg::m_clearCoatNormalMapUvIndex], normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength, + uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex], + MaterialSrg::m_sampler, isFrontFace, + surface.clearCoat.factor, surface.clearCoat.roughness, surface.clearCoat.normal); + } + + // manipulate base layer f0 if clear coat is enabled + // modify base layer's normal incidence reflectance + // for the derivation of the following equation please refer to: + // https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification + float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0)); + surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor); + } + + // ------- Opacity ------- + surface.opacityAffectsSpecularFactor = MaterialSrg::m_opacityAffectsSpecularFactor; +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli new file mode 100644 index 0000000000..2aad5f257d --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +// The built-in tangent frame evaluation forwards the tangent frame interpolanted from the vertex +// data streams for UV-index 0. For UV-index 1, the tangent frame is computed from UV surface gradients. +void EvaluateTangentFrame( + float3 normal, + float3 worldPosition, + bool isFrontFace, + float2 uv, + int uvIndex, + // The input tangent and bitangent vectors are optional and used to forward data from interpolants + float3 IN_tangent, + float3 IN_bitangent, + float3 OUT_tangent, + float3 OUT_bitangent) +{ + if (DrawSrg::GetTangentAtUv(uvIndex) == 0) + { + OUT_tangent = IN_tangent; + OUT_bitangent = IN_bitangent; + } + else + { + SurfaceGradientNormalMapping_Init(normal, worldPosition, !isFrontFace); \ + SurfaceGradientNormalMapping_GenerateTB(uv, OUT_tangent, OUT_bitangent); \ + } +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli new file mode 100644 index 0000000000..5ee527b9a4 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli @@ -0,0 +1,35 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include "../MaterialInputs/ParallaxInput.azsli" +#include + + void MultilayerSetPixelDepth( + float blendMask, + float3 worldPosition, + float3 normal, + float3 tangents[UvSetCount], + float3 bitangents[UvSetCount], + float2 uvs[UvSetCount], + bool isFrontFace, + out float depth) +{ + s_blendMaskFromVertexStream = blendMask; + + float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); + + float parallaxOverallOffset = MaterialSrg::m_displacementMax; + float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin; + GetParallaxInput( + normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], + parallaxOverallFactor, parallaxOverallOffset, + ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, + uvs[MaterialSrg::m_parallaxUvIndex], worldPosition, depth); +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli new file mode 100644 index 0000000000..0298656375 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli @@ -0,0 +1,51 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include "../MaterialInputs/ParallaxInput.azsli" +#include + + void SetPixelDepth( + inout float3 worldPosition, + float3 normal, + float3 tangents[UvSetCount], + float3 bitangents[UvSetCount], + inout float2 uvs[UvSetCount], + bool isFrontFace, + inout float depthNDC) +{ + float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); + + GetParallaxInput( + normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], + MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, + ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, + uvs[MaterialSrg::m_parallaxUvIndex], worldPosition, depthNDC); +} + + void SetPixelDepth( + inout float3 worldPosition, + float3 normal, + float3 tangents[UvSetCount], + float3 bitangents[UvSetCount], + inout float2 uvs[UvSetCount], + bool isFrontFace, + inout float depthCS, + inout float depthNDC, + out bool isClipped) +{ + float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); + + GetParallaxInput( + normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], + MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, + ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, + uvs[MaterialSrg::m_parallaxUvIndex], worldPosition, depthNDC, depthCS, isClipped); +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli new file mode 100644 index 0000000000..90f8e417e1 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli @@ -0,0 +1,17 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include "../MaterialInputs/AlphaInput.azsli" + +float GetAlpha(float2 uvs[UvSetCount]) +{ + // Alpha + float2 baseColorUV = uvs[MaterialSrg::m_baseColorMapUvIndex]; + float2 opacityUV = uvs[MaterialSrg::m_opacityMapUvIndex]; + return MaterialSrg::m_opacityFactor * SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli new file mode 100644 index 0000000000..b79b5b3418 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli @@ -0,0 +1,12 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +float3x3 GetNormalToWorld() +{ + return ObjectSrg::GetWorldMatrixInverseTranspose(); +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli new file mode 100644 index 0000000000..435326215b --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli @@ -0,0 +1,12 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +float4x4 GetObjectToWorld() +{ + return ObjectSrg::GetWorldMatrix(); +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli new file mode 100644 index 0000000000..2dabf9ba1e --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli @@ -0,0 +1,14 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +void MaybeClip(float alpha, float2 uvs[UvSetCount]) +{ + CheckClipping(alpha, MaterialSrg::m_opacityFactor); +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli new file mode 100644 index 0000000000..60ab575a2d --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli @@ -0,0 +1,18 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +void TransformDetailUvs(in float2 IN[UvSetCount], out float2 OUT[UvSetCount]) +{ + // Our standard practice is to only transform the first UV as that's the one we expect to be used for + // tiling. But for detail maps you could actually use either UV stream for tiling. There is no concern about applying + // the same transform to both UV sets because the detail map feature forces the same UV set to be used for all detail maps. + // Note we might be able to combine these into a single UV similar to what Skin.materialtype does, + // but we would need to address how it works with the parallax code below that indexes into the m_detailUV array. + OUT[0] = mul(MaterialSrg::m_detailUvMatrix, float3(IN[0], 1.0)).xy; + OUT[1] = mul(MaterialSrg::m_detailUvMatrix, float3(IN[1], 1.0)).xy; +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli new file mode 100644 index 0000000000..dd77f99ac3 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli @@ -0,0 +1,14 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +void TransformUvs(in float2 IN[UvSetCount], out float2 OUT[UvSetCount]) +{ + // By design, only UV0 is allowed to apply transforms. + OUT[0] = mul(MaterialSrg::m_uvMatrix, float3(IN[0], 1.0)).xy; + OUT[1] = IN[1]; +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl new file mode 100644 index 0000000000..dd0665efe7 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl @@ -0,0 +1,127 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +struct VertexInput +{ + float3 m_position : POSITION; + float2 m_uv0 : UV0; + float2 m_uv1 : UV1; + + // only used for parallax depth calculation + float3 m_normal : NORMAL; + float4 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + +#ifdef MULTILAYER + // This gets set automatically by the system at runtime only if it's available. + // There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available. + // (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention). + // [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream. + float4 m_optional_blendMask : COLOR0; +#endif +}; + +struct VertexOutput +{ + // "centroid" is needed for SV_Depth to compile + linear centroid float4 m_position : SV_Position; + float2 m_uv[UvSetCount] : UV1; + + // only used for parallax depth calculation + float3 m_normal : NORMAL; + float3 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + float3 m_worldPosition : UV0; + +#ifdef MULTILAYER + float3 m_blendMask : UV3; +#endif +}; + +VertexOutput MainVS(VertexInput IN) +{ + const float4x4 objectToWorld = GetObjectToWorld(); + VertexOutput OUT; + + const float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0)); + + float2 uv[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uv, OUT.m_uv); + + if(ShouldHandleParallaxInDepthShaders()) + { + OUT.m_worldPosition = worldPosition.xyz; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + } + +#ifdef MULTILAYER + if(o_blendMask_isBound) + { + OUT.m_blendMask = IN.m_optional_blendMask.rgb; + } + else + { + OUT.m_blendMask = float3(0,0,0); + } +#endif + + return OUT; +} + +struct PSDepthOutput +{ + float m_depth : SV_Depth; +}; + +PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) +{ + PSDepthOutput OUT; + + OUT.m_depth = IN.m_position.z; + + if(ShouldHandleParallaxInDepthShaders()) + { + float3 tangents[UvSetCount] = { IN.m_tangent, IN.m_tangent }; + float3 bitangents[UvSetCount] = { IN.m_bitangent, IN.m_bitangent }; + + for (int i = 0; i != UvSetCount; ++i) + { + EvaluateTangentFrame( + IN.m_normal, + IN.m_worldPosition, + isFrontFace, + IN.m_uv[i], + i, + IN.m_tangent, + IN.m_bitangent, + tangents[i], + bitangents[i]); + } + +#ifdef MULTILAYER + MultilayerSetPixelDepth(IN.m_blendMask, IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); +#else + SetPixelDepth(IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); +#endif + + OUT.m_depth += PdoShadowMapBias; + } + +#ifndef MULTILAYER + float alpha = GetAlpha(IN.m_uv); + MaybeClip(alpha, IN.m_uv); +#endif + + return OUT; +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl index 7875457489..d1a488ec0a 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl @@ -21,104 +21,11 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "./StandardMultilayerPBR_Common.azsli" -struct VSInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - - // This gets set automatically by the system at runtime only if it's available. - // There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available. - // (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention). - // [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream. - float4 m_optional_blendMask : COLOR0; -}; - -struct VSDepthOutput -{ - precise linear centroid float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; - float3 m_blendMask : UV3; -}; - -VSDepthOutput MainVS(VSInput IN) -{ - VSDepthOutput OUT; - - float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); - float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); - - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); - - // By design, only UV0 is allowed to apply transforms. - // Note there are additional UV transforms that happen for each layer, but we defer that step to the pixel shader to avoid bloating the vertex output buffer. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - - if(o_blendMask_isBound) - { - OUT.m_blendMask = IN.m_optional_blendMask.rgb; - } - else - { - OUT.m_blendMask = float3(0,0,0); - } - - return OUT; -} - -struct PSDepthOutput -{ - precise float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - - s_blendMaskFromVertexStream = IN.m_blendMask; - - float depth; - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - float parallaxOverallOffset = MaterialSrg::m_displacementMax; - float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin; - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth); - - OUT.m_depth = depth; - } - - return OUT; -} +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/StandardTransformUVs.azsli" +#include "MaterialFunctions/MultilayerParallaxDepth.azsli" + +#define MULTILAYER +#include "DepthPass_WithPS.azsl" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index 3617b7fb04..2fe9990862 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -450,16 +450,16 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Combine Albedo, roughness, specular, roughness --------- - float3 baseColor = BlendLayers(lightingInputLayer1.m_baseColor, lightingInputLayer2.m_baseColor, lightingInputLayer3.m_baseColor, blendWeights); - float3 specularF0Factor = BlendLayers(lightingInputLayer1.m_specularF0Factor, lightingInputLayer2.m_specularF0Factor, lightingInputLayer3.m_specularF0Factor, blendWeights); - float3 metallic = BlendLayers(lightingInputLayer1.m_metallic, lightingInputLayer2.m_metallic, lightingInputLayer3.m_metallic, blendWeights); + surface.baseColor = BlendLayers(lightingInputLayer1.m_baseColor, lightingInputLayer2.m_baseColor, lightingInputLayer3.m_baseColor, blendWeights); + float specularF0Factor = BlendLayers(lightingInputLayer1.m_specularF0Factor, lightingInputLayer2.m_specularF0Factor, lightingInputLayer3.m_specularF0Factor, blendWeights); + surface.metallic = BlendLayers(lightingInputLayer1.m_metallic, lightingInputLayer2.m_metallic, lightingInputLayer3.m_metallic, blendWeights); if(o_parallax_highlightClipping && displacementIsClipped) { - ApplyParallaxClippingHighlight(baseColor); + ApplyParallaxClippingHighlight(surface.baseColor); } - surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); + surface.SetAlbedoAndSpecularF0(specularF0Factor); surface.roughnessLinear = BlendLayers(lightingInputLayer1.m_roughness, lightingInputLayer2.m_roughness, lightingInputLayer3.m_roughness, blendWeights); surface.CalculateRoughnessA(); diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl index 45d8ed94b3..84b44512f0 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ - + #include #include #include @@ -21,103 +21,11 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "StandardMultilayerPBR_Common.azsli" -struct VertexInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - - // This gets set automatically by the system at runtime only if it's available. - // There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available. - // (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention). - // [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream. - float4 m_optional_blendMask : COLOR0; -}; - -struct VertexOutput -{ - float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; - float3 m_blendMask : UV3; -}; - -VertexOutput MainVS(VertexInput IN) -{ - const float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); - VertexOutput OUT; - - const float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz; - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0)); - - // By design, only UV0 is allowed to apply transforms. - // Note there are additional UV transforms that happen for each layer, but we defer that step to the pixel shader to avoid bloating the vertex output buffer. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - - if(o_blendMask_isBound) - { - OUT.m_blendMask = IN.m_optional_blendMask.rgb; - } - else - { - OUT.m_blendMask = float3(0,0,0); - } - - return OUT; -} - -struct PSDepthOutput -{ - float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - - s_blendMaskFromVertexStream = IN.m_blendMask; - - float depthNDC; - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - float parallaxOverallOffset = MaterialSrg::m_displacementMax; - float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin; - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC); +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/MultilayerParallaxDepth.azsli" - OUT.m_depth = depthNDC; - } - - return OUT; -} +#define MULTILAYER +#include "ShadowMap_WithPS.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl index 04fd104407..fe46d9bfba 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl @@ -8,91 +8,13 @@ #include "./StandardPBR_Common.azsli" #include -#include -#include -#include "MaterialInputs/AlphaInput.azsli" -#include "MaterialInputs/ParallaxInput.azsli" +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetAlpha.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" +#include "MaterialFunctions/ParallaxDepth.azsli" +#include "MaterialFunctions/StandardMaybeClip.azsli" -struct VSInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; -}; - -struct VSDepthOutput -{ - // "centroid" is needed for SV_Depth to compile - precise linear centroid float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; -}; - -VSDepthOutput MainVS(VSInput IN) -{ - VSDepthOutput OUT; - - float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); - float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); - - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); - // By design, only UV0 is allowed to apply transforms. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - return OUT; -} - -struct PSDepthOutput -{ - precise float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, OUT.m_depth); - } - - // Alpha - float2 baseColorUV = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; - float2 opacityUV = IN.m_uv[MaterialSrg::m_opacityMapUvIndex]; - float alpha = SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); - - CheckClipping(alpha, MaterialSrg::m_opacityFactor); - - return OUT; -} +#include "DepthPass_WithPS.azsl" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index b99ea734af..1a5e92b1d3 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -10,23 +10,7 @@ #include "StandardPBR_Common.azsli" -// SRGs #include -#include - -// Pass Output -#include - -// Utility -#include -#include - -// Custom Surface & Lighting -#include - -// Decals -#include - // ---------- Material Parameters ---------- @@ -43,320 +27,12 @@ COMMON_OPTIONS_EMISSIVE() // Alpha #include "MaterialInputs/AlphaInput.azsli" -// ---------- Vertex Shader ---------- - -struct VSInput -{ - // Base fields (required by the template azsli file)... - float3 m_position : POSITION; - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - - // Extended fields (only referenced in this azsl file)... - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; -}; - -struct VSOutput -{ - // Base fields (required by the template azsli file)... - // "centroid" is needed for SV_Depth to compile - precise linear centroid float4 m_position : SV_Position; - float3 m_normal: NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; - float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV3; - - // Extended fields (only referenced in this azsl file)... - float2 m_uv[UvSetCount] : UV1; -}; - -#include - -VSOutput StandardPbr_ForwardPassVS(VSInput IN) -{ - VSOutput OUT; - - float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz; - - // By design, only UV0 is allowed to apply transforms. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - // Shadow coords will be calculated in the pixel shader in this case - bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset; - - VertexHelper(IN, OUT, worldPosition, skipShadowCoords); - - return OUT; -} - - -// ---------- Pixel Shader ---------- - -PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depthNDC) -{ - const float3 vertexNormal = normalize(IN.m_normal); - - // ------- Tangents & Bitangets ------- - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - - if (ShouldHandleParallax() || o_normal_useTexture || (o_clearCoat_enabled && o_clearCoat_normal_useTexture)) - { - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - } - - // ------- Depth & Parallax ------- - - depthNDC = IN.m_position.z; - - bool displacementIsClipped = false; - - if(ShouldHandleParallax()) - { - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC, IN.m_position.w, displacementIsClipped); - - // Adjust directional light shadow coordinates for parallax correction - if(o_parallax_enablePixelDepthOffset) - { - const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; - if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) - { - DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, vertexNormal, IN.m_shadowCoords); - } - } - } - - Surface surface; - surface.position = IN.m_worldPosition.xyz; - - // ------- Alpha & Clip ------- - - float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; - float2 opacityUv = IN.m_uv[MaterialSrg::m_opacityMapUvIndex]; - float alpha = GetAlphaInputAndClip(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUv, opacityUv, MaterialSrg::m_sampler, MaterialSrg::m_opacityFactor, o_opacity_source); - - // ------- Normal ------- - - float2 normalUv = IN.m_uv[MaterialSrg::m_normalMapUvIndex]; - float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms. - surface.vertexNormal = vertexNormal; - surface.normal = GetNormalInputWS(MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, isFrontFace, IN.m_normal, - tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], uvMatrix, o_normal_useTexture, MaterialSrg::m_normalFactor); - - // ------- Base Color ------- - - float3 sampledColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor.rgb, o_baseColor_useTexture); - float3 baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); - - if(o_parallax_highlightClipping && displacementIsClipped) - { - ApplyParallaxClippingHighlight(baseColor); - } - - // ------- Metallic ------- - - float2 metallicUv = IN.m_uv[MaterialSrg::m_metallicMapUvIndex]; - float metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); - - // ------- Specular ------- - - float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex]; - float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - - surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); - - // ------- Roughness ------- - - float2 roughnessUv = IN.m_uv[MaterialSrg::m_roughnessMapUvIndex]; - surface.roughnessLinear = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor, - MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture); - surface.CalculateRoughnessA(); - - // ------- Lighting Data ------- - - LightingData lightingData; - - // Light iterator - lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); - lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); - - // Directional light shadow coordinates - lightingData.shadowCoords = IN.m_shadowCoords; - - // ------- Emissive ------- - - float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex]; - lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture); - - // ------- Occlusion ------- - - lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); - lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture); - - // ------- Clearcoat ------- - - // [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags - if(o_clearCoat_feature_enabled) - { - if(o_clearCoat_enabled) - { - float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, IN.m_uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture, - MaterialSrg::m_clearCoatRoughnessMap, IN.m_uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture, - MaterialSrg::m_clearCoatNormalMap, IN.m_uv[MaterialSrg::m_clearCoatNormalMapUvIndex], IN.m_normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength, - uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex], - MaterialSrg::m_sampler, isFrontFace, - surface.clearCoat.factor, surface.clearCoat.roughness, surface.clearCoat.normal); - } - - // manipulate base layer f0 if clear coat is enabled - // modify base layer's normal incidence reflectance - // for the derivation of the following equation please refer to: - // https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification - float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0)); - surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor); - } - - // Diffuse and Specular response (used in IBL calculations) - lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); - lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; - - if(o_clearCoat_feature_enabled) - { - // Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04 - lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor); - } - - // ------- Multiscatter ------- - - lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation); - - // ------- Lighting Calculation ------- - - // Apply Decals - ApplyDecals(lightingData.tileIterator, surface); - - // Apply Direct Lighting - ApplyDirectLighting(surface, lightingData); - - // Apply Image Based Lighting (IBL) - ApplyIBL(surface, lightingData); - - // Finalize Lighting - lightingData.FinalizeLighting(); - - PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); - - // ------- Opacity ------- - - if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) - { - // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. - // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface - // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor - // values close to 1.0, that indicates the absence of a surface entirely, so this effect should - // not apply. - float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; - alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor); - } - - if (o_opacity_mode == OpacityMode::Blended) - { - // [GFX_TODO ATOM-13187] PbrLighting shouldn't be writing directly to render targets. It's confusing when - // specular is being added to diffuse just because we're calling render target 0 "diffuse". - - // For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular - // to be added on top of the diffuse, but then the diffuse must be pre-multiplied. - // It's done this way because surface transparency doesn't really change specular response (eg, glass). - - lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - - // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. - float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); - lightingOutput.m_diffuseColor.rgb += specular; - - lightingOutput.m_diffuseColor.w = alpha; - } - else if (o_opacity_mode == OpacityMode::TintedTransparent) - { - // See OpacityMode::Blended above for the basic method. TintedTransparent adds onto the above concept by supporting - // colored alpha. This is currently a very basic calculation that uses the baseColor as a multiplier with strength - // determined by the alpha. We'll modify this later to be more physically accurate and allow surface depth, - // absorption, and interior color to be specified. - // - // The technique uses dual source blending to allow two separate sources to be part of the blending equation - // even though ultimately only a single render target is being written to. m_diffuseColor is render target 0 and - // m_specularColor render target 1, and the blend mode is (dest * source1color) + (source * 1.0). - // - // This means that m_specularColor.rgb (source 1) is multiplied against the destination, then - // m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0. - - lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - - // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. - float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); - lightingOutput.m_diffuseColor.rgb += specular; - - lightingOutput.m_specularColor.rgb = baseColor * (1.0 - alpha); - } - else - { - lightingOutput.m_diffuseColor.w = -1; // Disable subsurface scattering - } - - return lightingOutput; -} - -ForwardPassOutputWithDepth StandardPbr_ForwardPassPS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - ForwardPassOutputWithDepth OUT; - float depth; - - PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); - -#ifdef UNIFIED_FORWARD_OUTPUT - OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb; - OUT.m_color.a = lightingOutput.m_diffuseColor.a; - OUT.m_depth = depth; -#else - OUT.m_diffuseColor = lightingOutput.m_diffuseColor; - OUT.m_specularColor = lightingOutput.m_specularColor; - OUT.m_specularF0 = lightingOutput.m_specularF0; - OUT.m_albedo = lightingOutput.m_albedo; - OUT.m_normal = lightingOutput.m_normal; - OUT.m_depth = depth; -#endif - return OUT; -} - -[earlydepthstencil] -ForwardPassOutput StandardPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - ForwardPassOutput OUT; - float depth; - - PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); +#include "MaterialFunctions/EvaluateStandardSurface.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/ParallaxDepth.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardMaybeClip.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" -#ifdef UNIFIED_FORWARD_OUTPUT - OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb; - OUT.m_color.a = lightingOutput.m_diffuseColor.a; -#else - OUT.m_diffuseColor = lightingOutput.m_diffuseColor; - OUT.m_specularColor = lightingOutput.m_specularColor; - OUT.m_specularF0 = lightingOutput.m_specularF0; - OUT.m_albedo = lightingOutput.m_albedo; - OUT.m_normal = lightingOutput.m_normal; -#endif - return OUT; -} +#include "StandardSurface_ForwardPass.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl index 02f1cd0389..e8aeb20871 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl @@ -9,93 +9,16 @@ #include #include "StandardPBR_Common.azsli" #include -#include -#include -#include #include "MaterialInputs/AlphaInput.azsli" #include "MaterialInputs/ParallaxInput.azsli" -struct VertexInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetAlpha.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/ParallaxDepth.azsli" +#include "MaterialFunctions/StandardMaybeClip.azsli" - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; -}; - -struct VertexOutput -{ - // "centroid" is needed for SV_Depth to compile - linear centroid float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; -}; - -VertexOutput MainVS(VertexInput IN) -{ - const float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); - VertexOutput OUT; - - const float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz; - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0)); - // By design, only UV0 is allowed to apply transforms. - OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; - OUT.m_uv[1] = IN.m_uv1; - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - - return OUT; -} - -struct PSDepthOutput -{ - float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz }; - float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz }; - PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents); - - float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); - - GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, - ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, OUT.m_depth); - - OUT.m_depth += PdoShadowMapBias; - } - - // Alpha - float2 baseColorUV = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; - float2 opacityUV = IN.m_uv[MaterialSrg::m_opacityMapUvIndex]; - float alpha = SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); - - CheckClipping(alpha, MaterialSrg::m_opacityFactor); - - return OUT; -} +#include "ShadowMap_WithPS.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl new file mode 100644 index 0000000000..1d3fa29991 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl @@ -0,0 +1,306 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +// Pass Output +#include + +// Utility +#include +#include + +// Custom Surface & Lighting +#include + +// Decals +#include + + +// ---------- Vertex Shader ---------- + +struct VSInput +{ + // Base fields (required by the template azsli file)... + float3 m_position : POSITION; + float3 m_normal : NORMAL; + float4 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + + // Extended fields (only referenced in this azsl file)... + float2 m_uv0 : UV0; + float2 m_uv1 : UV1; +}; + +struct VSOutput +{ + // Base fields (required by the template azsli file)... + // "centroid" is needed for SV_Depth to compile + precise linear centroid float4 m_position : SV_Position; + float3 m_normal: NORMAL; + float3 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + float3 m_worldPosition : UV0; + float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV3; + + // Extended fields (only referenced in this azsl file)... + float2 m_uv[UvSetCount] : UV1; +}; + +#include + +VSOutput StandardPbr_ForwardPassVS(VSInput IN) +{ + VSOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + OUT.m_worldPosition = worldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + float2 uvs[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uvs, OUT.m_uv); + + // Shadow coords will be calculated in the pixel shader in this case + bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + + // directional light shadow + const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; + if (o_enableShadows && !skipShadowCoords && shadowIndex < SceneSrg::m_directionalLightCount) + { + DirectionalLightShadow::GetShadowCoords( + shadowIndex, + worldPosition, + OUT.m_normal, + OUT.m_shadowCoords); + } + + return OUT; +} + + +// ---------- Pixel Shader ---------- + +PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depthNDC) +{ + const float3 vertexNormal = normalize(IN.m_normal); + + // ------- Tangents & Bitangents ------- + float3 tangents[UvSetCount] = { IN.m_tangent, IN.m_tangent }; + float3 bitangents[UvSetCount] = { IN.m_bitangent, IN.m_bitangent }; + + if (ShouldHandleParallax() || o_normal_useTexture || (o_clearCoat_enabled && o_clearCoat_normal_useTexture)) + { + for (int i = 0; i != UvSetCount; ++i) + { + EvaluateTangentFrame( + IN.m_normal, + IN.m_worldPosition, + isFrontFace, + IN.m_uv[i], + i, + IN.m_tangent, + IN.m_bitangent, + tangents[i], + bitangents[i]); + } + } + + // ------- Depth & Parallax ------- + + depthNDC = IN.m_position.z; + bool displacementIsClipped = false; + + if(ShouldHandleParallax()) + { + SetPixelDepth( + IN.m_worldPosition, + IN.m_normal, + tangents, + bitangents, + IN.m_uv, + isFrontFace, + IN.m_position.w, + depthNDC, + displacementIsClipped); + + // Adjust directional light shadow coordinates for parallax correction + if(o_parallax_enablePixelDepthOffset) + { + const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; + if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) + { + DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, vertexNormal, IN.m_shadowCoords); + } + } + } + + Surface surface; + surface.vertexNormal = vertexNormal; + surface.position = IN.m_worldPosition.xyz; + + // ------- Alpha & Clip ------- + // TODO: this often invokes a separate sample of the base color texture which is wasteful + float alpha = GetAlpha(IN.m_uv); + MaybeClip(alpha, IN.m_uv); + + EvaluateStandardSurface(IN.m_normal, IN.m_uv, tangents, bitangents, isFrontFace, displacementIsClipped, surface); + + // ------- Lighting Data ------- + + LightingData lightingData; + + // Light iterator + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); + + // Directional light shadow coordinates + lightingData.shadowCoords = IN.m_shadowCoords; + + // Surface lighting properties + lightingData.emissiveLighting = surface.emissiveLighting; + lightingData.diffuseAmbientOcclusion = surface.diffuseAmbientOcclusion; + lightingData.specularOcclusion = surface.specularOcclusion; + + // Diffuse and Specular response (used in IBL calculations) + lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); + lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; + + if(o_clearCoat_feature_enabled) + { + // Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04 + lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor); + } + + // ------- Multiscatter ------- + + lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation); + + // ------- Lighting Calculation ------- + + // Apply Decals + ApplyDecals(lightingData.tileIterator, surface); + + // Apply Direct Lighting + ApplyDirectLighting(surface, lightingData); + + // Apply Image Based Lighting (IBL) + ApplyIBL(surface, lightingData); + + // Finalize Lighting + lightingData.FinalizeLighting(); + + PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); + + // ------- Opacity ------- + + if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) + { + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; + alpha = lerp(fresnelAlpha, alpha, surface.opacityAffectsSpecularFactor); + } + + if (o_opacity_mode == OpacityMode::Blended) + { + // [GFX_TODO ATOM-13187] PbrLighting shouldn't be writing directly to render targets. It's confusing when + // specular is being added to diffuse just because we're calling render target 0 "diffuse". + + // For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular + // to be added on top of the diffuse, but then the diffuse must be pre-multiplied. + // It's done this way because surface transparency doesn't really change specular response (eg, glass). + + lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; + + lightingOutput.m_diffuseColor.w = alpha; + } + else if (o_opacity_mode == OpacityMode::TintedTransparent) + { + // See OpacityMode::Blended above for the basic method. TintedTransparent adds onto the above concept by supporting + // colored alpha. This is currently a very basic calculation that uses the baseColor as a multiplier with strength + // determined by the alpha. We'll modify this later to be more physically accurate and allow surface depth, + // absorption, and interior color to be specified. + // + // The technique uses dual source blending to allow two separate sources to be part of the blending equation + // even though ultimately only a single render target is being written to. m_diffuseColor is render target 0 and + // m_specularColor render target 1, and the blend mode is (dest * source1color) + (source * 1.0). + // + // This means that m_specularColor.rgb (source 1) is multiplied against the destination, then + // m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0. + + lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; + + lightingOutput.m_specularColor.rgb = surface.baseColor * (1.0 - alpha); + } + else + { + lightingOutput.m_diffuseColor.w = -1; // Disable subsurface scattering + } + + return lightingOutput; +} + +ForwardPassOutputWithDepth StandardPbr_ForwardPassPS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) +{ + ForwardPassOutputWithDepth OUT; + float depth; + + PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); + +#ifdef UNIFIED_FORWARD_OUTPUT + OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb; + OUT.m_color.a = lightingOutput.m_diffuseColor.a; + OUT.m_depth = depth; +#else + OUT.m_diffuseColor = lightingOutput.m_diffuseColor; + OUT.m_specularColor = lightingOutput.m_specularColor; + OUT.m_specularF0 = lightingOutput.m_specularF0; + OUT.m_albedo = lightingOutput.m_albedo; + OUT.m_normal = lightingOutput.m_normal; + OUT.m_depth = depth; +#endif + return OUT; +} + +[earlydepthstencil] +ForwardPassOutput StandardPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFace) +{ + ForwardPassOutput OUT; + float depth; + + PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth); + +#ifdef UNIFIED_FORWARD_OUTPUT + OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb; + OUT.m_color.a = lightingOutput.m_diffuseColor.a; +#else + OUT.m_diffuseColor = lightingOutput.m_diffuseColor; + OUT.m_specularColor = lightingOutput.m_specularColor; + OUT.m_specularF0 = lightingOutput.m_specularF0; + OUT.m_albedo = lightingOutput.m_albedo; + OUT.m_normal = lightingOutput.m_normal; +#endif + return OUT; +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli index eb8c33cdce..21f55ea259 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli @@ -24,12 +24,31 @@ class Surface float3 position; //!< Position in world-space float3 normal; //!< Normal in world-space float3 vertexNormal; //!< Vertex normal in world-space - float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value - float3 specularF0; //!< Fresnel f0 spectral value of the surface + float3 baseColor; //!< Surface base color + float3 metallic; //!< Surface metallic property float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance + //! Subsurface scattering parameters + float subsurfaceScatteringFactor; + float subsurfaceScatteringQuality; + float3 scatterDistance; + + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float opacityAffectsSpecularFactor; + + //! Surface lighting inputs + float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value + float3 specularF0; //!< Fresnel f0 spectral value of the surface + float3 emissiveLighting; //!< Emissive lighting + float diffuseAmbientOcclusion; //!< Diffuse ambient occlusion factor - [0, 1] :: [Dark, Bright] + float specularOcclusion; //!< Specular occlusion factor - [0, 1] :: [Dark, Bright] + //! Applies specular anti-aliasing to roughnessA2 void ApplySpecularAA(); @@ -37,7 +56,7 @@ class Surface void CalculateRoughnessA(); //! Sets albedo and specularF0 using metallic workflow - void SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic); + void SetAlbedoAndSpecularF0(float specularF0Factor); }; @@ -76,7 +95,7 @@ void Surface::CalculateRoughnessA() } } -void Surface::SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic) +void Surface::SetAlbedoAndSpecularF0(float specularF0Factor) { float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * specularF0Factor; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli index cf4edba923..9d4abeb0f6 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli @@ -25,12 +25,26 @@ class Surface precise float3 position; //!< Position in world-space float3 normal; //!< Normal in world-space float3 vertexNormal; //!< Vertex normal in world-space - float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value - float3 specularF0; //!< Fresnel f0 spectral value of the surface + float3 baseColor; //!< Surface base color + float metallic; //!< Surface metallic property float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float opacityAffectsSpecularFactor; + + //! Surface lighting data + float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value + float3 specularF0; //!< Fresnel f0 spectral value of the surface + float3 emissiveLighting; //!< Emissive lighting + float diffuseAmbientOcclusion; //!< Diffuse ambient occlusion factor - [0, 1] :: [Dark, Bright] + float specularOcclusion; //!< Specular occlusion factor - [0, 1] :: [Dark, Bright] + //! Applies specular anti-aliasing to roughnessA2 void ApplySpecularAA(); @@ -38,7 +52,7 @@ class Surface void CalculateRoughnessA(); //! Sets albedo and specularF0 using metallic workflow - void SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic); + void SetAlbedoAndSpecularF0(float specularF0Factor); }; // Specular Anti-Aliasing technique from this paper: @@ -75,7 +89,7 @@ void Surface::CalculateRoughnessA() } } -void Surface::SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic) +void Surface::SetAlbedoAndSpecularF0(float specularF0Factor) { float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * specularF0Factor; diff --git a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl index 13f1e33ef7..3c4388350e 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl @@ -144,18 +144,20 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN) identityUvMatrix); IN.m_uv += tangentOffset.m_offsetTS.xy; + + Surface surface; - float3 baseColor = float3(1,1,1); + surface.baseColor = float3(1,1,1); const float noise = AutoBrickSrg::m_noise.Sample(AutoBrickSrg::m_sampler, IN.m_uv).r; float distanceFromBrick = GetNormalizedDistanceFromBrick(IN.m_uv); if(distanceFromBrick > AutoBrickSrg::m_brickColorBleed) { - baseColor = AutoBrickSrg::m_lineColor * lerp(1.0, noise, AutoBrickSrg::m_lineNoiseFactor); + surface.baseColor = AutoBrickSrg::m_lineColor * lerp(1.0, noise, AutoBrickSrg::m_lineNoiseFactor); } else { - baseColor = AutoBrickSrg::m_brickColor * lerp(1.0, noise, AutoBrickSrg::m_brickNoiseFactor); + surface.baseColor = AutoBrickSrg::m_brickColor * lerp(1.0, noise, AutoBrickSrg::m_brickNoiseFactor); } float surfaceDepth; @@ -164,8 +166,6 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN) const float3 normal = TangentSpaceToWorld(surfaceNormal, normalize(IN.m_normal), normalize(IN.m_tangent), normalize(IN.m_bitangent)); // ------- Surface ------- - - Surface surface; // Position, Normal, Roughness surface.position = IN.m_worldPosition.xyz; @@ -175,9 +175,9 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN) surface.CalculateRoughnessA(); // Albedo, SpecularF0 - const float metallic = 0.0f; - const float specularF0Factor = 0.5f; - surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); + surface.metallic = 0.0f; + float specularF0Factor = 0.5f; + surface.SetAlbedoAndSpecularF0(specularF0Factor); // Clear Coat surface.clearCoat.InitializeToZero(); diff --git a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl index 140fc57961..503c0107db 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl @@ -68,8 +68,10 @@ ForwardPassOutput MinimalPBR_MainPassPS(VSOutput IN) surface.CalculateRoughnessA(); // Albedo, SpecularF0 - const float specularF0Factor = 0.5f; - surface.SetAlbedoAndSpecularF0(MinimalPBRSrg::m_baseColor, specularF0Factor, MinimalPBRSrg::m_metallic); + surface.baseColor = MinimalPBRSrg::m_baseColor; + surface.metallic = MinimalPBRSrg::m_metallic; + float specularF0Factor = 0.5f; + surface.SetAlbedoAndSpecularF0(specularF0Factor); // Clear Coat surface.clearCoat.InitializeToZero(); From 7aace39c2fe63757c3ac966452b030842511e734 Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Fri, 4 Feb 2022 13:37:42 -0700 Subject: [PATCH 17/24] Consolidate alpha retrieval and clip Signed-off-by: Jeremy Ong --- .../Assets/Materials/Types/DepthPass_WithPS.azsl | 3 +-- .../Types/EnhancedPBR_DepthPass_WithPS.azsl | 3 +-- .../Materials/Types/EnhancedPBR_ForwardPass.azsl | 2 +- .../Types/EnhancedPBR_Shadowmap_WithPS.azsl | 3 +-- .../Types/EnhancedSurface_ForwardPass.azsl | 3 +-- .../EvaluateEnhancedSurface.azsli | 1 - .../EvaluateStandardSurface.azsli | 1 - .../MaterialFunctions/EvaluateTangentFrame.azsli | 4 ++-- ...etAlpha.azsli => StandardGetAlphaAndClip.azsli} | 6 ++++-- .../MaterialFunctions/StandardMaybeClip.azsli | 14 -------------- .../Assets/Materials/Types/ShadowMap_WithPS.azsl | 3 +-- .../Types/StandardPBR_DepthPass_WithPS.azsl | 3 +-- .../Materials/Types/StandardPBR_ForwardPass.azsl | 2 +- .../Types/StandardPBR_Shadowmap_WithPS.azsl | 3 +-- .../Types/StandardSurface_ForwardPass.azsl | 3 +-- 15 files changed, 16 insertions(+), 38 deletions(-) rename Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/{StandardGetAlpha.azsli => StandardGetAlphaAndClip.azsli} (57%) delete mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl index 9b017222b1..59d10f28f9 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl @@ -116,8 +116,7 @@ PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) } #ifndef MULTILAYER - float alpha = GetAlpha(IN.m_uv); - MaybeClip(alpha, IN.m_uv); + GetAlphaAndClip(IN.m_uv); #endif return OUT; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl index 2f7a5b94f9..f5ca5c5cde 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl @@ -11,10 +11,9 @@ #include "MaterialFunctions/StandardGetObjectToWorld.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" -#include "MaterialFunctions/StandardGetAlpha.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#include "MaterialFunctions/StandardMaybeClip.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "DepthPass_WithPS.azsl" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index bac97fed64..3e2bd4588b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -39,7 +39,7 @@ COMMON_OPTIONS_DETAIL_MAPS() #include "MaterialFunctions/EnhancedParallaxDepth.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" #include "MaterialFunctions/StandardGetObjectToWorld.azsli" -#include "MaterialFunctions/StandardMaybeClip.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "MaterialFunctions/StandardTransformDetailUvs.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl index 6c01a63a7c..3a9f8a7417 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl @@ -18,10 +18,9 @@ #include "MaterialFunctions/StandardGetObjectToWorld.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" -#include "MaterialFunctions/StandardGetAlpha.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#include "MaterialFunctions/StandardMaybeClip.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "ShadowMap_WithPS.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl index ceb9379f28..ef08b928cf 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl @@ -152,8 +152,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Alpha & Clip ------- // TODO: this often invokes a separate sample of the base color texture which is wasteful - float alpha = GetAlpha(IN.m_uv); - MaybeClip(alpha, IN.m_uv); + float alpha = GetAlphaAndClip(IN.m_uv); EvaluateEnhancedSurface(IN.m_normal, IN.m_uv, IN.m_detailUv, tangents, bitangents, isFrontFace, displacementIsClipped, surface); diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli index 9cc3e05789..c8d59363ea 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli @@ -8,7 +8,6 @@ #include #include -#include "StandardGetAlpha.azsli" void EvaluateEnhancedSurface( float3 normal, diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli index 54a4a2462a..c58f0534b3 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli @@ -8,7 +8,6 @@ #include #include -#include "StandardGetAlpha.azsli" void EvaluateStandardSurface( float3 normal, diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli index 2aad5f257d..643a2d29ca 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli @@ -17,8 +17,8 @@ void EvaluateTangentFrame( // The input tangent and bitangent vectors are optional and used to forward data from interpolants float3 IN_tangent, float3 IN_bitangent, - float3 OUT_tangent, - float3 OUT_bitangent) + out float3 OUT_tangent, + out float3 OUT_bitangent) { if (DrawSrg::GetTangentAtUv(uvIndex) == 0) { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli similarity index 57% rename from Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli rename to Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli index 90f8e417e1..81380e8c07 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlpha.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli @@ -8,10 +8,12 @@ #include "../MaterialInputs/AlphaInput.azsli" -float GetAlpha(float2 uvs[UvSetCount]) +float GetAlphaAndClip(float2 uvs[UvSetCount]) { // Alpha float2 baseColorUV = uvs[MaterialSrg::m_baseColorMapUvIndex]; float2 opacityUV = uvs[MaterialSrg::m_opacityMapUvIndex]; - return MaterialSrg::m_opacityFactor * SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); + float alpha = SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); + CheckClipping(alpha, MaterialSrg::m_opacityFactor); + return MaterialSrg::m_opacityFactor * alpha; } \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli deleted file mode 100644 index 2dabf9ba1e..0000000000 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardMaybeClip.azsli +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include - -void MaybeClip(float alpha, float2 uvs[UvSetCount]) -{ - CheckClipping(alpha, MaterialSrg::m_opacityFactor); -} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl index dd0665efe7..3dc2cf5d77 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl @@ -119,8 +119,7 @@ PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) } #ifndef MULTILAYER - float alpha = GetAlpha(IN.m_uv); - MaybeClip(alpha, IN.m_uv); + GetAlphaAndClip(IN.m_uv); #endif return OUT; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl index fe46d9bfba..62dcddf2a6 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl @@ -11,10 +11,9 @@ #include "MaterialFunctions/StandardGetObjectToWorld.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" -#include "MaterialFunctions/StandardGetAlpha.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#include "MaterialFunctions/StandardMaybeClip.azsli" #include "DepthPass_WithPS.azsl" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index 1a5e92b1d3..5dc1148370 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -32,7 +32,7 @@ COMMON_OPTIONS_EMISSIVE() #include "MaterialFunctions/ParallaxDepth.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" #include "MaterialFunctions/StandardGetObjectToWorld.azsli" -#include "MaterialFunctions/StandardMaybeClip.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" #include "StandardSurface_ForwardPass.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl index e8aeb20871..7acc121036 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl @@ -15,10 +15,9 @@ #include "MaterialFunctions/StandardGetObjectToWorld.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" -#include "MaterialFunctions/StandardGetAlpha.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#include "MaterialFunctions/StandardMaybeClip.azsli" #include "ShadowMap_WithPS.azsl" \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl index 1d3fa29991..b60f789cf5 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl @@ -149,8 +149,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Alpha & Clip ------- // TODO: this often invokes a separate sample of the base color texture which is wasteful - float alpha = GetAlpha(IN.m_uv); - MaybeClip(alpha, IN.m_uv); + float alpha = GetAlphaAndClip(IN.m_uv); EvaluateStandardSurface(IN.m_normal, IN.m_uv, tangents, bitangents, isFrontFace, displacementIsClipped, surface); From 4bcc83e7ac66f7c8631aa45fb9b6796d80e634c2 Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Fri, 4 Feb 2022 23:59:45 -0700 Subject: [PATCH 18/24] Address PR feedback, ensure all ASV tests pass Signed-off-by: Jeremy Ong --- .../Materials/Types/BasePBR_ForwardPass.azsl | 6 +- ...ass_WithPS.azsl => DepthPass_WithPS.azsli} | 9 +- .../Types/EnhancedPBR_DepthPass_WithPS.azsl | 2 +- .../Types/EnhancedPBR_ForwardPass.azsl | 2 +- .../Types/EnhancedPBR_Shadowmap_WithPS.azsl | 3 +- ...azsl => EnhancedSurface_ForwardPass.azsli} | 13 +- .../EnhancedParallaxDepth.azsli | 2 +- .../EvaluateEnhancedSurface.azsli | 19 +-- .../EvaluateStandardSurface.azsli | 15 ++- .../EvaluateTangentFrame.azsli | 6 +- .../MultilayerParallaxDepth.azsli | 6 +- .../MaterialFunctions/ParallaxDepth.azsli | 2 +- .../StandardGetAlphaAndClip.azsli | 2 +- .../StandardGetNormalToWorld.azsli | 2 +- .../StandardGetObjectToWorld.azsli | 2 +- .../StandardTransformDetailUvs.azsli | 2 +- .../StandardTransformUvs.azsli | 2 +- .../Materials/Types/ShadowMap_WithPS.azsl | 126 ------------------ ...tandardMultilayerPBR_DepthPass_WithPS.azsl | 3 +- .../StandardMultilayerPBR_ForwardPass.azsl | 8 +- ...tandardMultilayerPBR_Shadowmap_WithPS.azsl | 3 +- .../Types/StandardPBR_DepthPass_WithPS.azsl | 2 +- .../Types/StandardPBR_ForwardPass.azsl | 2 +- .../Types/StandardPBR_LowEndForward.azsl | 13 -- .../Types/StandardPBR_LowEndForward.shader | 4 +- .../StandardPBR_LowEndForward_EDS.shader | 4 +- .../Types/StandardPBR_Shadowmap_WithPS.azsl | 3 +- ...azsl => StandardSurface_ForwardPass.azsli} | 9 +- .../PBR/Surfaces/EnhancedSurface.azsli | 33 +++-- .../PBR/Surfaces/StandardSurface.azsli | 22 ++- .../atom_feature_common_asset_files.cmake | 15 ++- .../Types/AutoBrick_ForwardPass.azsl | 16 +-- .../Types/MinimalPBR_ForwardPass.azsl | 6 +- 33 files changed, 137 insertions(+), 227 deletions(-) rename Gems/Atom/Feature/Common/Assets/Materials/Types/{DepthPass_WithPS.azsl => DepthPass_WithPS.azsli} (95%) rename Gems/Atom/Feature/Common/Assets/Materials/Types/{EnhancedSurface_ForwardPass.azsl => EnhancedSurface_ForwardPass.azsli} (96%) delete mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl delete mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl rename Gems/Atom/Feature/Common/Assets/Materials/Types/{StandardSurface_ForwardPass.azsl => StandardSurface_ForwardPass.azsli} (97%) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl index b887761917..96318f2284 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/BasePBR_ForwardPass.azsl @@ -116,19 +116,19 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace) float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; float3 sampledColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor.rgb, o_baseColor_useTexture); - surface.baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); + float3 baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); // ------- Metallic ------- float2 metallicUv = IN.m_uv[MaterialSrg::m_metallicMapUvIndex]; - surface.metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); + float metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); // ------- Specular ------- float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex]; float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - surface.SetAlbedoAndSpecularF0(specularF0Factor); + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); // ------- Roughness ------- diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli similarity index 95% rename from Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl rename to Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli index 59d10f28f9..70d7b65b9b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli @@ -6,6 +6,10 @@ * */ +#ifdef SHADOWS +#include +#endif + struct VSInput { float3 m_position : POSITION; @@ -113,9 +117,12 @@ PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) SetPixelDepth(IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); #endif +#ifdef SHADOW + OUT.m_depth += PdoShadowMapBias; +#endif } -#ifndef MULTILAYER +#ifndef DEACTIVATE_ALPHA_CLIP GetAlphaAndClip(IN.m_uv); #endif diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl index f5ca5c5cde..a13d04bdb8 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl @@ -16,4 +16,4 @@ #include "MaterialFunctions/ParallaxDepth.azsli" #include "MaterialFunctions/StandardGetAlphaAndClip.azsli" -#include "DepthPass_WithPS.azsl" +#include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 3e2bd4588b..640ada8bd8 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -43,4 +43,4 @@ COMMON_OPTIONS_DETAIL_MAPS() #include "MaterialFunctions/StandardTransformDetailUvs.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" -#include "EnhancedSurface_ForwardPass.azsl" \ No newline at end of file +#include "EnhancedSurface_ForwardPass.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl index 3a9f8a7417..e5a7b3eb3c 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl @@ -23,4 +23,5 @@ #include "MaterialFunctions/ParallaxDepth.azsli" #include "MaterialFunctions/StandardGetAlphaAndClip.azsli" -#include "ShadowMap_WithPS.azsl" \ No newline at end of file +#define SHADOWS +#include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsli similarity index 96% rename from Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl rename to Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsli index ef08b928cf..8bc9802443 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedSurface_ForwardPass.azsli @@ -146,6 +146,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float } } + SurfaceSettings surfaceSettings; Surface surface; surface.vertexNormal = vertexNormal; surface.position = IN.m_worldPosition; @@ -154,7 +155,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // TODO: this often invokes a separate sample of the base color texture which is wasteful float alpha = GetAlphaAndClip(IN.m_uv); - EvaluateEnhancedSurface(IN.m_normal, IN.m_uv, IN.m_detailUv, tangents, bitangents, isFrontFace, displacementIsClipped, surface); + EvaluateEnhancedSurface(IN.m_normal, IN.m_uv, IN.m_detailUv, tangents, bitangents, isFrontFace, displacementIsClipped, surface, surfaceSettings); // ------- Lighting Data ------- @@ -222,7 +223,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // values close to 1.0, that indicates the absence of a surface entirely, so this effect should // not apply. float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; - alpha = lerp(fresnelAlpha, alpha, surface.opacityAffectsSpecularFactor); + alpha = lerp(fresnelAlpha, alpha, surfaceSettings.opacityAffectsSpecularFactor); } // Note: lightingOutput rendertargets are not always used as named, particularly m_diffuseColor (target 0) and @@ -241,7 +242,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surfaceSettings.opacityAffectsSpecularFactor); lightingOutput.m_diffuseColor.rgb += specular; lightingOutput.m_diffuseColor.w = alpha; @@ -264,7 +265,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surfaceSettings.opacityAffectsSpecularFactor); lightingOutput.m_diffuseColor.rgb += specular; lightingOutput.m_specularColor.rgb = surface.baseColor * (1.0 - alpha); @@ -272,9 +273,9 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float else { // Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961 - uint factorAndQuality = dot(round(float2(saturate(surface.subsurfaceScatteringFactor), surface.subsurfaceScatteringQuality) * 255), float2(256, 1)); + uint factorAndQuality = dot(round(float2(saturate(surface.subsurfaceScatteringFactor), surfaceSettings.subsurfaceScatteringQuality) * 255), float2(256, 1)); lightingOutput.m_diffuseColor.w = factorAndQuality * (o_enableSubsurfaceScattering ? 1.0 : -1.0); - lightingOutput.m_scatterDistance = surface.scatterDistance; + lightingOutput.m_scatterDistance = surfaceSettings.scatterDistance; } return lightingOutput; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli index e89afd6f37..449c789d01 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli @@ -38,4 +38,4 @@ // Apply second part of the offset to the detail UV (see comment above) detailUv[MaterialSrg::m_parallaxUvIndex] -= uvs[MaterialSrg::m_parallaxUvIndex]; -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli index c8d59363ea..d1cb52004a 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli @@ -17,7 +17,8 @@ void EvaluateEnhancedSurface( float3 bitangents[UvSetCount], bool isFrontFace, bool displacementIsClipped, - inout Surface surface) + inout Surface surface, + out SurfaceSettings surfaceSettings) { // ------- Detail Layer Setup ------- @@ -52,22 +53,22 @@ void EvaluateEnhancedSurface( float detailLayerBaseColorFactor = MaterialSrg::m_detail_baseColor_factor * detailLayerBlendFactor; float2 baseColorUv = uvs[MaterialSrg::m_baseColorMapUvIndex]; - surface.baseColor = GetDetailedBaseColorInput( + float3 baseColor = GetDetailedBaseColorInput( MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, o_baseColor_useTexture, MaterialSrg::m_baseColor, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, MaterialSrg::m_detail_baseColor_texture, MaterialSrg::m_sampler, detailUv, o_detail_baseColor_useTexture, detailLayerBaseColorFactor); if(o_parallax_highlightClipping && displacementIsClipped) { - ApplyParallaxClippingHighlight(surface.baseColor); + ApplyParallaxClippingHighlight(baseColor); } // ------- Metallic ------- - surface.metallic = 0; + float metallic = 0; if(!o_enableSubsurfaceScattering) // If subsurface scattering is enabled skip texture lookup for metallic, as this quantity won't be used anyway { float2 metallicUv = uvs[MaterialSrg::m_metallicMapUvIndex]; - surface.metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); + metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); } // ------- Specular ------- @@ -75,7 +76,7 @@ void EvaluateEnhancedSurface( float2 specularUv = uvs[MaterialSrg::m_specularF0MapUvIndex]; float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - surface.SetAlbedoAndSpecularF0(specularF0Factor); + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); // ------- Roughness ------- @@ -88,8 +89,8 @@ void EvaluateEnhancedSurface( float2 subsurfaceUv = uvs[MaterialSrg::m_subsurfaceScatteringInfluenceMapUvIndex]; surface.subsurfaceScatteringFactor = GetSubsurfaceInput(MaterialSrg::m_subsurfaceScatteringInfluenceMap, MaterialSrg::m_sampler, subsurfaceUv, MaterialSrg::m_subsurfaceScatteringFactor); - surface.subsurfaceScatteringQuality = MaterialSrg::m_subsurfaceScatteringQuality; - surface.scatterDistance = MaterialSrg::m_scatterDistance; + surfaceSettings.subsurfaceScatteringQuality = MaterialSrg::m_subsurfaceScatteringQuality; + surfaceSettings.scatterDistance = MaterialSrg::m_scatterDistance; // ------- Transmission ------- @@ -144,5 +145,5 @@ void EvaluateEnhancedSurface( surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor); } - surface.opacityAffectsSpecularFactor = MaterialSrg::m_opacityAffectsSpecularFactor; + surfaceSettings.opacityAffectsSpecularFactor = MaterialSrg::m_opacityAffectsSpecularFactor; } diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli index c58f0534b3..da24bb3937 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli @@ -16,7 +16,8 @@ void EvaluateStandardSurface( float3 bitangents[UvSetCount], bool isFrontFace, bool displacementIsClipped, - inout Surface surface) + inout Surface surface, + out SurfaceSettings surfaceSettings) { // ------- Normal ------- @@ -29,24 +30,24 @@ void EvaluateStandardSurface( float2 baseColorUv = uv[MaterialSrg::m_baseColorMapUvIndex]; float3 sampledColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor.rgb, o_baseColor_useTexture); - surface.baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); + float3 baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture); if(o_parallax_highlightClipping && displacementIsClipped) { - ApplyParallaxClippingHighlight(surface.baseColor); + ApplyParallaxClippingHighlight(baseColor); } // ------- Metallic ------- float2 metallicUv = uv[MaterialSrg::m_metallicMapUvIndex]; - surface.metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); + float metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); // ------- Specular ------- float2 specularUv = uv[MaterialSrg::m_specularF0MapUvIndex]; float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - surface.SetAlbedoAndSpecularF0(specularF0Factor); + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); // ------- Roughness ------- @@ -90,5 +91,5 @@ void EvaluateStandardSurface( } // ------- Opacity ------- - surface.opacityAffectsSpecularFactor = MaterialSrg::m_opacityAffectsSpecularFactor; -} \ No newline at end of file + surfaceSettings.opacityAffectsSpecularFactor = MaterialSrg::m_opacityAffectsSpecularFactor; +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli index 643a2d29ca..0045d18e47 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli @@ -27,7 +27,7 @@ void EvaluateTangentFrame( } else { - SurfaceGradientNormalMapping_Init(normal, worldPosition, !isFrontFace); \ - SurfaceGradientNormalMapping_GenerateTB(uv, OUT_tangent, OUT_bitangent); \ + SurfaceGradientNormalMapping_Init(normal, worldPosition, !isFrontFace); + SurfaceGradientNormalMapping_GenerateTB(uv, OUT_tangent, OUT_bitangent); } -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli index 5ee527b9a4..3f8b87c942 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli @@ -11,7 +11,7 @@ #include void MultilayerSetPixelDepth( - float blendMask, + float3 blendMask, float3 worldPosition, float3 normal, float3 tangents[UvSetCount], @@ -21,7 +21,7 @@ out float depth) { s_blendMaskFromVertexStream = blendMask; - + float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); @@ -32,4 +32,4 @@ parallaxOverallFactor, parallaxOverallOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, uvs[MaterialSrg::m_parallaxUvIndex], worldPosition, depth); -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli index 0298656375..645e3a4c2d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli @@ -48,4 +48,4 @@ MaterialSrg::m_heightmapScale, MaterialSrg::m_heightmapOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, uvs[MaterialSrg::m_parallaxUvIndex], worldPosition, depthNDC, depthCS, isClipped); -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli index 81380e8c07..c588b4423b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli @@ -16,4 +16,4 @@ float GetAlphaAndClip(float2 uvs[UvSetCount]) float alpha = SampleAlpha(MaterialSrg::m_baseColorMap, MaterialSrg::m_opacityMap, baseColorUV, opacityUV, MaterialSrg::m_sampler, o_opacity_source); CheckClipping(alpha, MaterialSrg::m_opacityFactor); return MaterialSrg::m_opacityFactor * alpha; -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli index b79b5b3418..f55f1b2078 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli @@ -9,4 +9,4 @@ float3x3 GetNormalToWorld() { return ObjectSrg::GetWorldMatrixInverseTranspose(); -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli index 435326215b..f02677658d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli @@ -9,4 +9,4 @@ float4x4 GetObjectToWorld() { return ObjectSrg::GetWorldMatrix(); -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli index 60ab575a2d..e6bb26ddc5 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli @@ -15,4 +15,4 @@ void TransformDetailUvs(in float2 IN[UvSetCount], out float2 OUT[UvSetCount]) // but we would need to address how it works with the parallax code below that indexes into the m_detailUV array. OUT[0] = mul(MaterialSrg::m_detailUvMatrix, float3(IN[0], 1.0)).xy; OUT[1] = mul(MaterialSrg::m_detailUvMatrix, float3(IN[1], 1.0)).xy; -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli index dd77f99ac3..39d77c7a93 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli @@ -11,4 +11,4 @@ void TransformUvs(in float2 IN[UvSetCount], out float2 OUT[UvSetCount]) // By design, only UV0 is allowed to apply transforms. OUT[0] = mul(MaterialSrg::m_uvMatrix, float3(IN[0], 1.0)).xy; OUT[1] = IN[1]; -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl deleted file mode 100644 index 3dc2cf5d77..0000000000 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/ShadowMap_WithPS.azsl +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -struct VertexInput -{ - float3 m_position : POSITION; - float2 m_uv0 : UV0; - float2 m_uv1 : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float4 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - -#ifdef MULTILAYER - // This gets set automatically by the system at runtime only if it's available. - // There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available. - // (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention). - // [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream. - float4 m_optional_blendMask : COLOR0; -#endif -}; - -struct VertexOutput -{ - // "centroid" is needed for SV_Depth to compile - linear centroid float4 m_position : SV_Position; - float2 m_uv[UvSetCount] : UV1; - - // only used for parallax depth calculation - float3 m_normal : NORMAL; - float3 m_tangent : TANGENT; - float3 m_bitangent : BITANGENT; - float3 m_worldPosition : UV0; - -#ifdef MULTILAYER - float3 m_blendMask : UV3; -#endif -}; - -VertexOutput MainVS(VertexInput IN) -{ - const float4x4 objectToWorld = GetObjectToWorld(); - VertexOutput OUT; - - const float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz; - OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0)); - - float2 uv[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; - TransformUvs(uv, OUT.m_uv); - - if(ShouldHandleParallaxInDepthShaders()) - { - OUT.m_worldPosition = worldPosition.xyz; - - float3x3 objectToWorldIT = GetNormalToWorld(); - ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); - } - -#ifdef MULTILAYER - if(o_blendMask_isBound) - { - OUT.m_blendMask = IN.m_optional_blendMask.rgb; - } - else - { - OUT.m_blendMask = float3(0,0,0); - } -#endif - - return OUT; -} - -struct PSDepthOutput -{ - float m_depth : SV_Depth; -}; - -PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) -{ - PSDepthOutput OUT; - - OUT.m_depth = IN.m_position.z; - - if(ShouldHandleParallaxInDepthShaders()) - { - float3 tangents[UvSetCount] = { IN.m_tangent, IN.m_tangent }; - float3 bitangents[UvSetCount] = { IN.m_bitangent, IN.m_bitangent }; - - for (int i = 0; i != UvSetCount; ++i) - { - EvaluateTangentFrame( - IN.m_normal, - IN.m_worldPosition, - isFrontFace, - IN.m_uv[i], - i, - IN.m_tangent, - IN.m_bitangent, - tangents[i], - bitangents[i]); - } - -#ifdef MULTILAYER - MultilayerSetPixelDepth(IN.m_blendMask, IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); -#else - SetPixelDepth(IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); -#endif - - OUT.m_depth += PdoShadowMapBias; - } - -#ifndef MULTILAYER - GetAlphaAndClip(IN.m_uv); -#endif - - return OUT; -} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl index d1a488ec0a..a185aae106 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl @@ -28,4 +28,5 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "MaterialFunctions/MultilayerParallaxDepth.azsli" #define MULTILAYER -#include "DepthPass_WithPS.azsl" +#define DEACTIVATE_ALPHA_CLIP +#include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index 2fe9990862..48d3cb4739 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -450,16 +450,16 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Combine Albedo, roughness, specular, roughness --------- - surface.baseColor = BlendLayers(lightingInputLayer1.m_baseColor, lightingInputLayer2.m_baseColor, lightingInputLayer3.m_baseColor, blendWeights); + float3 baseColor = BlendLayers(lightingInputLayer1.m_baseColor, lightingInputLayer2.m_baseColor, lightingInputLayer3.m_baseColor, blendWeights); float specularF0Factor = BlendLayers(lightingInputLayer1.m_specularF0Factor, lightingInputLayer2.m_specularF0Factor, lightingInputLayer3.m_specularF0Factor, blendWeights); - surface.metallic = BlendLayers(lightingInputLayer1.m_metallic, lightingInputLayer2.m_metallic, lightingInputLayer3.m_metallic, blendWeights); + float metallic = BlendLayers(lightingInputLayer1.m_metallic, lightingInputLayer2.m_metallic, lightingInputLayer3.m_metallic, blendWeights); if(o_parallax_highlightClipping && displacementIsClipped) { - ApplyParallaxClippingHighlight(surface.baseColor); + ApplyParallaxClippingHighlight(baseColor); } - surface.SetAlbedoAndSpecularF0(specularF0Factor); + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); surface.roughnessLinear = BlendLayers(lightingInputLayer1.m_roughness, lightingInputLayer2.m_roughness, lightingInputLayer3.m_roughness, blendWeights); surface.CalculateRoughnessA(); diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl index 84b44512f0..331fa76b16 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl @@ -28,4 +28,5 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "MaterialFunctions/MultilayerParallaxDepth.azsli" #define MULTILAYER -#include "ShadowMap_WithPS.azsl" \ No newline at end of file +#define DEACTIVATE_ALPHA_CLIP +#include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl index 62dcddf2a6..cf0b7b7311 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl @@ -16,4 +16,4 @@ #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#include "DepthPass_WithPS.azsl" +#include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index 5dc1148370..4240c291da 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -35,4 +35,4 @@ COMMON_OPTIONS_EMISSIVE() #include "MaterialFunctions/StandardGetAlphaAndClip.azsli" #include "MaterialFunctions/StandardTransformUvs.azsli" -#include "StandardSurface_ForwardPass.azsl" \ No newline at end of file +#include "StandardSurface_ForwardPass.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl deleted file mode 100644 index 02e9e93ba2..0000000000 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -// NOTE: This file is a temporary workaround until .shader files can #define macros for their .azsl files - -#define QUALITY_LOW_END 1 - -#include "StandardPBR_ForwardPass.azsl" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader index 44139608ca..511749c6ae 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader @@ -5,7 +5,9 @@ // DrawListTag. If your pipeline doesn't have a "lowEndForward" DrawListTag, no draw items // for this shader will be created. - "Source" : "./StandardPBR_LowEndForward.azsl", + "Source" : "./StandardPBR_ForwardPass.azsl", + + "Definitions": [ "QUALITY_LOW_END=1" ], "DepthStencilState" : { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader index 9faa1d3698..6dc4004b07 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader @@ -5,7 +5,9 @@ // DrawListTag. If your pipeline doesn't have a "lowEndForward" DrawListTag, no draw items // for this shader will be created. - "Source" : "./StandardPBR_LowEndForward.azsl", + "Source" : "./StandardPBR_ForwardPass.azsl", + + "Definitions": [ "QUALITY_LOW_END=1" ], "DepthStencilState" : { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl index 7acc121036..665c85c02e 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl @@ -20,4 +20,5 @@ #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#include "ShadowMap_WithPS.azsl" \ No newline at end of file +#define SHADOWS +#include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsli similarity index 97% rename from Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl rename to Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsli index b60f789cf5..5f89fc704b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsli @@ -143,6 +143,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float } } + SurfaceSettings surfaceSettings; Surface surface; surface.vertexNormal = vertexNormal; surface.position = IN.m_worldPosition.xyz; @@ -151,7 +152,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // TODO: this often invokes a separate sample of the base color texture which is wasteful float alpha = GetAlphaAndClip(IN.m_uv); - EvaluateStandardSurface(IN.m_normal, IN.m_uv, tangents, bitangents, isFrontFace, displacementIsClipped, surface); + EvaluateStandardSurface(IN.m_normal, IN.m_uv, tangents, bitangents, isFrontFace, displacementIsClipped, surface, surfaceSettings); // ------- Lighting Data ------- @@ -209,7 +210,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // values close to 1.0, that indicates the absence of a surface entirely, so this effect should // not apply. float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; - alpha = lerp(fresnelAlpha, alpha, surface.opacityAffectsSpecularFactor); + alpha = lerp(fresnelAlpha, alpha, surfaceSettings.opacityAffectsSpecularFactor); } if (o_opacity_mode == OpacityMode::Blended) @@ -225,7 +226,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surfaceSettings.opacityAffectsSpecularFactor); lightingOutput.m_diffuseColor.rgb += specular; lightingOutput.m_diffuseColor.w = alpha; @@ -248,7 +249,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. float3 specular = lightingOutput.m_specularColor.rgb; - specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surface.opacityAffectsSpecularFactor); + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, surfaceSettings.opacityAffectsSpecularFactor); lightingOutput.m_diffuseColor.rgb += specular; lightingOutput.m_specularColor.rgb = surface.baseColor * (1.0 - alpha); diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli index 21f55ea259..c12cd2834b 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli @@ -13,6 +13,21 @@ #include #include +// This data varies across different surfaces, but is uniform within a surface +class SurfaceSettings +{ + //! Subsurface scattering parameters + float subsurfaceScatteringQuality; + float3 scatterDistance; + + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float opacityAffectsSpecularFactor; +}; + class Surface { AnisotropicSurfaceData anisotropy; @@ -29,18 +44,7 @@ class Surface float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance - - //! Subsurface scattering parameters float subsurfaceScatteringFactor; - float subsurfaceScatteringQuality; - float3 scatterDistance; - - // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. - // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface - // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor - // values close to 1.0, that indicates the absence of a surface entirely, so this effect should - // not apply. - float opacityAffectsSpecularFactor; //! Surface lighting inputs float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value @@ -56,7 +60,7 @@ class Surface void CalculateRoughnessA(); //! Sets albedo and specularF0 using metallic workflow - void SetAlbedoAndSpecularF0(float specularF0Factor); + void SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic); }; @@ -95,12 +99,13 @@ void Surface::CalculateRoughnessA() } } -void Surface::SetAlbedoAndSpecularF0(float specularF0Factor) +void Surface::SetAlbedoAndSpecularF0(float3 newBaseColor, float specularF0Factor, float newMetallic) { + baseColor = newBaseColor; + metallic = newMetallic; float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * specularF0Factor; // Compute albedo and specularF0 based on metalness albedo = lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic); specularF0 = lerp(dielectricSpecularF0, baseColor, metallic); } - diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli index 9d4abeb0f6..9a8d5cfd54 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli @@ -8,11 +8,21 @@ #pragma once -#include #include #include #include +// This data varies across different surfaces, but is uniform within a surface +class SurfaceSettings +{ + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float opacityAffectsSpecularFactor; +}; + class Surface { @@ -51,8 +61,8 @@ class Surface //! Calculates roughnessA and roughnessA2 after roughness has been set void CalculateRoughnessA(); - //! Sets albedo and specularF0 using metallic workflow - void SetAlbedoAndSpecularF0(float specularF0Factor); + //! Sets albedo, base color, specularF0, and metallic properties using metallic workflow + void SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic); }; // Specular Anti-Aliasing technique from this paper: @@ -89,12 +99,14 @@ void Surface::CalculateRoughnessA() } } -void Surface::SetAlbedoAndSpecularF0(float specularF0Factor) +void Surface::SetAlbedoAndSpecularF0(float3 newBaseColor, float specularF0Factor, float newMetallic) { + baseColor = newBaseColor; + metallic = newMetallic; + float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * specularF0Factor; // Compute albedo and specularF0 based on metalness albedo = lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic); specularF0 = lerp(dielectricSpecularF0, baseColor, metallic); } - diff --git a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake index e6ad71bde3..00d437acd1 100644 --- a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake +++ b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake @@ -10,12 +10,24 @@ set(FILES Materials/Special/ShadowCatcher.azsl Materials/Special/ShadowCatcher.materialtype Materials/Special/ShadowCatcher.shader + Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli + Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli + Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli + Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli + Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli + Materials/Types/MaterialFunctions/ParallaxDepth.azsli + Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli + Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli + Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli + Materials/Types/MaterialFunctions/StandardTransformDetailUvs.azsli + Materials/Types/MaterialFunctions/StandardTransformUvs.azsli Materials/Types/BasePBR.materialtype Materials/Types/BasePBR_Common.azsli Materials/Types/BasePBR_ForwardPass.azsl Materials/Types/BasePBR_ForwardPass.shader Materials/Types/BasePBR_LowEndForward.azsl Materials/Types/BasePBR_LowEndForward.shader + Materials/Types/DepthPass_WithPS.azsli Materials/Types/EnhancedPBR.materialtype Materials/Types/EnhancedPBR_Common.azsli Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl @@ -26,6 +38,7 @@ set(FILES Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl Materials/Types/EnhancedPBR_Shadowmap_WithPS.shader Materials/Types/EnhancedPBR_SubsurfaceState.lua + Materials/Types/EnhancedSurface_ForwardPass.azsli Materials/Types/Skin.azsl Materials/Types/Skin.materialtype Materials/Types/Skin.shader @@ -56,7 +69,6 @@ set(FILES Materials/Types/StandardPBR_ForwardPass_EDS.shader Materials/Types/StandardPBR_HandleOpacityDoubleSided.lua Materials/Types/StandardPBR_HandleOpacityMode.lua - Materials/Types/StandardPBR_LowEndForward.azsl Materials/Types/StandardPBR_LowEndForward.shader Materials/Types/StandardPBR_LowEndForward_EDS.shader Materials/Types/StandardPBR_Metallic.lua @@ -65,6 +77,7 @@ set(FILES Materials/Types/StandardPBR_ShaderEnable.lua Materials/Types/StandardPBR_Shadowmap_WithPS.azsl Materials/Types/StandardPBR_Shadowmap_WithPS.shader + Materials/Types/StandardSurface_ForwardPass.azsli Materials/Types/MaterialInputs/AlphaInput.azsli Materials/Types/MaterialInputs/BaseColorInput.azsli Materials/Types/MaterialInputs/ClearCoatInput.azsli diff --git a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl index 3c4388350e..13f1e33ef7 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl @@ -144,20 +144,18 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN) identityUvMatrix); IN.m_uv += tangentOffset.m_offsetTS.xy; - - Surface surface; - surface.baseColor = float3(1,1,1); + float3 baseColor = float3(1,1,1); const float noise = AutoBrickSrg::m_noise.Sample(AutoBrickSrg::m_sampler, IN.m_uv).r; float distanceFromBrick = GetNormalizedDistanceFromBrick(IN.m_uv); if(distanceFromBrick > AutoBrickSrg::m_brickColorBleed) { - surface.baseColor = AutoBrickSrg::m_lineColor * lerp(1.0, noise, AutoBrickSrg::m_lineNoiseFactor); + baseColor = AutoBrickSrg::m_lineColor * lerp(1.0, noise, AutoBrickSrg::m_lineNoiseFactor); } else { - surface.baseColor = AutoBrickSrg::m_brickColor * lerp(1.0, noise, AutoBrickSrg::m_brickNoiseFactor); + baseColor = AutoBrickSrg::m_brickColor * lerp(1.0, noise, AutoBrickSrg::m_brickNoiseFactor); } float surfaceDepth; @@ -166,6 +164,8 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN) const float3 normal = TangentSpaceToWorld(surfaceNormal, normalize(IN.m_normal), normalize(IN.m_tangent), normalize(IN.m_bitangent)); // ------- Surface ------- + + Surface surface; // Position, Normal, Roughness surface.position = IN.m_worldPosition.xyz; @@ -175,9 +175,9 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN) surface.CalculateRoughnessA(); // Albedo, SpecularF0 - surface.metallic = 0.0f; - float specularF0Factor = 0.5f; - surface.SetAlbedoAndSpecularF0(specularF0Factor); + const float metallic = 0.0f; + const float specularF0Factor = 0.5f; + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); // Clear Coat surface.clearCoat.InitializeToZero(); diff --git a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl index 503c0107db..71c1621f7f 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl @@ -68,10 +68,10 @@ ForwardPassOutput MinimalPBR_MainPassPS(VSOutput IN) surface.CalculateRoughnessA(); // Albedo, SpecularF0 - surface.baseColor = MinimalPBRSrg::m_baseColor; - surface.metallic = MinimalPBRSrg::m_metallic; + float3 baseColor = MinimalPBRSrg::m_baseColor; + float metallic = MinimalPBRSrg::m_metallic; float specularF0Factor = 0.5f; - surface.SetAlbedoAndSpecularF0(specularF0Factor); + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); // Clear Coat surface.clearCoat.InitializeToZero(); From 9ed9bcbb2f3324949bf774f56cb37c7ed91159cf Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Sat, 5 Feb 2022 12:31:03 -0700 Subject: [PATCH 19/24] Fix incorrect include header casing Signed-off-by: Jeremy Ong --- .../Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl index a185aae106..7edea547ac 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl @@ -24,7 +24,7 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "MaterialFunctions/StandardGetObjectToWorld.azsli" #include "MaterialFunctions/StandardGetNormalToWorld.azsli" #include "MaterialFunctions/EvaluateTangentFrame.azsli" -#include "MaterialFunctions/StandardTransformUVs.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/MultilayerParallaxDepth.azsli" #define MULTILAYER From 86d8ececfbf1e1b197acc4c2157f59b5b31f4b02 Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Mon, 7 Feb 2022 10:54:31 -0700 Subject: [PATCH 20/24] Resolve incorrect SHADOWS definitions Signed-off-by: Jeremy Ong --- .../Common/Assets/Materials/Types/DepthPass_WithPS.azsli | 2 +- .../Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli index 70d7b65b9b..3dd3792102 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli @@ -117,7 +117,7 @@ PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) SetPixelDepth(IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); #endif -#ifdef SHADOW +#ifdef SHADOWS OUT.m_depth += PdoShadowMapBias; #endif } diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl index 331fa76b16..8d7314640b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl @@ -29,4 +29,5 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #define MULTILAYER #define DEACTIVATE_ALPHA_CLIP +#define SHADOWS #include "DepthPass_WithPS.azsli" From faa65bca1bee49a6ae607d209d391788e668540a Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Tue, 8 Feb 2022 11:51:16 -0700 Subject: [PATCH 21/24] Refactor shader definitions to be more consistent with other shaders Signed-off-by: Jeremy Ong --- .../Materials/Types/DepthPass_WithPS.azsli | 24 ++++++++++++++----- .../Types/EnhancedPBR_DepthPass_WithPS.azsl | 1 + .../Types/EnhancedPBR_Shadowmap_WithPS.azsl | 3 ++- ...tandardMultilayerPBR_DepthPass_WithPS.azsl | 4 ++-- ...tandardMultilayerPBR_Shadowmap_WithPS.azsl | 6 ++--- .../Types/StandardPBR_DepthPass_WithPS.azsl | 1 + .../Types/StandardPBR_Shadowmap_WithPS.azsl | 3 ++- .../PBR/Surfaces/EnhancedSurface.azsli | 2 +- 8 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli index 3dd3792102..a1318bf383 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli @@ -10,6 +10,18 @@ #include #endif +#ifndef MULTILAYER +#define MULTILAYER 0 +#endif + +#ifndef ENABLE_ALPHA_CLIP +#define ENABLE_ALPHA_CLIP 0 +#endif + +#ifndef SHADOWS +#define SHADOWS 0 +#endif + struct VSInput { float3 m_position : POSITION; @@ -21,7 +33,7 @@ struct VSInput float4 m_tangent : TANGENT; float3 m_bitangent : BITANGENT; -#ifdef MULTILAYER +#if MULTILAYER // This gets set automatically by the system at runtime only if it's available. // There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available. // (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention). @@ -42,7 +54,7 @@ struct VSDepthOutput float3 m_bitangent : BITANGENT; float3 m_worldPosition : UV0; -#ifdef MULTILAYER +#if MULTILAYER float3 m_blendMask : UV3; #endif }; @@ -67,7 +79,7 @@ VSDepthOutput MainVS(VSInput IN) ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); } -#ifdef MULTILAYER +#if MULTILAYER if(o_blendMask_isBound) { OUT.m_blendMask = IN.m_optional_blendMask.rgb; @@ -111,18 +123,18 @@ PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) bitangents[i]); } -#ifdef MULTILAYER +#if MULTILAYER MultilayerSetPixelDepth(IN.m_blendMask, IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); #else SetPixelDepth(IN.m_worldPosition, IN.m_normal, tangents, bitangents, IN.m_uv, isFrontFace, OUT.m_depth); #endif -#ifdef SHADOWS +#if SHADOWS OUT.m_depth += PdoShadowMapBias; #endif } -#ifndef DEACTIVATE_ALPHA_CLIP +#if ENABLE_ALPHA_CLIP GetAlphaAndClip(IN.m_uv); #endif diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl index a13d04bdb8..eb220faec6 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl @@ -16,4 +16,5 @@ #include "MaterialFunctions/ParallaxDepth.azsli" #include "MaterialFunctions/StandardGetAlphaAndClip.azsli" +#define ENABLE_ALPHA_CLIP 1 #include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl index e5a7b3eb3c..be350a3ce7 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl @@ -23,5 +23,6 @@ #include "MaterialFunctions/ParallaxDepth.azsli" #include "MaterialFunctions/StandardGetAlphaAndClip.azsli" -#define SHADOWS +#define SHADOWS 1 +#define ENABLE_ALPHA_CLIP 1 #include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl index 7edea547ac..0f000fba98 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl @@ -27,6 +27,6 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/MultilayerParallaxDepth.azsli" -#define MULTILAYER -#define DEACTIVATE_ALPHA_CLIP +#define MULTILAYER 1 +#define ENABLE_ALPHA_CLIP 0 #include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl index 8d7314640b..9d64916444 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl @@ -27,7 +27,7 @@ COMMON_OPTIONS_PARALLAX(o_layer3_) #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/MultilayerParallaxDepth.azsli" -#define MULTILAYER -#define DEACTIVATE_ALPHA_CLIP -#define SHADOWS +#define MULTILAYER 1 +#define ENABLE_ALPHA_CLIP 0 +#define SHADOWS 1 #include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl index cf0b7b7311..b848ba03ba 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl @@ -16,4 +16,5 @@ #include "MaterialFunctions/StandardTransformUvs.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" +#define ENABLE_ALPHA_CLIP 1 #include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl index 665c85c02e..634d23daa1 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Shadowmap_WithPS.azsl @@ -20,5 +20,6 @@ #include "MaterialFunctions/EvaluateTangentFrame.azsli" #include "MaterialFunctions/ParallaxDepth.azsli" -#define SHADOWS +#define SHADOWS 1 +#define ENABLE_ALPHA_CLIP 1 #include "DepthPass_WithPS.azsli" diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli index c12cd2834b..961fbd49f9 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli @@ -40,7 +40,7 @@ class Surface float3 normal; //!< Normal in world-space float3 vertexNormal; //!< Vertex normal in world-space float3 baseColor; //!< Surface base color - float3 metallic; //!< Surface metallic property + float metallic; //!< Surface metallic property float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance From 5f914e8e1aa1da1235784b26cb355a7189859b98 Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Tue, 8 Feb 2022 12:03:28 -0700 Subject: [PATCH 22/24] Add README to describe upcoming material type changes Signed-off-by: Jeremy Ong --- .../Common/Assets/Materials/Types/README.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/README.md diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/README.md b/Gems/Atom/Feature/Common/Assets/Materials/Types/README.md new file mode 100644 index 0000000000..e176f6d7dc --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/README.md @@ -0,0 +1,98 @@ +# Upcoming material system changes + +Currently, `.materialtype` files specify a set of shaders for each pass in the rendering pipeline. +For example, the `StandardPBR.materialtype` asset specifies the following shaders: + +```json +[ + { + "file": "./StandardPBR_ForwardPass.shader", + "tag": "ForwardPass" + }, + { + "file": "./StandardPBR_ForwardPass_EDS.shader", + "tag": "ForwardPass_EDS" + }, + { + "file": "./StandardPBR_LowEndForward.shader", + "tag": "LowEndForward" + }, + { + "file": "./StandardPBR_LowEndForward_EDS.shader", + "tag": "LowEndForward_EDS" + }, + { + "file": "Shaders/Shadow/Shadowmap.shader", + "tag": "Shadowmap" + }, + { + "file": "./StandardPBR_Shadowmap_WithPS.shader", + "tag": "Shadowmap_WithPS" + }, + { + "file": "Shaders/Depth/DepthPass.shader", + "tag": "DepthPass" + }, + { + "file": "./StandardPBR_DepthPass_WithPS.shader", + "tag": "DepthPass_WithPS" + }, + { + "file": "Shaders/MotionVector/MeshMotionVector.shader", + "tag": "MeshMotionVector" + }, + { + "file": "Shaders/Depth/DepthPassTransparentMin.shader", + "tag": "DepthPassTransparentMin" + }, + { + "file": "Shaders/Depth/DepthPassTransparentMax.shader", + "tag": "DepthPassTransparentMax" + } +] +``` + +**This will be changing in a future release** to a material type description that specifies shader snippets (aka material functions) +instead of explicit shaders. + +## Why is it changing? + +There are two primary reasons to move to a different scheme. + +1. Material types are strongly coupled to the rendering pipeline. If a user wants to change the pipeline, or the engine wants to use, for example, a custom pipeline for mobile, or VR, this isn't possible today without cloning existing material types and changing the shader array. +2. The material canvas work that has been prioritized to allow artist-driven material customization benefits from a more modular construction of materials. For example, we'd like to apply a "wind graph" and mix and match that with a "foliage graph" to describe the appearance of some foliage. The current material type description couples all the geometric passes with the material and lighting passes, which makes this sort of decomposition difficult. + +## What is it changing to? + +The best way to understand how this is changing is to inspect the current structure of `EnhancedPBR_ForwardPass.azsl` and `StandardPBR_ForwardPass.azsl`. +These shaders start with a number of includes to specify the SRG as follows: + +```hlsl +#include "StandardPBR_Common.azsli" +#include +``` + +Later, it includes a number of material functions, for example: + +```hlsl +#include "MaterialFunctions/EvaluateStandardSurface.azsli" +#include "MaterialFunctions/EvaluateTangentFrame.azsli" +#include "MaterialFunctions/ParallaxDepth.azsli" +#include "MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "MaterialFunctions/StandardTransformUvs.azsli" +``` + +The material function headers define functions that may later be overridden using material graphs. + +Finally, in the case of the standard surface shader, it includes an implementation file: + +```hlsl +#include "StandardSurface_ForwardPass.azsli" +``` + +This file, if you inspect it, _makes no reference to `MaterialSrg`_, and furthermore, does not include files needed to implement any of the material functions. +In other words, the structure of the standard pbr forward shader is such that it can be assembled with different components, specifing the SRG, material functions, and implementation. + +In the future, a material pipeline abstraction will allow the `materialtype` asset to specify _only_ the material function files, and the tuple of `materialtype` and `materialpipeline` will allow the material builder to assemble the shader on behalf of the user. The final piece to the puzzle is that (again, in the future), material canvas (in active development) can produce material functions to replace the built-in ones. From 42c2243eaac0ac8174ffef52808b2f5f08d49352 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 8 Feb 2022 14:34:04 -0800 Subject: [PATCH 23/24] Fix benchmark non-unity build Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp index de19ee1783..e44ba3ce67 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include From 90503f2bef683e864ec35b836b757eb3050891ad Mon Sep 17 00:00:00 2001 From: chiyenteng <82238204+chiyenteng@users.noreply.github.com> Date: Tue, 8 Feb 2022 15:25:35 -0800 Subject: [PATCH 24/24] Remove error message from InMemorySpawnableAssetContainer (#7499) * Remove error message from InMemorySpawnableAssetContainer Signed-off-by: chiyenteng <82238204+chiyenteng@users.noreply.github.com> * Fix nits Signed-off-by: chiyenteng <82238204+chiyenteng@users.noreply.github.com> --- .../Gem/PythonTests/Physics/TestSuite_Main_Optimized.py | 8 ++++---- .../Gem/PythonTests/Physics/TestSuite_Periodic.py | 6 +----- .../tests/collider/Collider_AddColliderComponent.py | 5 +++-- .../Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp | 5 +---- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py index a40b9065d6..3242735345 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py @@ -54,7 +54,7 @@ class EditorSingleTest_WithFileOverrides(EditorSingleTest): fm._restore_file(f, file_list[f]) -# @pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") +@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) @@ -113,6 +113,9 @@ class TestAutomationWithPrefabSystemEnabled(EditorTestSuite): class C14861504_RenderMeshAsset_WithNoPxAsset(EditorSharedTest): from .tests.collider import Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx as test_module + + class C4976236_AddPhysxColliderComponent(EditorSharedTest): + from .tests.collider import Collider_AddColliderComponent as test_module @pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @@ -346,9 +349,6 @@ class TestAutomation(EditorTestSuite): class C5959809_ForceRegion_RotationalOffset(EditorSharedTest): from .tests.force_region import ForceRegion_RotationalOffset as test_module - class C4976236_AddPhysxColliderComponent(EditorSharedTest): - from .tests.collider import Collider_AddColliderComponent as test_module - class C100000_RigidBody_EnablingGravityWorksPoC(EditorSharedTest): from .tests.rigid_body import RigidBody_EnablingGravityWorksPoC as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py index d75328d8f7..d8fa6a30cd 100755 --- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py @@ -440,13 +440,9 @@ class TestAutomation(TestAutomationBase): from .tests.material import Material_LibraryClearingAssignsDefault as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.xfail(reason= - "Test failed due to an error message shown while in game mode: " - "'(Prefab) - Invalid asset found referenced in scene while entering game mode. " - "The asset was stored in an instance of Asset.'") def test_Collider_AddColliderComponent(self, request, workspace, editor, launcher_platform): from .tests.collider import Collider_AddColliderComponent as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module) @pytest.mark.xfail( reason="This will fail due to this issue ATOM-15487.") diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_AddColliderComponent.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_AddColliderComponent.py index 4172e66962..d03cc7fff5 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_AddColliderComponent.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_AddColliderComponent.py @@ -49,9 +49,10 @@ def Collider_AddColliderComponent(): from editor_python_test_tools.utils import Tracer from editor_python_test_tools.asset_utils import Asset - helper.init_idle() + import editor_python_test_tools.hydra_editor_utils as hydra + # 1) Load the level - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create test entity test_entity = EditorEntity.create_editor_entity("TestEntity") diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp index 567ccc3619..dcb17d02b4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp @@ -235,10 +235,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils if (!asset->GetId().IsValid()) { - AZ_Error( - "Prefab", false, - "Invalid asset found referenced in scene while entering game mode. The asset was stored in an instance of %s.", - classData->m_name); + // Invalid asset found referenced in scene while entering game mode. return false; }