Merge branch 'stabilization/2106' into V2Mainline
This commit is contained in:
@@ -49,7 +49,7 @@ class TestViewMenuOptions(EditorTestHelper):
|
||||
view_menu_options = [
|
||||
("Center on Selection",),
|
||||
("Show Quick Access Bar",),
|
||||
("Viewport", "Wireframe"),
|
||||
("Viewport", "Configure Layout"),
|
||||
("Viewport", "Go to Position"),
|
||||
("Viewport", "Center on Selection"),
|
||||
("Viewport", "Go to Location"),
|
||||
|
||||
@@ -89,7 +89,7 @@ class TestMenus(object):
|
||||
expected_lines = [
|
||||
"Center on Selection Action triggered",
|
||||
"Show Quick Access Bar Action triggered",
|
||||
"Wireframe Action triggered",
|
||||
"Configure Layout Action triggered",
|
||||
"Go to Position Action triggered",
|
||||
"Center on Selection Action triggered",
|
||||
"Go to Location Action triggered",
|
||||
|
||||
@@ -406,6 +406,7 @@ namespace AZ
|
||||
AZStd::vector<AZ::BehaviorParameter> eventParamsTypes{ AZStd::initializer_list<AZ::BehaviorParameter>{
|
||||
CreateBehaviorEventParameter<decay_array<T>>()... } };
|
||||
behaviorContext->Class<AZ::Event<T...>>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
|
||||
->Attribute(AZ::Script::Attributes::EventHandlerCreationFunction, createHandlerHolder)
|
||||
->Attribute(AZ::Script::Attributes::EventParameterTypes, eventParamsTypes)
|
||||
->Method("HasHandlerConnected", &AZ::Event<T...>::HasHandlerConnected)
|
||||
@@ -413,6 +414,7 @@ namespace AZ
|
||||
|
||||
behaviorContext->Class<AZ::EventHandler<T...>>()
|
||||
->Method("Disconnect", &AZ::EventHandler<T...>::Disconnect)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,10 +607,12 @@ namespace AZ
|
||||
}
|
||||
else if (source.Size() > target.Size())
|
||||
{
|
||||
rapidjson::SizeType sourceCount = source.Size();
|
||||
for (rapidjson::SizeType i = count; i < sourceCount; ++i)
|
||||
// Loop backwards through the removals so that each removal has a valid index when processing in order.
|
||||
for (rapidjson::SizeType i = source.Size(); i > count; --i)
|
||||
{
|
||||
ScopedStackedString entryName(element, i);
|
||||
// (We use "i - 1" here instead of in the loop to ensure we don't wrap around our unsigned numbers in the case
|
||||
// where count is 0.)
|
||||
ScopedStackedString entryName(element, i - 1);
|
||||
patch.PushBack(CreatePatchInternal_Remove(allocator, element), allocator);
|
||||
resultCode.Combine(settings.m_reporting("Removed member from array in JSON Patch.",
|
||||
ResultCode(Tasks::CreatePatch, Outcomes::Success), element));
|
||||
|
||||
@@ -303,6 +303,29 @@ namespace JsonSerializationTests
|
||||
R"( { "foo": [ "bar", "baz" ] })");
|
||||
}
|
||||
|
||||
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchRemoveArrayMembersInCorrectOrder_ReportsSuccess)
|
||||
{
|
||||
CheckApplyPatch(
|
||||
R"( { "foo": [ "bar", "qux", "baz" ] })",
|
||||
R"( [
|
||||
{ "op": "remove", "path": "/foo/2" },
|
||||
{ "op": "remove", "path": "/foo/1" }
|
||||
])",
|
||||
R"( { "foo": [ "bar" ] })");
|
||||
}
|
||||
|
||||
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchRemoveArrayMembersInWrongOrder_ReportsError)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
CheckApplyPatchOutcome(
|
||||
R"( { "foo": [ "bar", "qux", "baz" ] })",
|
||||
R"( [
|
||||
{ "op": "remove", "path": "/foo/1" },
|
||||
{ "op": "remove", "path": "/foo/2" }
|
||||
])",
|
||||
Outcomes::Invalid, Processing::Halted);
|
||||
}
|
||||
|
||||
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchRemoveOperationInvalidParent_ReportError)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -949,6 +972,27 @@ namespace JsonSerializationTests
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(JsonPatchingSerializationTests, CreatePatch_UseJsonPatchRemoveLastArrayEntries_MultipleOperationsInCorrectOrder)
|
||||
{
|
||||
CheckCreatePatch(
|
||||
R"( [ "foo", "hello", "bar" ])", R"( [ "foo" ])",
|
||||
R"( [
|
||||
{ "op": "remove", "path": "/2" },
|
||||
{ "op": "remove", "path": "/1" }
|
||||
])");
|
||||
}
|
||||
|
||||
TEST_F(JsonPatchingSerializationTests, CreatePatch_UseJsonPatchRemoveAllArrayEntries_MultipleOperationsInCorrectOrder)
|
||||
{
|
||||
CheckCreatePatch(
|
||||
R"( [ "foo", "hello", "bar" ])", R"( [])",
|
||||
R"( [
|
||||
{ "op": "remove", "path": "/2" },
|
||||
{ "op": "remove", "path": "/1" },
|
||||
{ "op": "remove", "path": "/0" }
|
||||
])");
|
||||
}
|
||||
|
||||
TEST_F(JsonPatchingSerializationTests, CreatePatch_UseJsonPatchRemoveObjectFromArrayInMiddle_OperationToUpdateMember)
|
||||
{
|
||||
CheckCreatePatch(
|
||||
|
||||
+14
-3
@@ -159,12 +159,23 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabEditorEntityOwnershipService::GetNonPrefabEntities(EntityList& entities)
|
||||
{
|
||||
m_rootInstance->GetEntities(entities, false);
|
||||
m_rootInstance->GetEntities(
|
||||
[&entities](const AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
entities.emplace_back(entity.get());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::GetAllEntities(EntityList& entities)
|
||||
{
|
||||
m_rootInstance->GetEntities(entities, true);
|
||||
m_rootInstance->GetAllEntitiesInHierarchy(
|
||||
[&entities](const AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
entities.emplace_back(entity.get());
|
||||
return true;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -551,7 +562,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
m_rootInstance->GetNestedEntities([this](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
m_rootInstance->GetAllEntitiesInHierarchy([this](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
AZ_Assert(entity, "Invalid entity found in root instance while starting play in editor.");
|
||||
if (entity->GetState() == AZ::Entity::State::Active)
|
||||
|
||||
@@ -373,17 +373,25 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::GetConstNestedEntities(const AZStd::function<bool(const AZ::Entity&)>& callback)
|
||||
bool Instance::GetEntities_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
{
|
||||
GetConstEntities(callback);
|
||||
|
||||
for (const auto& [instanceAlias, instance] : m_nestedInstances)
|
||||
for (auto& [entityAlias, entity] : m_entities)
|
||||
{
|
||||
instance->GetConstNestedEntities(callback);
|
||||
if (!entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!callback(entity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Instance::GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback)
|
||||
bool Instance::GetConstEntities_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const
|
||||
{
|
||||
for (const auto& [entityAlias, entity] : m_entities)
|
||||
{
|
||||
@@ -394,19 +402,83 @@ namespace AzToolsFramework
|
||||
|
||||
if (!callback(*entity))
|
||||
{
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Instance::GetNestedEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
bool Instance::GetAllEntitiesInHierarchy_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
{
|
||||
GetEntities(callback);
|
||||
if (HasContainerEntity())
|
||||
{
|
||||
if (!callback(m_containerEntity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetEntities_Impl(callback))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& [instanceAlias, instance] : m_nestedInstances)
|
||||
{
|
||||
instance->GetNestedEntities(callback);
|
||||
if (!instance->GetAllEntitiesInHierarchy_Impl(callback))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Instance::GetAllEntitiesInHierarchyConst_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const
|
||||
{
|
||||
if (HasContainerEntity())
|
||||
{
|
||||
if (!callback(*m_containerEntity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetConstEntities_Impl(callback))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& [instanceAlias, instance] : m_nestedInstances)
|
||||
{
|
||||
if (!instance->GetAllEntitiesInHierarchyConst_Impl(callback))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Instance::GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
{
|
||||
GetEntities_Impl(callback);
|
||||
}
|
||||
|
||||
void Instance::GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback) const
|
||||
{
|
||||
GetConstEntities_Impl(callback);
|
||||
}
|
||||
|
||||
void Instance::GetAllEntitiesInHierarchy(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
{
|
||||
GetAllEntitiesInHierarchy_Impl(callback);
|
||||
}
|
||||
|
||||
void Instance::GetAllEntitiesInHierarchyConst(const AZStd::function<bool(const AZ::Entity&)>& callback) const
|
||||
{
|
||||
GetAllEntitiesInHierarchyConst_Impl(callback);
|
||||
}
|
||||
|
||||
void Instance::GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback)
|
||||
@@ -417,44 +489,6 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
{
|
||||
for (auto& [entityAlias, entity] : m_entities)
|
||||
{
|
||||
if (!callback(entity))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::GetEntities(EntityList& entities, bool includeNestedEntities)
|
||||
{
|
||||
// Non-recursive traversal of instances
|
||||
AZStd::vector<Instance*> instancesToTraverse = { this };
|
||||
while (!instancesToTraverse.empty())
|
||||
{
|
||||
Instance* currentInstance = instancesToTraverse.back();
|
||||
instancesToTraverse.pop_back();
|
||||
if (includeNestedEntities)
|
||||
{
|
||||
instancesToTraverse.reserve(instancesToTraverse.size() + currentInstance->m_nestedInstances.size());
|
||||
for (const auto& instanceByAlias : currentInstance->m_nestedInstances)
|
||||
{
|
||||
instancesToTraverse.push_back(instanceByAlias.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Size increases by 1 for each instance because we have to count the container entity also.
|
||||
entities.reserve(entities.size() + currentInstance->m_entities.size() + 1);
|
||||
entities.push_back(m_containerEntity.get());
|
||||
for (const auto& entityByAlias : currentInstance->m_entities)
|
||||
{
|
||||
entities.push_back(entityByAlias.second.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EntityAliasOptionalReference Instance::GetEntityAlias(const AZ::EntityId& id)
|
||||
{
|
||||
if (m_instanceToTemplateEntityIdMap.count(id))
|
||||
|
||||
@@ -121,10 +121,10 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Gets the entities in the Instance DOM. Can recursively trace all nested instances.
|
||||
*/
|
||||
void GetConstNestedEntities(const AZStd::function<bool(const AZ::Entity&)>& callback);
|
||||
void GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback);
|
||||
void GetNestedEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
void GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
void GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
|
||||
void GetAllEntitiesInHierarchy(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
void GetAllEntitiesInHierarchyConst(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
|
||||
void GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback);
|
||||
|
||||
/**
|
||||
@@ -184,12 +184,6 @@ namespace AzToolsFramework
|
||||
|
||||
static InstanceAlias GenerateInstanceAlias();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Gets the entities owned by this instance
|
||||
*/
|
||||
void GetEntities(EntityList& entities, bool includeNestedEntities = false);
|
||||
|
||||
private:
|
||||
static constexpr const char s_aliasPathSeparator = '/';
|
||||
|
||||
@@ -197,6 +191,11 @@ namespace AzToolsFramework
|
||||
|
||||
void RemoveEntities(const AZStd::function<bool(const AZStd::unique_ptr<AZ::Entity>&)>& filter);
|
||||
|
||||
bool GetEntities_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
bool GetConstEntities_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
|
||||
bool GetAllEntitiesInHierarchy_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
bool GetAllEntitiesInHierarchyConst_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
|
||||
|
||||
bool RegisterEntity(const AZ::EntityId& entityId, const EntityAlias& entityAlias);
|
||||
AZStd::unique_ptr<AZ::Entity> DetachEntity(const EntityAlias& entityAlias);
|
||||
|
||||
|
||||
+9
-24
@@ -62,25 +62,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Entity*> EditorInfoRemover::GetEntitiesFromInstance(AZStd::unique_ptr<Instance>& instance)
|
||||
void EditorInfoRemover::GetEntitiesFromInstance(
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance>& instance, EntityList& hierarchyEntities)
|
||||
{
|
||||
AZStd::vector<AZ::Entity*> result;
|
||||
|
||||
instance->GetNestedEntities(
|
||||
[&result](const AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
instance->GetAllEntitiesInHierarchy(
|
||||
[&hierarchyEntities](const AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
result.emplace_back(entity.get());
|
||||
hierarchyEntities.emplace_back(entity.get());
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
if (instance->HasContainerEntity())
|
||||
{
|
||||
auto containerEntityReference = instance->GetContainerEntity();
|
||||
result.emplace_back(&containerEntityReference->get());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void EditorInfoRemover::SetEditorOnlyEntityHandlerFromCandidates(const EntityList& entities)
|
||||
@@ -543,7 +534,9 @@ exportComponent, prefabProcessorContext);
|
||||
}
|
||||
|
||||
// grab all nested entities from the Instance as source entities.
|
||||
EntityList sourceEntities = GetEntitiesFromInstance(instance);
|
||||
EntityList sourceEntities;
|
||||
GetEntitiesFromInstance(instance, sourceEntities);
|
||||
|
||||
EntityList exportEntities;
|
||||
|
||||
// prepare for validation of component requirements.
|
||||
@@ -616,7 +609,7 @@ exportComponent, prefabProcessorContext);
|
||||
);
|
||||
|
||||
// replace entities of instance with exported ones.
|
||||
instance->GetNestedEntities(
|
||||
instance->GetAllEntitiesInHierarchy(
|
||||
[&exportEntitiesMap](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
auto entityId = entity->GetId();
|
||||
@@ -625,14 +618,6 @@ exportComponent, prefabProcessorContext);
|
||||
}
|
||||
);
|
||||
|
||||
if (instance->HasContainerEntity())
|
||||
{
|
||||
if (auto found = exportEntitiesMap.find(instance->GetContainerEntityId()); found != exportEntitiesMap.end())
|
||||
{
|
||||
instance->SetContainerEntity(*found->second);
|
||||
}
|
||||
}
|
||||
|
||||
// save the final result in the target Prefab DOM.
|
||||
PrefabDom filteredPrefab;
|
||||
if (!PrefabDomUtils::StoreInstanceInPrefabDom(*instance, filteredPrefab))
|
||||
|
||||
+2
-2
@@ -55,8 +55,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
protected:
|
||||
using EntityList = AZStd::vector<AZ::Entity*>;
|
||||
static EntityList GetEntitiesFromInstance(
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance>& instance);
|
||||
static void GetEntitiesFromInstance(
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance>& instance, EntityList& hierarchyEntities);
|
||||
|
||||
static bool ReadComponentAttribute(
|
||||
AZ::Component* component,
|
||||
|
||||
+12
-6
@@ -29,15 +29,20 @@ namespace Benchmark
|
||||
{},
|
||||
m_pathString));
|
||||
|
||||
|
||||
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(instance->GetTemplateId());
|
||||
for (auto _ : state)
|
||||
{
|
||||
state.PauseTiming();
|
||||
|
||||
AzFramework::Spawnable spawnable;
|
||||
AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(spawnable, prefabDom);
|
||||
|
||||
state.ResumeTiming();
|
||||
// Create a vector to store spawnables so that they don't get destroyed immediately after construction.
|
||||
AZStd::vector<AZStd::unique_ptr<AzFramework::Spawnable>> spawnables;
|
||||
spawnables.reserve(numSpawnables);
|
||||
|
||||
for (int spwanableCounter = 0; spwanableCounter < numSpawnables; ++spwanableCounter)
|
||||
{
|
||||
AZStd::unique_ptr<AzFramework::Spawnable> spawnable = AZStd::make_unique<AzFramework::Spawnable>();
|
||||
AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(*spawnable, prefabDom);
|
||||
spawnables.push_back(AZStd::move(spawnable));
|
||||
}
|
||||
}
|
||||
|
||||
state.SetComplexityN(numSpawnables);
|
||||
@@ -50,3 +55,4 @@ namespace Benchmark
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace UnitTest
|
||||
|
||||
// Retrieve the entity pointer from the component application bus.
|
||||
AZ::Entity* wheelEntityUnderAxle = nullptr;
|
||||
axleInstance->GetNestedEntities([&wheelEntityUnderAxle, wheelEntityIdUnderAxle](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
axleInstance->GetAllEntitiesInHierarchy([&wheelEntityUnderAxle, wheelEntityIdUnderAxle](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
if (entity->GetId() == wheelEntityIdUnderAxle)
|
||||
{
|
||||
|
||||
@@ -514,18 +514,28 @@ void EditorViewportWidget::Update()
|
||||
// Disable rendering to avoid recursion into Update()
|
||||
PushDisableRendering();
|
||||
|
||||
|
||||
//get debug display interface for the viewport
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, GetViewportId());
|
||||
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
||||
|
||||
AzFramework::DebugDisplayRequests* debugDisplay =
|
||||
AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
|
||||
|
||||
// draw debug visualizations
|
||||
if (m_debugDisplay)
|
||||
if (debugDisplay)
|
||||
{
|
||||
const AZ::u32 prevState = m_debugDisplay->GetState();
|
||||
m_debugDisplay->SetState(
|
||||
const AZ::u32 prevState = debugDisplay->GetState();
|
||||
debugDisplay->SetState(
|
||||
e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
|
||||
AzFramework::EntityDebugDisplayEventBus::Broadcast(
|
||||
&AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport,
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *m_debugDisplay);
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *debugDisplay);
|
||||
|
||||
m_debugDisplay->SetState(prevState);
|
||||
debugDisplay->SetState(prevState);
|
||||
}
|
||||
|
||||
QtViewport::Update();
|
||||
|
||||
@@ -154,11 +154,23 @@ SandboxIntegrationManager::SandboxIntegrationManager()
|
||||
{
|
||||
// Required to receive events from the Cry Engine undo system
|
||||
GetIEditor()->GetUndoManager()->AddListener(this);
|
||||
|
||||
// Only create the PrefabIntegrationManager if prefabs are enabled
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (prefabSystemEnabled)
|
||||
{
|
||||
m_prefabIntegrationManager = aznew AzToolsFramework::Prefab::PrefabIntegrationManager();
|
||||
}
|
||||
}
|
||||
|
||||
SandboxIntegrationManager::~SandboxIntegrationManager()
|
||||
{
|
||||
GetIEditor()->GetUndoManager()->RemoveListener(this);
|
||||
|
||||
delete m_prefabIntegrationManager;
|
||||
m_prefabIntegrationManager = nullptr;
|
||||
}
|
||||
|
||||
void SandboxIntegrationManager::Setup()
|
||||
@@ -187,11 +199,16 @@ void SandboxIntegrationManager::Setup()
|
||||
AZ_Assert((m_editorEntityUiInterface != nullptr),
|
||||
"SandboxIntegrationManager requires a EditorEntityUiInterface instance to be present on Setup().");
|
||||
|
||||
m_prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
|
||||
|
||||
AZ_Assert(
|
||||
(m_prefabIntegrationInterface != nullptr),
|
||||
"SandboxIntegrationManager requires a PrefabIntegrationInterface instance to be present on Setup().");
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (prefabSystemEnabled)
|
||||
{
|
||||
m_prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
|
||||
AZ_Assert(
|
||||
(m_prefabIntegrationInterface != nullptr),
|
||||
"SandboxIntegrationManager requires a PrefabIntegrationInterface instance to be present on Setup().");
|
||||
}
|
||||
|
||||
m_editorEntityAPI = AZ::Interface<AzToolsFramework::EditorEntityAPI>::Get();
|
||||
AZ_Assert(m_editorEntityAPI, "SandboxIntegrationManager requires an EditorEntityAPI instance to be present on Setup().");
|
||||
|
||||
@@ -305,7 +305,7 @@ private:
|
||||
|
||||
bool m_debugDisplayBusImplementationActive = false;
|
||||
|
||||
AzToolsFramework::Prefab::PrefabIntegrationManager m_prefabIntegrationManager;
|
||||
AzToolsFramework::Prefab::PrefabIntegrationManager* m_prefabIntegrationManager = nullptr;
|
||||
|
||||
AzToolsFramework::EditorEntityUiInterface* m_editorEntityUiInterface = nullptr;
|
||||
AzToolsFramework::Prefab::PrefabIntegrationInterface* m_prefabIntegrationInterface = nullptr;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "BuilderManager.h"
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <native/connection/connectionManager.h>
|
||||
@@ -186,10 +187,9 @@ namespace AssetProcessor
|
||||
QDir projectCacheRoot;
|
||||
AssetUtilities::ComputeProjectCacheRoot(projectCacheRoot);
|
||||
|
||||
QString gameName = AssetUtilities::ComputeProjectName();
|
||||
QString projectPath = AssetUtilities::ComputeProjectPath();
|
||||
QDir engineRoot;
|
||||
AssetUtilities::ComputeEngineRoot(engineRoot);
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName = AZ::Utils::GetProjectName();
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
AZ::IO::FixedMaxPathString enginePath = AZ::Utils::GetEnginePath();
|
||||
|
||||
int portNumber = 0;
|
||||
ApplicationServerBus::BroadcastResult(portNumber, &ApplicationServerBus::Events::GetServerListeningPort);
|
||||
@@ -197,14 +197,14 @@ namespace AssetProcessor
|
||||
AZStd::string params;
|
||||
#if !AZ_TRAIT_OS_PLATFORM_APPLE && !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
|
||||
params = AZStd::string::format(
|
||||
R"(-task=%s -id="%s" -project-name="%s" -project-cache-path="%s" -project-path="%s" -engine-path="%s" -port %d)", task,
|
||||
builderGuid.c_str(), gameName.toUtf8().constData(), projectCacheRoot.absolutePath().toUtf8().constData(),
|
||||
projectPath.toUtf8().constData(), engineRoot.absolutePath().toUtf8().constData(), portNumber);
|
||||
R"(-task=%s -id="%s" -project-name="%s" -project-cache-path="%s" -project-path="%s" -engine-path="%s" -port %d)",
|
||||
task, builderGuid.c_str(), projectName.c_str(), projectCacheRoot.absolutePath().toUtf8().constData(),
|
||||
projectPath.c_str(), enginePath.c_str(), portNumber);
|
||||
#else
|
||||
params = AZStd::string::format(
|
||||
R"(-task=%s -id="%s" -project-name="\"%s\"" -project-cache-path="\"%s\"" -project-path="\"%s\"" -engine-path="\"%s\"" -port %d)",
|
||||
task, builderGuid.c_str(), gameName.toUtf8().constData(), projectCacheRoot.absolutePath().toUtf8().constData(),
|
||||
projectPath.toUtf8().constData(), engineRoot.absolutePath().toUtf8().constData(), portNumber);
|
||||
task, builderGuid.c_str(), projectName.c_str(), projectCacheRoot.absolutePath().toUtf8().constData(),
|
||||
projectPath.c_str(), enginePath.c_str(), portNumber);
|
||||
#endif // !AZ_TRAIT_OS_PLATFORM_APPLE && !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
|
||||
|
||||
if (moduleFilePath && moduleFilePath[0])
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace AZ
|
||||
{
|
||||
AZStd::string extension;
|
||||
StringFunc::Path::GetExtension(path.c_str(), extension);
|
||||
AZStd::to_lower(extension.begin(), extension.end());
|
||||
|
||||
if (!m_settings.m_supportedFileTypeExtensions.contains(extension))
|
||||
{
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(4); // [LYN-3971] Bone pruning crash fix in AssImp SDK
|
||||
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(5); // [LYN-4226] Invert PostRotation matrix in animation chains
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -385,24 +385,36 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, convert the nested slice to a prefab.
|
||||
bool nestedSliceResult = ConvertSliceFile(serializeContext, assetPath, isDryRun);
|
||||
if (!nestedSliceResult)
|
||||
{
|
||||
AZ_Warning("Convert-Slice", nestedSliceResult, " Nested slice '%s' could not be converted.", assetPath.c_str());
|
||||
return false;
|
||||
}
|
||||
// Check to see if we've already converted this slice at a higher level of slice nesting, or if this is our first
|
||||
// occurrence and we need to convert it now.
|
||||
|
||||
// Find the prefab template we created for the newly-created nested prefab.
|
||||
// To get the template, we need to take our absolute slice path and turn it into a project-relative prefab path.
|
||||
// First, take our absolute slice path and turn it into a project-relative prefab path.
|
||||
AZ::IO::Path nestedPrefabPath = assetPath;
|
||||
nestedPrefabPath.ReplaceExtension("prefab");
|
||||
|
||||
auto prefabLoaderInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
|
||||
nestedPrefabPath = prefabLoaderInterface->GenerateRelativePath(nestedPrefabPath);
|
||||
|
||||
// Now, see if we already have a template ID in memory for it.
|
||||
AzToolsFramework::Prefab::TemplateId nestedTemplateId =
|
||||
prefabSystemComponentInterface->GetTemplateIdFromFilePath(nestedPrefabPath);
|
||||
|
||||
// If we don't have a template ID yet, convert the nested slice to a prefab and get the template ID.
|
||||
if (nestedTemplateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
bool nestedSliceResult = ConvertSliceFile(serializeContext, assetPath, isDryRun);
|
||||
if (!nestedSliceResult)
|
||||
{
|
||||
AZ_Warning("Convert-Slice", nestedSliceResult, " Nested slice '%s' could not be converted.", assetPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
nestedTemplateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(nestedPrefabPath);
|
||||
AZ_Assert(nestedTemplateId != AzToolsFramework::Prefab::InvalidTemplateId,
|
||||
"Template ID for %s is invalid", nestedPrefabPath.c_str());
|
||||
}
|
||||
|
||||
// Get the nested prefab template.
|
||||
AzToolsFramework::Prefab::TemplateReference nestedTemplate =
|
||||
prefabSystemComponentInterface->FindTemplate(nestedTemplateId);
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"Format": "R16G16B16A16_FLOAT",
|
||||
"MipLevels": "8",
|
||||
"SharedQueueMask": "Graphics"
|
||||
}
|
||||
},
|
||||
"GenerateFullMipChain": true
|
||||
}
|
||||
],
|
||||
"Connections": [
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"ClassData": {
|
||||
"PassTemplate": {
|
||||
"Name": "ReflectionScreenSpaceCompositePassTemplate",
|
||||
"PassClass": "FullScreenTriangle",
|
||||
"PassClass": "ReflectionScreenSpaceCompositePass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "TraceInput",
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include <Atom/Features/PBR/Lights/LightTypesCommon.azsli>
|
||||
#include <Atom/Features/Shadow/ProjectedShadow.azsli>
|
||||
|
||||
// The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp
|
||||
static const float3 PointLightShadowCubemapDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)};
|
||||
|
||||
int GetPointLightShadowCubemapFace(const float3 targetPos, const float3 lightPos)
|
||||
{
|
||||
const float3 toPoint = targetPos - lightPos;
|
||||
@@ -83,12 +80,13 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD
|
||||
{
|
||||
const int shadowCubemapFace = GetPointLightShadowCubemapFace(surface.position, light.m_position);
|
||||
const int shadowIndex = UnpackPointLightShadowIndex(light, shadowCubemapFace);
|
||||
|
||||
const float3 lightDir = normalize(light.m_position - surface.position);
|
||||
|
||||
litRatio *= ProjectedShadow::GetVisibility(
|
||||
shadowIndex,
|
||||
light.m_position,
|
||||
surface.position,
|
||||
PointLightShadowCubemapDirections[shadowCubemapFace],
|
||||
lightDir,
|
||||
surface.normal);
|
||||
|
||||
// Use backShadowRatio to carry thickness from shadow map for thick mode
|
||||
|
||||
+4
-6
@@ -37,6 +37,9 @@ ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
|
||||
// the max roughness mip level for sampling the previous frame image
|
||||
uint m_maxMipLevel;
|
||||
}
|
||||
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
@@ -69,10 +72,6 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
|
||||
float4 positionWS = mul(ViewSrg::m_viewProjectionInverseMatrix, projectedPos);
|
||||
positionWS /= positionWS.w;
|
||||
|
||||
//float4 positionVS = mul(ViewSrg::m_projectionMatrixInverse, projectedPos);
|
||||
//positionVS /= positionVS.w;
|
||||
//float4 positionWS = mul(ViewSrg::m_viewMatrixInverse, positionVS);
|
||||
|
||||
// compute ray from camera to surface position
|
||||
float3 cameraToPositionWS = normalize(positionWS.xyz - ViewSrg::m_worldPosition);
|
||||
|
||||
@@ -103,8 +102,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
|
||||
// compute the roughness mip to use in the previous frame image
|
||||
// remap the roughness mip into a lower range to more closely match the material roughness values
|
||||
const float MaxRoughness = 0.5f;
|
||||
const float MaxRoughnessMip = 7;
|
||||
float mip = saturate(roughness / MaxRoughness) * MaxRoughnessMip;
|
||||
float mip = saturate(roughness / MaxRoughness) * PassSrg::m_maxMipLevel;
|
||||
|
||||
// sample reflection value from the roughness mip
|
||||
float4 reflectionColor = float4(PassSrg::m_previousFrame.SampleLevel(PassSrg::LinearSampler, tracePrevUV, mip).rgb, 1.0f);
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
#include <DiffuseGlobalIllumination/DiffuseGlobalIlluminationFeatureProcessor.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessor.h>
|
||||
|
||||
@@ -283,6 +284,7 @@ namespace AZ
|
||||
// Add Reflection passes
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurPass"), &Render::ReflectionScreenSpaceBlurPass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurChildPass"), &Render::ReflectionScreenSpaceBlurChildPass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceCompositePass"), &Render::ReflectionScreenSpaceCompositePass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionCopyFrameBufferPass"), &Render::ReflectionCopyFrameBufferPass::Create);
|
||||
|
||||
// Add RayTracing pas
|
||||
|
||||
+3
@@ -37,6 +37,9 @@ namespace AZ
|
||||
//! to store the previous frame image
|
||||
Data::Instance<RPI::AttachmentImage>& GetFrameBufferImageAttachment() { return m_frameBufferImageAttachment; }
|
||||
|
||||
//! Returns the number of mip levels in the blur
|
||||
uint32_t GetNumBlurMips() const { return m_numBlurMips; }
|
||||
|
||||
private:
|
||||
explicit ReflectionScreenSpaceBlurPass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ReflectionScreenSpaceCompositePass.h"
|
||||
#include "ReflectionScreenSpaceBlurPass.h"
|
||||
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Pass/PassFilter.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<ReflectionScreenSpaceCompositePass> ReflectionScreenSpaceCompositePass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<ReflectionScreenSpaceCompositePass> pass = aznew ReflectionScreenSpaceCompositePass(descriptor);
|
||||
return AZStd::move(pass);
|
||||
}
|
||||
|
||||
ReflectionScreenSpaceCompositePass::ReflectionScreenSpaceCompositePass(const RPI::PassDescriptor& descriptor)
|
||||
: RPI::FullscreenTrianglePass(descriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void ReflectionScreenSpaceCompositePass::CompileResources([[maybe_unused]] const RHI::FrameGraphCompileContext& context)
|
||||
{
|
||||
if (!m_shaderResourceGroup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RPI::PassHierarchyFilter passFilter(AZ::Name("ReflectionScreenSpaceBlurPass"));
|
||||
const AZStd::vector<RPI::Pass*>& passes = RPI::PassSystemInterface::Get()->FindPasses(passFilter);
|
||||
if (!passes.empty())
|
||||
{
|
||||
Render::ReflectionScreenSpaceBlurPass* blurPass = azrtti_cast<ReflectionScreenSpaceBlurPass*>(passes.front());
|
||||
|
||||
// compute the max mip level based on the available mips in the previous frame image, and capping it
|
||||
// to stay within a range that has reasonable data
|
||||
const uint32_t MaxNumRoughnessMips = 8;
|
||||
uint32_t maxMipLevel = AZStd::min(MaxNumRoughnessMips, blurPass->GetNumBlurMips()) - 1;
|
||||
|
||||
auto constantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_maxMipLevel"));
|
||||
m_shaderResourceGroup->SetConstant(constantIndex, maxMipLevel);
|
||||
}
|
||||
|
||||
FullscreenTrianglePass::CompileResources(context);
|
||||
}
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/Pass/Pass.h>
|
||||
#include <Atom/RPI.Public/Pass/FullscreenTrianglePass.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
#include <Atom/RPI.Public/Shader/Shader.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! This pass composites the screenspace reflection trace onto the reflection buffer.
|
||||
class ReflectionScreenSpaceCompositePass
|
||||
: public RPI::FullscreenTrianglePass
|
||||
{
|
||||
AZ_RPI_PASS(ReflectionScreenSpaceCompositePass);
|
||||
|
||||
public:
|
||||
AZ_RTTI(Render::ReflectionScreenSpaceCompositePass, "{88739CC9-C3F1-413A-A527-9916C697D93A}", FullscreenTrianglePass);
|
||||
AZ_CLASS_ALLOCATOR(Render::ReflectionScreenSpaceCompositePass, SystemAllocator, 0);
|
||||
|
||||
//! Creates a new pass without a PassTemplate
|
||||
static RPI::Ptr<ReflectionScreenSpaceCompositePass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
private:
|
||||
explicit ReflectionScreenSpaceCompositePass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
// Pass Overrides...
|
||||
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@@ -629,6 +629,11 @@ namespace AZ
|
||||
|
||||
Data::Asset<RPI::ModelLodAsset> lodAsset;
|
||||
modelLodCreator.End(lodAsset);
|
||||
if (!lodAsset.IsReady())
|
||||
{
|
||||
// [GFX TODO] During mesh reload the modelLodCreator could report errors and result in the lodAsset not ready.
|
||||
return nullptr;
|
||||
}
|
||||
modelCreator.AddLodAsset(AZStd::move(lodAsset));
|
||||
|
||||
lodIndex++;
|
||||
|
||||
@@ -267,6 +267,8 @@ set(FILES
|
||||
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h
|
||||
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.cpp
|
||||
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.h
|
||||
Source/ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.cpp
|
||||
Source/ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.h
|
||||
Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.cpp
|
||||
Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h
|
||||
Source/ScreenSpace/DeferredFogSettings.cpp
|
||||
|
||||
@@ -417,7 +417,7 @@ namespace AZ
|
||||
AZ::IO::FileIOStream sourceMtlfileStream(inputMetalFile.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary);
|
||||
if (!sourceMtlfileStream.IsOpen())
|
||||
{
|
||||
AZ_Error(platformName, false, "Failed because the shader file \"%s\" could not be opened", inputMetalFile);
|
||||
AZ_Error(platformName, false, "Failed because the shader file \"%s\" could not be opened", inputMetalFile.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -400,15 +400,13 @@ namespace AZ
|
||||
id<MTLResource> mtlconstantBufferResource = m_constantBuffer.GetGpuAddress<id<MTLResource>>();
|
||||
if(RHI::CheckBitsAny(srgResourcesVisInfo.m_constantDataStageMask, RHI::ShaderStageMask::Compute))
|
||||
{
|
||||
uint16_t arrayIndex = resourcesToMakeResidentCompute[MTLResourceUsageRead].m_resourceArrayLen++;
|
||||
resourcesToMakeResidentCompute[MTLResourceUsageRead].m_resourceArray[arrayIndex] = mtlconstantBufferResource;
|
||||
resourcesToMakeResidentCompute[MTLResourceUsageRead].emplace(mtlconstantBufferResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
MTLRenderStages mtlRenderStages = GetRenderStages(srgResourcesVisInfo.m_constantDataStageMask);
|
||||
AZStd::pair <MTLResourceUsage,MTLRenderStages> key = AZStd::make_pair(MTLResourceUsageRead, mtlRenderStages);
|
||||
uint16_t arrayIndex = resourcesToMakeResidentGraphics[key].m_resourceArrayLen++;
|
||||
resourcesToMakeResidentGraphics[key].m_resourceArray[arrayIndex] = mtlconstantBufferResource;
|
||||
AZStd::pair <MTLResourceUsage,MTLRenderStages> key = AZStd::make_pair(MTLResourceUsageRead, mtlRenderStages);
|
||||
resourcesToMakeResidentGraphics[key].emplace(mtlconstantBufferResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,16 +438,18 @@ namespace AZ
|
||||
//Call UseResource on all resources for Compute stage
|
||||
for (const auto& key : resourcesToMakeResidentCompute)
|
||||
{
|
||||
[static_cast<id<MTLComputeCommandEncoder>>(commandEncoder) useResources: key.second.m_resourceArray.data()
|
||||
count: key.second.m_resourceArrayLen
|
||||
AZStd::vector<id <MTLResource>> resourcesToProcessVec(key.second.begin(), key.second.end());
|
||||
[static_cast<id<MTLComputeCommandEncoder>>(commandEncoder) useResources: &resourcesToProcessVec[0]
|
||||
count: resourcesToProcessVec.size()
|
||||
usage: key.first];
|
||||
}
|
||||
|
||||
//Call UseResource on all resources for Vertex and Fragment stages
|
||||
for (const auto& key : resourcesToMakeResidentGraphics)
|
||||
{
|
||||
[static_cast<id<MTLRenderCommandEncoder>>(commandEncoder) useResources: key.second.m_resourceArray.data()
|
||||
count: key.second.m_resourceArrayLen
|
||||
AZStd::vector<id <MTLResource>> resourcesToProcessVec(key.second.begin(), key.second.end());
|
||||
[static_cast<id<MTLRenderCommandEncoder>>(commandEncoder) useResources: &resourcesToProcessVec[0]
|
||||
count: resourcesToProcessVec.size()
|
||||
usage: key.first.first
|
||||
stages: key.first.second];
|
||||
}
|
||||
@@ -480,9 +480,9 @@ namespace AZ
|
||||
AZ_Assert(false, "Undefined Resource type");
|
||||
}
|
||||
}
|
||||
uint16_t arrayIndex = resourcesToMakeResidentMap[resourceUsage].m_resourceArrayLen++;
|
||||
|
||||
id<MTLResource> mtlResourceToBind = resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLResource>>();
|
||||
resourcesToMakeResidentMap[resourceUsage].m_resourceArray[arrayIndex] = mtlResourceToBind;
|
||||
resourcesToMakeResidentMap[resourceUsage].emplace(mtlResourceToBind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,9 +516,8 @@ namespace AZ
|
||||
}
|
||||
|
||||
AZStd::pair <MTLResourceUsage, MTLRenderStages> key = AZStd::make_pair(resourceUsage, mtlRenderStages);
|
||||
uint16_t arrayIndex = resourcesToMakeResidentMap[key].m_resourceArrayLen++;
|
||||
id<MTLResource> mtlResourceToBind = resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLResource>>();
|
||||
resourcesToMakeResidentMap[key].m_resourceArray[arrayIndex] = mtlResourceToBind;
|
||||
resourcesToMakeResidentMap[key].emplace(mtlResourceToBind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,15 +120,10 @@ namespace AZ
|
||||
ResourceBindingsMap m_resourceBindings;
|
||||
|
||||
static const int MaxEntriesInArgTable = 31;
|
||||
struct MetalResourceArray
|
||||
{
|
||||
AZStd::array<id <MTLResource>, MaxEntriesInArgTable> m_resourceArray;
|
||||
uint16_t m_resourceArrayLen = 0;
|
||||
};
|
||||
//Map to cache all the resources based on the usage as we can batch all the resources for a given usage
|
||||
using ComputeResourcesToMakeResidentMap = AZStd::unordered_map<MTLResourceUsage, MetalResourceArray>;
|
||||
//Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage
|
||||
using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map<AZStd::pair<MTLResourceUsage,MTLRenderStages>, MetalResourceArray>;
|
||||
//Map to cache all the resources based on the usage as we can batch all the resources for a given usage.
|
||||
using ComputeResourcesToMakeResidentMap = AZStd::unordered_map<MTLResourceUsage, AZStd::unordered_set<id <MTLResource>>>;
|
||||
//Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage.
|
||||
using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map<AZStd::pair<MTLResourceUsage,MTLRenderStages>, AZStd::unordered_set<id <MTLResource>>>;
|
||||
|
||||
void CollectResourcesForCompute(id<MTLCommandEncoder> encoder,
|
||||
const ResourceBindingsSet& resourceBindingData,
|
||||
|
||||
@@ -85,16 +85,36 @@ namespace AZ
|
||||
|
||||
uint64_t AsyncUploadQueue::QueueUpload(const RHI::BufferStreamRequest& uploadRequest)
|
||||
{
|
||||
uint64_t queueValue = m_uploadFence.Increment();
|
||||
Buffer& destBuffer = static_cast<Buffer&>(*uploadRequest.m_buffer);
|
||||
const MemoryView& destMemoryView = destBuffer.GetMemoryView();
|
||||
MTLStorageMode mtlStorageMode = destBuffer.GetMemoryView().GetStorageMode();
|
||||
RHI::BufferPool& bufferPool = static_cast<RHI::BufferPool&>(*destBuffer.GetPool());
|
||||
|
||||
// No need to use staging buffers since it's host memory.
|
||||
// We just map, copy and then unmap.
|
||||
if(mtlStorageMode == MTLStorageModeShared || mtlStorageMode == GetCPUGPUMemoryMode())
|
||||
{
|
||||
RHI::BufferMapRequest mapRequest;
|
||||
mapRequest.m_buffer = uploadRequest.m_buffer;
|
||||
mapRequest.m_byteCount = uploadRequest.m_byteCount;
|
||||
mapRequest.m_byteOffset = uploadRequest.m_byteOffset;
|
||||
RHI::BufferMapResponse mapResponse;
|
||||
bufferPool.MapBuffer(mapRequest, mapResponse);
|
||||
::memcpy(mapResponse.m_data, uploadRequest.m_sourceData, uploadRequest.m_byteCount);
|
||||
bufferPool.UnmapBuffer(*uploadRequest.m_buffer);
|
||||
if (uploadRequest.m_fenceToSignal)
|
||||
{
|
||||
uploadRequest.m_fenceToSignal->SignalOnCpu();
|
||||
}
|
||||
return m_uploadFence.GetPendingValue();
|
||||
}
|
||||
|
||||
const MemoryView& memoryView = static_cast<Buffer&>(*uploadRequest.m_buffer).GetMemoryView();
|
||||
RHI::Ptr<Memory> buffer = memoryView.GetMemory();
|
||||
|
||||
Fence* fenceToSignal = nullptr;
|
||||
uint64_t fenceToSignalValue = 0;
|
||||
|
||||
size_t byteCount = uploadRequest.m_byteCount;
|
||||
size_t byteOffset = memoryView.GetOffset() + uploadRequest.m_byteOffset;
|
||||
size_t byteOffset = destMemoryView.GetOffset() + uploadRequest.m_byteOffset;
|
||||
uint64_t queueValue = m_uploadFence.Increment();
|
||||
|
||||
const uint8_t* sourceData = reinterpret_cast<const uint8_t*>(uploadRequest.m_sourceData);
|
||||
|
||||
if (uploadRequest.m_fenceToSignal)
|
||||
@@ -125,11 +145,11 @@ namespace AZ
|
||||
}
|
||||
|
||||
id<MTLBlitCommandEncoder> blitEncoder = [framePacket->m_mtlCommandBuffer blitCommandEncoder];
|
||||
[blitEncoder copyFromBuffer:framePacket->m_stagingResource
|
||||
sourceOffset:0
|
||||
toBuffer:buffer->GetGpuAddress<id<MTLBuffer>>()
|
||||
destinationOffset:byteOffset + pendingByteOffset
|
||||
size:bytesToCopy];
|
||||
[blitEncoder copyFromBuffer: framePacket->m_stagingResource
|
||||
sourceOffset: 0
|
||||
toBuffer: destMemoryView.GetGpuAddress<id<MTLBuffer>>()
|
||||
destinationOffset: byteOffset + pendingByteOffset
|
||||
size: bytesToCopy];
|
||||
[blitEncoder endEncoding];
|
||||
blitEncoder = nil;
|
||||
|
||||
|
||||
@@ -40,9 +40,8 @@ namespace AZ
|
||||
buffer->m_pendingResolves++;
|
||||
|
||||
uploadRequest.m_attachmentBuffer = buffer;
|
||||
uploadRequest.m_byteOffset = request.m_byteOffset;
|
||||
uploadRequest.m_byteOffset = buffer->GetMemoryView().GetOffset() + request.m_byteOffset;
|
||||
uploadRequest.m_stagingBuffer = stagingBuffer;
|
||||
uploadRequest.m_byteSize = request.m_byteCount;
|
||||
|
||||
return stagingBuffer->GetMemoryView().GetCpuAddress();
|
||||
}
|
||||
@@ -64,12 +63,15 @@ namespace AZ
|
||||
AZ_Assert(stagingBuffer, "Staging Buffer is null.");
|
||||
AZ_Assert(destBuffer, "Attachment Buffer is null.");
|
||||
|
||||
//Inform the GPU that the CPU has modified the staging buffer.
|
||||
Platform::SynchronizeBufferOnCPU(stagingBuffer->GetMemoryView().GetGpuAddress<id<MTLBuffer>>(), stagingBuffer->GetMemoryView().GetOffset(), stagingBuffer->GetMemoryView().GetSize());
|
||||
|
||||
RHI::CopyBufferDescriptor copyDescriptor;
|
||||
copyDescriptor.m_sourceBuffer = stagingBuffer;
|
||||
copyDescriptor.m_sourceOffset = 0;
|
||||
copyDescriptor.m_sourceOffset = stagingBuffer->GetMemoryView().GetOffset();
|
||||
copyDescriptor.m_destinationBuffer = destBuffer;
|
||||
copyDescriptor.m_destinationOffset = static_cast<uint32_t>(packet.m_byteOffset);
|
||||
copyDescriptor.m_size = static_cast<uint32_t>(packet.m_byteSize);
|
||||
copyDescriptor.m_size = stagingBuffer->GetMemoryView().GetSize();
|
||||
|
||||
commandList.Submit(RHI::CopyItem(copyDescriptor));
|
||||
device.QueueForRelease(stagingBuffer->GetMemoryView());
|
||||
|
||||
@@ -54,7 +54,6 @@ namespace AZ
|
||||
Buffer* m_attachmentBuffer = nullptr;
|
||||
RHI::Ptr<Buffer> m_stagingBuffer;
|
||||
size_t m_byteOffset = 0;
|
||||
size_t m_byteSize = 0;
|
||||
};
|
||||
|
||||
AZStd::mutex m_uploadPacketsLock;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace AZ
|
||||
if (memoryView.IsValid())
|
||||
{
|
||||
heapMemoryUsage.m_residentInBytes += m_descriptor.m_pageSizeInBytes;
|
||||
memoryView.SetName("BufferPage");
|
||||
memoryView.SetName(AZStd::string::format("BufferPage_%s", AZ::Uuid::CreateRandom().ToString<AZStd::string>().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -55,7 +55,11 @@ namespace AZ
|
||||
const auto& image = static_cast<const Image&>(resourceBase);
|
||||
const RHI::ImageViewDescriptor& descriptor = GetDescriptor();
|
||||
|
||||
AZ_Assert(image.GetNativeImage() != VK_NULL_HANDLE, "Image has not been initialized.");
|
||||
// this can happen when image has been invalidated/released right before re-compiling the image
|
||||
if (image.GetNativeImage() == VK_NULL_HANDLE)
|
||||
{
|
||||
return RHI::ResultCode::Fail;
|
||||
}
|
||||
|
||||
RHI::Format viewFormat = descriptor.m_overrideFormat;
|
||||
// If an image is not owner of native image, it is a swapchain image.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RPI
|
||||
{
|
||||
//! Bus for post-load initialization of assets.
|
||||
//! Assets that need to do post-load initialization should connect to this bus in their asset handler's LoadAssetData() function.
|
||||
//! Be sure to disconnect from this bus as soon as initialization is complete, as it will be called every frame.
|
||||
//! (Note this bus is needed rather than utilizing TickBus because TickBus is not protected by a mutex which means it can't be
|
||||
//! connected on an asset load job thread).
|
||||
class AssetInitEvents
|
||||
: public EBusTraits
|
||||
{
|
||||
public:
|
||||
// EBus Configuration
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
typedef AZStd::recursive_mutex MutexType;
|
||||
|
||||
//! This function is called every frame on the main thread to perform any necessary post-load initialization.
|
||||
//! Connect to the bus after loading the asset data, and disconnect when initialization is complete.
|
||||
//! @return whether initialization was successful
|
||||
virtual bool PostLoadInit() = 0;
|
||||
};
|
||||
|
||||
using AssetInitBus = AZ::EBus<AssetInitEvents>;
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@@ -12,6 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/Shader/ShaderVariant.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h>
|
||||
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroup.h>
|
||||
@@ -57,6 +58,7 @@ namespace AZ
|
||||
: public Data::InstanceData
|
||||
, public Data::AssetBus::Handler
|
||||
, public ShaderVariantFinderNotificationBus::Handler
|
||||
, public ShaderReloadNotificationBus::Handler
|
||||
{
|
||||
friend class ShaderSystem;
|
||||
public:
|
||||
@@ -149,6 +151,15 @@ namespace AZ
|
||||
void OnShaderVariantTreeAssetReady(Data::Asset<ShaderVariantTreeAsset> /*shaderVariantTreeAsset*/, bool /*isError*/) override {};
|
||||
void OnShaderVariantAssetReady(Data::Asset<ShaderVariantAsset> shaderVariantAsset, bool IsError) override;
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// ShaderReloadNotificationBus overrides...
|
||||
void OnShaderAssetReinitialized(const Data::Asset<ShaderAsset>& shaderAsset) override;
|
||||
// Note we don't need OnShaderVariantReinitialized because the Shader class doesn't do anything with the data inside
|
||||
// the ShaderVariant object. The only thing we might want to do is propagate the message upward, but that's unnecessary
|
||||
// because the ShaderReloadNotificationBus uses the Shader's AssetId as the ID for all messages including those from the variants.
|
||||
// And of course we don't need to handle OnShaderReinitialized because this *is* this Shader.
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Returns the path to the pipeline library cache file.
|
||||
AZStd::string GetPipelineLibraryPath() const;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AtomCore/std/containers/array_view.h>
|
||||
|
||||
#include <Atom/RPI.Public/AssetInitBus.h>
|
||||
#include <Atom/RPI.Reflect/Base.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialPropertyValue.h>
|
||||
@@ -38,6 +39,7 @@ namespace AZ
|
||||
: public AZ::Data::AssetData
|
||||
, public Data::AssetBus::Handler
|
||||
, public MaterialReloadNotificationBus::Handler
|
||||
, public AssetInitBus::Handler
|
||||
{
|
||||
friend class MaterialAssetCreator;
|
||||
friend class MaterialAssetHandler;
|
||||
@@ -90,13 +92,17 @@ namespace AZ
|
||||
AZStd::array_view<MaterialPropertyValue> GetPropertyValues() const;
|
||||
|
||||
private:
|
||||
bool PostLoadInit();
|
||||
bool PostLoadInit() override;
|
||||
|
||||
//! Called by asset creators to assign the asset to a ready state.
|
||||
void SetReady();
|
||||
|
||||
// AssetBus overrides...
|
||||
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
|
||||
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
|
||||
|
||||
//! Replaces the MaterialTypeAsset when a reload occurs
|
||||
void ReinitializeMaterialTypeAsset(Data::Asset<Data::AssetData> asset);
|
||||
|
||||
// MaterialReloadNotificationBus overrides...
|
||||
void OnMaterialTypeAssetReinitialized(const Data::Asset<MaterialTypeAsset>& materialTypeAsset) override;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AtomCore/std/containers/array_view.h>
|
||||
|
||||
#include <Atom/RPI.Public/AssetInitBus.h>
|
||||
#include <Atom/RPI.Reflect/Base.h>
|
||||
#include <Atom/RPI.Reflect/Material/ShaderCollection.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialPropertiesLayout.h>
|
||||
@@ -52,6 +53,7 @@ namespace AZ
|
||||
class MaterialTypeAsset
|
||||
: public AZ::Data::AssetData
|
||||
, public Data::AssetBus::MultiHandler
|
||||
, public AssetInitBus::Handler
|
||||
{
|
||||
friend class MaterialTypeAssetCreator;
|
||||
friend class MaterialTypeAssetHandler;
|
||||
@@ -100,13 +102,17 @@ namespace AZ
|
||||
MaterialUvNameMap GetUvNameMap() const;
|
||||
|
||||
private:
|
||||
bool PostLoadInit();
|
||||
bool PostLoadInit() override;
|
||||
|
||||
//! Called by asset creators to assign the asset to a ready state.
|
||||
void SetReady();
|
||||
|
||||
// AssetBus overrides...
|
||||
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
|
||||
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
|
||||
|
||||
//! Replaces the appropriate asset members when a reload occurs
|
||||
void ReinitializeAsset(Data::Asset<Data::AssetData> asset);
|
||||
|
||||
//! Holds values for each material property, used to initialize Material instances.
|
||||
//! This is indexed by MaterialPropertyIndex and aligns with entries in m_materialPropertiesLayout.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
|
||||
#include <Atom/RPI.Public/AssetInitBus.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetHandler.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroupLayout.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderVariantAsset.h>
|
||||
@@ -40,6 +41,7 @@ namespace AZ
|
||||
: public Data::AssetData
|
||||
, public ShaderVariantFinderNotificationBus::Handler
|
||||
, public Data::AssetBus::Handler
|
||||
, public AssetInitBus::Handler
|
||||
{
|
||||
friend class ShaderAssetCreator;
|
||||
friend class ShaderAssetHandler;
|
||||
@@ -134,8 +136,11 @@ namespace AZ
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/// AssetBus overrides
|
||||
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
|
||||
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
void ReinitializeRootShaderVariant(Data::Asset<Data::AssetData> asset);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/// ShaderVariantFinderNotificationBus overrides
|
||||
void OnShaderVariantTreeAssetReady(Data::Asset<ShaderVariantTreeAsset> shaderVariantTreeAsset, bool isError) override;
|
||||
@@ -165,8 +170,13 @@ namespace AZ
|
||||
RHI::ShaderStageAttributeMapList m_attributeMaps;
|
||||
};
|
||||
|
||||
bool FinalizeAfterLoad();
|
||||
bool PostLoadInit() override;
|
||||
void SetReady();
|
||||
|
||||
//! SelectShaderApiData() must be called before most other ShaderAsset functions.
|
||||
bool SelectShaderApiData();
|
||||
|
||||
//! Returns the active ShaderApiDataContainer which was selected in SelectShaderApiData().
|
||||
ShaderApiDataContainer& GetCurrentShaderApiData();
|
||||
const ShaderApiDataContainer& GetCurrentShaderApiData() const;
|
||||
|
||||
@@ -216,7 +226,6 @@ namespace AZ
|
||||
const Data::Asset<Data::AssetData>& asset,
|
||||
AZStd::shared_ptr<Data::AssetDataStream> stream,
|
||||
const Data::AssetFilterCB& assetLoadFilterCB) override;
|
||||
Data::AssetHandler::LoadResult PostLoadInit(const Data::Asset<Data::AssetData>& asset);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
|
||||
#include <Atom/RPI.Public/AssetInitBus.h>
|
||||
#include <Atom/RPI.Public/FeatureProcessor.h>
|
||||
#include <Atom/RPI.Public/GpuQuery/GpuQueryTypes.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
@@ -240,6 +241,8 @@ namespace AZ
|
||||
}
|
||||
AZ_ATOM_PROFILE_FUNCTION("RPI", "RPISystem: SimulationTick");
|
||||
|
||||
AssetInitBus::Broadcast(&AssetInitBus::Events::PostLoadInit);
|
||||
|
||||
// Update tick time info
|
||||
FillTickTimeInfo();
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <AtomCore/Instance/InstanceDatabase.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderReloadDebugTracker.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -55,8 +54,9 @@ namespace AZ
|
||||
|
||||
RHI::ResultCode Shader::Init(ShaderAsset& shaderAsset)
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
ShaderReloadNotificationBus::Handler::BusDisconnect();
|
||||
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
|
||||
ShaderVariantFinderNotificationBus::Handler::BusConnect(shaderAsset.GetId());
|
||||
|
||||
RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get();
|
||||
RHI::DrawListTagRegistry* drawListTagRegistry = rhiSystem->GetDrawListTagRegistry();
|
||||
@@ -100,8 +100,10 @@ namespace AZ
|
||||
AZ_Error("Shader", false, "Failed to acquire a DrawListTag. Entries are full.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ShaderVariantFinderNotificationBus::Handler::BusConnect(m_asset.GetId());
|
||||
Data::AssetBus::Handler::BusConnect(m_asset.GetId());
|
||||
ShaderReloadNotificationBus::Handler::BusConnect(m_asset.GetId());
|
||||
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
@@ -110,6 +112,7 @@ namespace AZ
|
||||
{
|
||||
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
ShaderReloadNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
if (m_pipelineLibraryHandle.IsValid())
|
||||
{
|
||||
@@ -139,7 +142,6 @@ namespace AZ
|
||||
Data::Asset<ShaderAsset> newAsset = { asset.GetAs<ShaderAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ_Assert(newAsset, "Reloaded ShaderAsset is null");
|
||||
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
Init(*newAsset.Get());
|
||||
ShaderReloadNotificationBus::Event(asset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderReinitialized, *this);
|
||||
}
|
||||
@@ -196,6 +198,19 @@ namespace AZ
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// ShaderReloadNotificationBus overrides...
|
||||
void Shader::OnShaderAssetReinitialized(const Data::Asset<ShaderAsset>& shaderAsset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Shader::OnShaderAssetReinitialized %s", this, shaderAsset.GetHint().c_str());
|
||||
|
||||
Init(*m_asset.Get());
|
||||
ShaderReloadNotificationBus::Event(shaderAsset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderReinitialized, *this);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ConstPtr<RHI::PipelineLibraryData> Shader::LoadPipelineLibrary() const
|
||||
{
|
||||
if (IO::FileIOBase::GetInstance())
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -47,6 +48,7 @@ namespace AZ
|
||||
{
|
||||
MaterialReloadNotificationBus::Handler::BusDisconnect();
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
const Data::Asset<MaterialTypeAsset>& MaterialAsset::GetMaterialTypeAsset() const
|
||||
@@ -97,6 +99,8 @@ namespace AZ
|
||||
{
|
||||
if (!m_materialTypeAsset.Get())
|
||||
{
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
|
||||
// Any MaterialAsset with invalid MaterialTypeAsset is not a successfully-loaded asset.
|
||||
return false;
|
||||
}
|
||||
@@ -104,6 +108,8 @@ namespace AZ
|
||||
{
|
||||
Data::AssetBus::Handler::BusConnect(m_materialTypeAsset.GetId());
|
||||
MaterialReloadNotificationBus::Handler::BusConnect(m_materialTypeAsset.GetId());
|
||||
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -116,11 +122,9 @@ namespace AZ
|
||||
// Ultimately it's the Material that cares about these changes, so we just forward any signal we get.
|
||||
MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialAssetReinitialized, Data::Asset<MaterialAsset>{this, AZ::Data::AssetLoadBehavior::PreLoad});
|
||||
}
|
||||
|
||||
void MaterialAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
||||
|
||||
void MaterialAsset::ReinitializeMaterialTypeAsset(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
|
||||
|
||||
Data::Asset<MaterialTypeAsset> newMaterialTypeAsset = { asset.GetAs<MaterialTypeAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
|
||||
if (newMaterialTypeAsset)
|
||||
@@ -135,16 +139,31 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
|
||||
ReinitializeMaterialTypeAsset(asset);
|
||||
}
|
||||
|
||||
void MaterialAsset::OnAssetReady(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
// Regarding why we listen to both OnAssetReloaded and OnAssetReady, see explanation in ShaderAsset::OnAssetReady.
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnAssetReady %s", this, asset.GetHint().c_str());
|
||||
ReinitializeMaterialTypeAsset(asset);
|
||||
}
|
||||
|
||||
Data::AssetHandler::LoadResult MaterialAssetHandler::LoadAssetData(
|
||||
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
|
||||
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
|
||||
const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
{
|
||||
Data::AssetHandler::LoadResult baseResult = Base::LoadAssetData(asset, stream, assetLoadFilterCB);
|
||||
bool postLoadResult = asset.GetAs<MaterialAsset>()->PostLoadInit();
|
||||
return ((baseResult == Data::AssetHandler::LoadResult::LoadComplete) && postLoadResult) ?
|
||||
Data::AssetHandler::LoadResult::LoadComplete :
|
||||
Data::AssetHandler::LoadResult::Error;
|
||||
if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete)
|
||||
{
|
||||
asset.GetAs<MaterialAsset>()->AssetInitBus::Handler::BusConnect();
|
||||
return Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
|
||||
} // namespace RPI
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace AZ
|
||||
MaterialTypeAsset::~MaterialTypeAsset()
|
||||
{
|
||||
Data::AssetBus::MultiHandler::BusDisconnect();
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
const ShaderCollection& MaterialTypeAsset::GetShaderCollection() const
|
||||
@@ -116,6 +117,8 @@ namespace AZ
|
||||
Data::AssetBus::MultiHandler::BusConnect(shaderItem.GetShaderAsset().GetId());
|
||||
}
|
||||
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -127,11 +130,9 @@ namespace AZ
|
||||
assetToReplace = newAsset;
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTypeAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
||||
|
||||
void MaterialTypeAsset::ReinitializeAsset(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialTypeAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
|
||||
|
||||
// The order of asset reloads is non-deterministic. If the MaterialTypeAsset reloads before these
|
||||
// dependency assets, this will make sure the MaterialTypeAsset gets the latest ones when they reload.
|
||||
// Or in some cases a these assets could get updated and reloaded without reloading the MaterialTypeAsset at all.
|
||||
@@ -146,16 +147,31 @@ namespace AZ
|
||||
MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialTypeAssetReinitialized, Data::Asset<MaterialTypeAsset>{this, AZ::Data::AssetLoadBehavior::PreLoad});
|
||||
}
|
||||
|
||||
void MaterialTypeAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialTypeAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
|
||||
ReinitializeAsset(asset);
|
||||
}
|
||||
|
||||
void MaterialTypeAsset::OnAssetReady(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
// Regarding why we listen to both OnAssetReloaded and OnAssetReady, see explanation in ShaderAsset::OnAssetReady.
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialTypeAsset::OnAssetReady %s", this, asset.GetHint().c_str());
|
||||
ReinitializeAsset(asset);
|
||||
}
|
||||
|
||||
AZ::Data::AssetHandler::LoadResult MaterialTypeAssetHandler::LoadAssetData(
|
||||
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
|
||||
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
|
||||
const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
{
|
||||
Data::AssetHandler::LoadResult baseResult = Base::LoadAssetData(asset, stream, assetLoadFilterCB);
|
||||
bool postLoadResult = asset.GetAs<MaterialTypeAsset>()->PostLoadInit();
|
||||
return ((baseResult == Data::AssetHandler::LoadResult::LoadComplete) && postLoadResult) ?
|
||||
Data::AssetHandler::LoadResult::LoadComplete :
|
||||
Data::AssetHandler::LoadResult::Error;
|
||||
if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete)
|
||||
{
|
||||
asset.GetAs<MaterialTypeAsset>()->AssetInitBus::Handler::BusConnect();
|
||||
return Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace AZ
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
const Name& ShaderAsset::GetName() const
|
||||
@@ -331,8 +332,8 @@ namespace AZ
|
||||
// We may only endup here when running in a Builder context.
|
||||
return m_perAPIShaderData[0];
|
||||
}
|
||||
|
||||
bool ShaderAsset::FinalizeAfterLoad()
|
||||
|
||||
bool ShaderAsset::SelectShaderApiData()
|
||||
{
|
||||
// Use the current RHI that is active to select which shader data to use.
|
||||
// We don't assert if the Factory is not available because this method could be called during build time,
|
||||
@@ -370,28 +371,51 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShaderAsset::PostLoadInit()
|
||||
{
|
||||
// Once the ShaderAsset is loaded, it is necessary to listen for changes in the Root Variant Asset.
|
||||
Data::AssetBus::Handler::BusConnect(GetRootVariant().GetId());
|
||||
ShaderVariantFinderNotificationBus::Handler::BusConnect(GetId());
|
||||
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShaderAsset::ReinitializeRootShaderVariant(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
Data::Asset<ShaderVariantAsset> shaderVariantAsset = { asset.GetAs<ShaderVariantAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ_Assert(shaderVariantAsset->GetStableId() == RootShaderVariantStableId, "Was expecting to update the root variant");
|
||||
GetCurrentShaderApiData().m_rootShaderVariantAsset = asset;
|
||||
ShaderReloadNotificationBus::Event(GetId(), &ShaderReloadNotificationBus::Events::OnShaderAssetReinitialized, Data::Asset<ShaderAsset>{ this, AZ::Data::AssetLoadBehavior::PreLoad } );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// AssetBus overrides...
|
||||
void ShaderAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->ShaderAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
|
||||
ReinitializeRootShaderVariant(asset);
|
||||
}
|
||||
void ShaderAsset::OnAssetReady(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
// We have to listen to OnAssetReady, OnAssetReloaded isn't enough, because of the following scenario:
|
||||
// The user changes a .shader file, which causes the AP to rebuild the ShaderAsset and root ShaderVariantAsset.
|
||||
// 1) Thread A creates the new ShaderAsset, loads it, and gets the old ShaderVariantAsset.
|
||||
// 2) Thread B creates the new ShaderVariantAsset, loads it, and calls OnAssetReloaded.
|
||||
// 3) Main thread calls ShaderAsset::PostLoadInit which connects to the AssetBus but it's too late to receive OnAssetReloaded,
|
||||
// so it continues using the old ShaderVariantAsset instead of the new one.
|
||||
// The OnAssetReady bus function is called automatically whenever a connection to AssetBus is made, so listening to this gives
|
||||
// us the opportunity to assign the appropriate ShaderVariantAsset.
|
||||
|
||||
Data::Asset<ShaderVariantAsset> shaderVariantAsset = { asset.GetAs<ShaderVariantAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ_Assert(shaderVariantAsset->GetStableId() == RootShaderVariantStableId,
|
||||
"Was expecting to update the root variant");
|
||||
GetCurrentShaderApiData().m_rootShaderVariantAsset = asset;
|
||||
|
||||
ShaderReloadNotificationBus::Event(GetId(), &ShaderReloadNotificationBus::Events::OnShaderAssetReinitialized, Data::Asset<ShaderAsset>{ this, AZ::Data::AssetLoadBehavior::PreLoad } );
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->ShaderAsset::OnAssetReady %s", this, asset.GetHint().c_str());
|
||||
ReinitializeRootShaderVariant(asset);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/// ShaderVariantFinderNotificationBus overrides
|
||||
void ShaderAsset::OnShaderVariantTreeAssetReady(Data::Asset<ShaderVariantTreeAsset> shaderVariantTreeAsset, bool isError)
|
||||
@@ -425,25 +449,25 @@ namespace AZ
|
||||
{
|
||||
if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete)
|
||||
{
|
||||
return PostLoadInit(asset);
|
||||
}
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
ShaderAsset* shaderAsset = asset.GetAs<ShaderAsset>();
|
||||
|
||||
Data::AssetHandler::LoadResult ShaderAssetHandler::PostLoadInit(const Data::Asset<Data::AssetData>& asset)
|
||||
{
|
||||
if (ShaderAsset* shaderAsset = asset.GetAs<ShaderAsset>())
|
||||
{
|
||||
if (!shaderAsset->FinalizeAfterLoad())
|
||||
// The shader API selection must occur immediately ofter loading, on the same thread, rather than
|
||||
// deferring to AssetInitBus::PostLoadInit. Many functions in the ShaderAsset class are invalid
|
||||
// until after SelectShaderApiData() is called and some client code may need to access data in
|
||||
// the ShaderAsset before then.
|
||||
if (!shaderAsset->SelectShaderApiData())
|
||||
{
|
||||
AZ_Error("ShaderAssetHandler", false, "Shader asset failed to finalize.");
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
|
||||
shaderAsset->AssetInitBus::Handler::BusConnect();
|
||||
|
||||
return Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace RPI
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_asset->FinalizeAfterLoad())
|
||||
if (!m_asset->SelectShaderApiData())
|
||||
{
|
||||
ReportError("Failed to finalize the ShaderAsset.");
|
||||
return false;
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace AZ
|
||||
AZ::Data::Asset<ShaderAsset> SerializeInHelper(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
AZ::Data::Asset<ShaderAsset> asset = Base::SerializeIn(assetId);
|
||||
asset->FinalizeAfterLoad();
|
||||
asset->SelectShaderApiData();
|
||||
asset->SetReady();
|
||||
return asset;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Include/Atom/RPI.Public/AssetInitBus.h
|
||||
Include/Atom/RPI.Public/Base.h
|
||||
Include/Atom/RPI.Public/Culling.h
|
||||
Include/Atom/RPI.Public/FeatureProcessor.h
|
||||
|
||||
@@ -8,3 +8,7 @@
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
add_subdirectory(LookDevelopmentStudioPixar)
|
||||
add_subdirectory(ReferenceMaterials)
|
||||
add_subdirectory(Sponza)
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6cfa740b94b898e85d93f970a7d7d76581e065662dd8e2b350ea076bd6fe8d35
|
||||
size 37187591
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:254aacfb72ed12743f83740f9eb31a01d28c40c0abeacc39907d20ab82f42636
|
||||
size 390896034
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c164a61daf248f57eacee5167eb9d098a49d7dfc7aea6c68007d7e0c06a29906
|
||||
size 74644256
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ade44968832bf7a3e9cab95ddccc4018c7250b07437cddc51c784815b1dcb930
|
||||
size 392066587
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:51dacbe0048b892a196ea9e6178cca908ba46a6f86b7ec979cf0fd7e381720b3
|
||||
size 112681262
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Materials/Bricks038_8K/Bricks038_8K_AmbientOcclusion.png"
|
||||
},
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.496940553188324,
|
||||
0.496940553188324,
|
||||
0.496940553188324,
|
||||
1.0
|
||||
],
|
||||
"factor": 0.6464645862579346,
|
||||
"textureBlendMode": "LinearLight",
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_BaseColor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Normal.png"
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "POM",
|
||||
"factor": 0.02500000037252903,
|
||||
"pdo": true,
|
||||
"quality": "Ultra",
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Displacement.png"
|
||||
},
|
||||
"roughness": {
|
||||
"upperBound": 0.5,
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Roughness.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.19562065601348878,
|
||||
0.22017242014408112,
|
||||
0.2503242492675781,
|
||||
1.0
|
||||
],
|
||||
"factor": 0.30000001192092898,
|
||||
"textureBlendMode": "LinearLight",
|
||||
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_BaseColor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"enable": true,
|
||||
"normalMap": "Materials/Concrete016_8K/roller_painted_metal_normal.tif",
|
||||
"roughness": 0.18181820213794709
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.6499999761581421,
|
||||
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Normal.png"
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.019999999552965165,
|
||||
"quality": "Ultra",
|
||||
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Displacement.png",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Roughness.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:42d3ef187f7f98bcee42ffc4ae0629370f4fc19e6532c2db8cc130ce9ece072a
|
||||
size 74279846
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b8e8149f5609ae85f876183f3b4461de4a334658660fc187c5fd469752e5b2d6
|
||||
size 93715669
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6f997219d3bb846ea0db7786a394e508d59f99be9548b63d3c73824d97cdacd7
|
||||
size 379009988
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9ea7f520b28d5232697ea9e4fb4cc7d655069d05f9de0313c92c56e4c1526556
|
||||
size 25594794
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:94c9398b1f5d71aa3f4debb5a9571f0d9a4b1b1992b662e35ca94996b507e4ff
|
||||
size 6933173
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_BaseColor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"enable": true,
|
||||
"normalMap": "Materials/Fabric001_8K/Fabric001_8K_Normal.png",
|
||||
"roughness": 0.4040403962135315
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_Normal.png"
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.004999999888241291,
|
||||
"quality": "Ultra",
|
||||
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_Displacement.png"
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_Roughness.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e04ea2d456e13fb45a2c4f3f88d2ed07c2799fbdaeba6b52bab64dcd84fefc77
|
||||
size 69539547
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4b41f8b8aa685c443216220063cd6c1de3f620ef66776aecd374025a689dec77
|
||||
size 19743435
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:009302f8be232e7fd6b23d368c85afdb74ea4deda8147152f2c92d116a2ac585
|
||||
size 56894065
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a557862deee7f4ff9bb113f66b1fd432871338d5b801edec7c50f70aa302557d
|
||||
size 26820294
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_BaseColor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"enable": true,
|
||||
"normalMap": "Materials/Fabric030_4K/Fabric030_4K_Normal.png",
|
||||
"roughness": 0.7676767706871033,
|
||||
"roughnessMap": "Materials/Fabric030_4K/Fabric030_4K_Roughness.png",
|
||||
"useInfluenceMap": false
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_Normal.png"
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.0020000000949949028,
|
||||
"pdo": true,
|
||||
"quality": "Medium",
|
||||
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_Displacement.png"
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_Roughness.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:eb2f62e3166428f137b8712f4527c62d3905a8e177840b56fb1775e39417448d
|
||||
size 11268075
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:194674f50a0c868d2a2c12cc7a4ddbe5abbe6ebb9687be4be4e49eece3976e29
|
||||
size 94910229
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c3f29be8c7afe73b12f5c7df3e3ffd69a0bce46218cef57f73c11638aa07ccc3
|
||||
size 19243987
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0bc0c08f0b8e33b3251f7dba85c5042138a201e912752135a0bdcfe9c381d5ab
|
||||
size 63142427
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:aa5ffdb5b9ef2363c58eb85b47adc9e1bdde13256bdc6de05cbfb5b04cf91f91
|
||||
size 26802284
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"occlusion": {
|
||||
"diffuseFactor": 0.30000001192092898,
|
||||
"diffuseTextureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_AmbientOcclusion.png"
|
||||
},
|
||||
"baseColor": {
|
||||
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_BaseColor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_Normal.png"
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.009999999776482582,
|
||||
"pdo": true,
|
||||
"quality": "Ultra",
|
||||
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_Displacement.png"
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_Roughness.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c271d8a3f305bacafb74037898e8d5841fb8a2fedc0092cbe14134d2ec891d01
|
||||
size 115473298
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:720d85d530e192da6e7daaab89501a9612e145f4aa41405958ff49f765f072ab
|
||||
size 325006015
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:71f256cde0427ab8558b09d743d9379899a9a72b4388ca14529bfc9090dd811e
|
||||
size 88972723
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4e7eb03dd1ae07ade8e8e99fe6f522fd268ef8e00d3e3f9c3594d9f887b864d8
|
||||
size 382741403
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3f065a3929ea98b54c725515528c2d40b3908a352d497bcce2f088a91b623b11
|
||||
size 98105202
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.496940553188324,
|
||||
0.496940553188324,
|
||||
0.496940553188324,
|
||||
1.0
|
||||
],
|
||||
"textureBlendMode": "LinearLight",
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_BaseColor.png",
|
||||
"useTexture": false
|
||||
},
|
||||
"emissive": {
|
||||
"useTexture": false
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Normal.png",
|
||||
"useTexture": false
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "POM",
|
||||
"factor": 0.02500000037252903,
|
||||
"pdo": true,
|
||||
"quality": "Ultra",
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Displacement.png",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.4343433976173401,
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Roughness.png",
|
||||
"useTexture": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.496940553188324,
|
||||
0.496940553188324,
|
||||
0.496940553188324,
|
||||
1.0
|
||||
],
|
||||
"factor": 0.6464645862579346,
|
||||
"textureBlendMode": "LinearLight"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Normal.png"
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "POM",
|
||||
"factor": 0.02500000037252903,
|
||||
"pdo": true,
|
||||
"quality": "Ultra",
|
||||
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Displacement.png"
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Roughness.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:486712a84618c56b79c6cb12966fe5c44a70bc6573c5eed74381ccdd68592e06
|
||||
size 20574
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c2826872e937f6794a62f75b10b5217dd541fc419ebc1ebe2d4469a38344332
|
||||
size 24339
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9d603f570813bad6c2db2c055114a5990d5113f7b2c11074a0e8ba83c2007490
|
||||
size 1849470
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d2715b8a38b8198d84927a881440328b2fe565be27737c970da9366c9eab566a
|
||||
size 3886331
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1658a8fbf035d669c88e112c3922f223e77cccece7cb51a0fa2df50412fb02d0
|
||||
size 435923
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b63a99deac3bcf4b9d93359edb68bb22f28da4c9c3d5a7f1d715a84e8c603519
|
||||
size 7522972
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d4065dfea401af3b53bcd2906535239d54628c800704f96acbd2767042bc432c
|
||||
size 8792244
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:93f5e3663a69d9e29bcc64715363420fb8a1331c8f714b9dbdf4d6a6577f943b
|
||||
size 175120
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d09adbd3e1ef1f1bed98c9ea3034c323bf3f1be25faba5d3721310f46029b0bb
|
||||
size 24608
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:391a2e1931263446ee2f38810ee9fc4bc4de29c171cf557398d6bf4a0eba1263
|
||||
size 110384
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
1.600000023841858,
|
||||
1.600000023841858,
|
||||
1.600000023841858,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"emissive": {
|
||||
"enable": true,
|
||||
"intensity": 0.0
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c6c174dde81f8a37f591108b62666347920d0765f3e61c6d557ebf807f38cd3b
|
||||
size 4512544
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.4000000059604645,
|
||||
0.4000000059604645,
|
||||
0.4000000059604645,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.25
|
||||
}
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.6000000238418579,
|
||||
0.6000000238418579,
|
||||
0.6000000238418579,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.25
|
||||
}
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.8199999928474426,
|
||||
0.8199999928474426,
|
||||
0.8199999928474426,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.25
|
||||
}
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"clearCoat": {
|
||||
"enable": true,
|
||||
"normalMap": "EngineAssets/Textures/perlinNoiseNormal_ddn.tif",
|
||||
"normalStrength": 0.10000000149011612
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 0.10000000149011612
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.05000000074505806,
|
||||
"textureMap": "Materials/round_metal_flecks_4096_normal.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"specularF0": {
|
||||
"enableMultiScatterCompensation": true
|
||||
}
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"clearCoat": {
|
||||
"enable": true,
|
||||
"normalMap": "Materials/Concrete016_8K/roller_painted_metal_normal.tif",
|
||||
"roughness": 0.1414141058921814
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 0.20000000298023225
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.10000000149011612,
|
||||
"textureMap": "Materials/round_metal_flecks_2048_normal.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.5
|
||||
},
|
||||
"uv": {
|
||||
"tileU": 2.0,
|
||||
"tileV": 2.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c2f3ea6e00e15901263c06fee2aa4d54b96277f7ac103dd8b3c0f8441158d31e
|
||||
size 83584
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user