Merge branch 'main' into debug_draw_transform

This commit is contained in:
greerdv
2021-05-11 09:50:51 +01:00
335 changed files with 821 additions and 39058 deletions
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# Test case ID : C18977329
# Test Case Title : Add cloth simulation to a Mesh
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977329
# fmt: off
class Tests:
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# Test case ID : C18977330
# Test Case Title : Add cloth simulation to an Actor
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977330
# fmt: off
class Tests:
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# Test case ID : C28798177
# Test Case Title : White Box Tool Component can be added to an Entity
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798177
# fmt:off
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# Test case ID : C28798205
# Test Case Title : From the White Box Component Card the White Box Mesh can be set to be invisible in Game View
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798205
# fmt:off
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# Test case ID : C29279329
# Test Case Title : White Box mesh shape can be changed with the Default Shape dropdown on the Component
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/29279329
# fmt:off
@@ -68,7 +68,7 @@ def C14976308_ScriptCanvas_SetKinematicTargetTransform():
the script deactivates Signal, Sphere's transform will update to that of Transform_Target.
NOTE: There is a known bug (LY-107723) which causes the rotation to update to a value that is not sufficiently close
to the expected result when using Set Kinematic Target which will cause the test to fail:
https://jira.agscollab.com/browse/LY-107723
LY-107723
Test Steps:
1) Open level and enter game mode
@@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# Test case ID : C3510644
# Test Case Title : Check that the collision layer and collision group of the terrain can be changed
# and the collision behavior of the terrain changes accordingly
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/3510644
# fmt: off
@@ -239,7 +239,7 @@ def C6321601_Force_HighValuesDirectionAxes():
force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
# Wait for 3 secs, because there is a known bug identified and filed in
# JIRA https://jira.agscollab.com/browse/LY-107677
# JIRA LY-107677
# The error "[Error] Huge object being added to a COctreeNode, name: 'MeshComponentRenderNode', objBox:"
# will show (if occured) in about 3 sec into the game mode.
helper.wait_for_condition(has_physx_error, 3.0)
@@ -50,7 +50,7 @@ class TestAutomation(TestAutomationBase):
unexpected_lines = ["Assert"]
self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines)
# BUG: https://jira.agscollab.com/browse/LY-107723")
# BUG: LY-107723")
def test_C14976308_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor):
from . import C14976308_ScriptCanvas_SetKinematicTargetTransform as test_module
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
'''
This unittest might have to be refactored once changes to Physmaterial_Editor.py are made.
These changes will occur after the but, reverence below is resloved.
Bug: https://jira.agscollab.com/browse/LY-107392
Bug: LY-107392
'''
class Tests:
opening_bad_file = ("Bad file could not be opened", "Bad file was opened")
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569013
Test Case Title: Script Event file can be created
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569013
"""
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568942
Test Case Title: Clicking the "+" button and selecting "New Script Event" opens the
Asset Editor with a new Script Event asset
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568942
"""
from PySide2 import QtWidgets
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568856
Test Case Title: Multiple Entities can be targeted in the Debugger tool
URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568856
"""
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569137
Test Case Title: Multiple Graphs can be targeted in the Debugger tool
URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569137
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702824
Test Case Title: Docking
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702824
"""
@@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569049
Test Case Title: Edit > Undo undoes the last action
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569049
Test case ID: T92569051
Test Case Title: Edit > Redo redoes the last undone action
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569051
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562978
Test Case Title: Script Canvas Component can be added to an entity
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562978
"""
@@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569037
Test Case Title: File > New Script creates a new script
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569037
Test case ID: T92569039
Test Case Title: File > Open opens the Open... dialog
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569039
"""
import os
@@ -11,11 +11,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92563070
Test Case Title: Graphs can be closed by clicking X on the Graph name tab
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563070
Test case ID: T92563068
Test Case Title: Save Prompt: User is prompted to save a graph on close after
creating a new graph
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563068
"""
import os
@@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569079
Test Case Title: View > Zoom In zooms the graph in
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569079
Test case ID: T92569081
Test Case Title: View > Zoom In zooms the graph out
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569081
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562988
Test Case Title: Left-click/double click expands and collapses node categories
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562988
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568982
Test Case Title: Renaming variables in the Node Inspector
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568982
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562993
Test Case Title: Clicking the X button on the Search Box clears the currently entered string
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562993
"""
@@ -0,0 +1,91 @@
"""
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.
"""
# fmt: off
class Tests():
set_search_string = ("Search string is set", "Search string is not set")
search_string_deleted = ("Search string deleted as expected", "Search string not deleted")
# fmt: on
def NodePalette_SearchText_Deletion():
"""
Summary:
We enter some string in the Node Palette Search box, select that text and delete it.
Expected Behavior:
After RightClick->Delete the text in the Searchbox should be deleted.
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
2) Get the SC window object
3) Open Node Manager if not opened already
4) Set some string in the Search box
5) Verify if the test string is set
6) Delete search string using right click and verify if it is cleared
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
from PySide2 import QtWidgets, QtTest, QtCore
from utils import TestHelper as helper
import azlmbr.legacy.general as general
import pyside_utils
TEST_STRING = "TestString"
# 1) Open Script Canvas window (Tools > Script Canvas)
general.idle_enable(True)
general.open_pane("Script Canvas")
helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0)
# 2) Get the SC window object
editor_window = pyside_utils.get_editor_main_window()
sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
# 3) Open Node Manager if not opened already
if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None:
action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction})
action.trigger()
node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette")
search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame")
# 4) Set some string in the Search box
search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter")
search_box.setText(TEST_STRING)
# 5) Verify if the test string is set
result = helper.wait_for_condition(lambda: search_box.text() == TEST_STRING, 1.0)
Report.result(Tests.set_search_string, result)
# 6) Delete search string using right click and verify if it is cleared
QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_A, QtCore.Qt.ControlModifier)
pyside_utils.trigger_context_menu_entry(search_box, "Delete")
result = helper.wait_for_condition(lambda: search_box.text() == "", 2.0)
Report.result(Tests.search_string_deleted, result)
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(NodePalette_SearchText_Deletion)
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568940
Test Case Title: Categories and Nodes can be selected
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568940
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569253 // T92569254
Test Case Title: On Entity Activated // On Entity Deactivated
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569253 // https://testrail.agscollab.com/index.php?/tests/view/92569254
"""
@@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702834 // C1702823
Test Case Title: Opening pane // Closing pane
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702834 and
https://testrail.agscollab.com/index.php?/cases/view/1702823
"""
@@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702821 // C1702832
Test Case Title: Retain visibility, size and location upon Script Canvas restart
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702821 and
https://testrail.agscollab.com/index.php?/cases/view/1702832
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702829
Test Case Title: Resizing pane
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702829
"""
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562986
Test Case Title: Changing the assigned Script Canvas Asset on an entity properly updates
level functionality
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562986
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92563190
Test Case Title: A single Entity with two Script Canvas components works properly
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563190
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92563191
Test Case Title: Two Entities can use the same Graph asset successfully at RunTime
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563191
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92567321
Test Case Title: Script Events: Can send and receive a script event across multiple entities successfully
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567321
"""
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92567320
Test Case Title: Script Events: Can send and receive a script event successfully
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567320
"""
@@ -195,6 +195,10 @@ class TestAutomation(TestAutomationBase):
def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform):
from . import NodeCategory_ExpandOnClick as test_module
self._run_test(request, workspace, editor, test_module)
def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform):
from . import NodePalette_SearchText_Deletion as test_module
self._run_test(request, workspace, editor, test_module)
# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method
# fails because of pyside_utils import
@@ -13,11 +13,6 @@ Test Case Title: Tools > Node Palette toggles the Node Palette
Tools > Node Inspector toggles the Node Inspector
Tools > Bookmarks toggles the Bookmarks
Tools > Variable Manager toggles the Variable Manager
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/92569165
https://testrail.agscollab.com/index.php?/cases/view/92569167
https://testrail.agscollab.com/index.php?/cases/view/92569168
https://testrail.agscollab.com/index.php?/cases/view/92569170
"""
@@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702825 // C1702831
Test Case Title: Undocking // Closing script canvas with the pane floating
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702825 &
https://testrail.agscollab.com/index.php?/cases/view/1702831
"""
@@ -10,10 +10,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92564789
Test Case Title: Each Variable type can be created
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92564789
Test case ID: T92568873
Test Case Title: Each Variable type can be deleted
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568873
"""
@@ -189,7 +189,7 @@ namespace AZ
if (!WasLoadSuccess(result.GetOutcome()))
{
// This if is a hack around fault in the JSON serialization system
// Jira: https://jira.agscollab.com/browse/LY-106587
// Jira: LY-106587
if (message != "No part of the string could be interpreted as a uuid.")
{
deserializeError.append(message);
@@ -89,7 +89,7 @@ namespace AzToolsFramework
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
{
return AZ::Failure(
AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
AZStd::string("Could not create a new prefab out of the entities provided - invalid selection."));
}
// When we create a prefab with other prefab instances, we have to remove the existing links between the source and
@@ -140,9 +140,13 @@ namespace AzToolsFramework
// Mark them as dirty so this change is correctly applied to the template
for (AZ::Entity* topLevelEntity : topLevelEntities)
{
m_prefabUndoCache.UpdateCache(topLevelEntity->GetId());
undoBatch.MarkEntityDirty(topLevelEntity->GetId());
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
AZ::EntityId topLevelEntityId = topLevelEntity->GetId();
if (topLevelEntityId.IsValid())
{
m_prefabUndoCache.UpdateCache(topLevelEntityId);
undoBatch.MarkEntityDirty(topLevelEntityId);
AZ::TransformBus::Event(topLevelEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId);
}
}
// Select Container Entity
@@ -237,6 +241,21 @@ namespace AzToolsFramework
// Retrieve entityList from entityIds
inputEntityList = EntityIdListToEntityList(entityIds);
// Remove Level Container Entity if it's part of the list
AZ::EntityId levelEntityId = GetLevelInstanceContainerEntityId();
if (levelEntityId.IsValid())
{
AZ::Entity* levelEntity = GetEntityById(levelEntityId);
if (levelEntity)
{
auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity);
if (levelEntityIter != inputEntityList.end())
{
inputEntityList.erase(levelEntityIter);
}
}
}
// Find common root and top level entities
bool entitiesHaveCommonRoot = false;
@@ -807,6 +826,11 @@ namespace AzToolsFramework
const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const
{
if (inputEntities.size() == 0)
{
return false;
}
AZStd::queue<AZ::Entity*> entityQueue;
for (auto inputEntity : inputEntities)
@@ -894,7 +918,7 @@ namespace AzToolsFramework
outInstances.push_back(AZStd::move(commonRootEntityOwningInstance.DetachNestedInstance(instancePtr->GetInstanceAlias())));
}
return true;
return (outEntities.size() + outInstances.size()) > 0;
}
bool PrefabPublicHandler::EntitiesBelongToSameInstance(const EntityIdList& entityIds) const
@@ -1353,7 +1353,7 @@ namespace AzToolsFramework
// Iterate over the entities left in the instance and if none of them have this
// asset entity as its ancestor, then we want to remove it.
// \todo - Investigate ways to make this non-linear time. Tricky since removed entities
// obviously aren't maintained in any maps. (https://jira.agscollab.com/browse/LY-88218)
// obviously aren't maintained in any maps. (LY-88218)
bool foundAsAncestor = false;
for (const AZ::Entity* instanceEntity : instanceEntities)
{
@@ -151,32 +151,36 @@ namespace AzToolsFramework
{
if (!selectedEntities.empty())
{
bool layerInSelection = false;
for (AZ::EntityId entityId : selectedEntities)
// Hide if the only selected entity is the Level Container
if (selectedEntities.size() > 1 || !s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0]))
{
if (!layerInSelection)
{
AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult(
layerInSelection, entityId,
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer);
bool layerInSelection = false;
if (layerInSelection)
for (AZ::EntityId entityId : selectedEntities)
{
if (!layerInSelection)
{
break;
AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult(
layerInSelection, entityId,
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer);
if (layerInSelection)
{
break;
}
}
}
}
// Layers can't be in prefabs.
if (!layerInSelection)
{
QAction* createAction = menu->addAction(QObject::tr("Create Prefab..."));
createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities."));
// Layers can't be in prefabs.
if (!layerInSelection)
{
QAction* createAction = menu->addAction(QObject::tr("Create Prefab..."));
createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities."));
QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] {
ContextMenu_CreatePrefab(selectedEntities);
});
QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] {
ContextMenu_CreatePrefab(selectedEntities);
});
}
}
}
}
@@ -272,6 +276,15 @@ namespace AzToolsFramework
QWidget* activeWindow = QApplication::activeWindow();
const AZStd::string prefabFilesPath = "@devassets@/Prefabs";
// Remove Level entity if it's part of the list
auto levelContainerIter =
AZStd::find(selectedEntities.begin(), selectedEntities.end(), s_prefabPublicInterface->GetLevelInstanceContainerEntityId());
if (levelContainerIter != selectedEntities.end())
{
selectedEntities.erase(levelContainerIter);
}
// Set default folder for prefabs
AZ::IO::FileIOBase* fileIoBaseInstance = AZ::IO::FileIOBase::GetInstance();
@@ -514,7 +514,7 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
/*
* The following block of code is part of the feature "Isolation Mode" and is temporarily
* disabled for 1.10 release.
* Jira: https://jira.agscollab.com/browse/LY-49532
* Jira: LY-49532
// Isolate Selected
QAction* isolateSelectedAction = editMenu->addAction(tr("Isolate Selected"));
@@ -95,32 +95,32 @@ namespace UnitTest
class ImageProcessingTest
: public ::testing::Test
, public AllocatorsBase
, public ComponentApplicationBus::Handler
, public AZ::ComponentApplicationBus::Handler
{
public:
//////////////////////////////////////////////////////////////////////////
// ComponentApplicationMessages.
ComponentApplication* GetApplication() override { return nullptr; }
void RegisterComponentDescriptor(const ComponentDescriptor*) override { }
void UnregisterComponentDescriptor(const ComponentDescriptor*) override { }
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler&) override { }
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler&) override { }
void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { }
void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { }
void SignalEntityActivated(Entity*) override { }
void SignalEntityDeactivated(Entity*) override { }
bool AddEntity(Entity*) override { return false; }
bool RemoveEntity(Entity*) override { return false; }
bool DeleteEntity(const EntityId&) override { return false; }
Entity* FindEntity(const EntityId&) override { return nullptr; }
SerializeContext* GetSerializeContext() override { return m_context.get(); }
BehaviorContext* GetBehaviorContext() override { return nullptr; }
AZ::ComponentApplication* GetApplication() override { return nullptr; }
void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { }
void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { }
void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override { }
void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override { }
void RegisterEntityActivatedEventHandler(AZ::EntityActivatedEvent::Handler&) override { }
void RegisterEntityDeactivatedEventHandler(AZ::EntityDeactivatedEvent::Handler&) override { }
void SignalEntityActivated(AZ::Entity*) override { }
void SignalEntityDeactivated(AZ::Entity*) override { }
bool AddEntity(AZ::Entity*) override { return false; }
bool RemoveEntity(AZ::Entity*) override { return false; }
bool DeleteEntity(const AZ::EntityId&) override { return false; }
Entity* FindEntity(const AZ::EntityId&) override { return nullptr; }
AZ::SerializeContext* GetSerializeContext() override { return m_context.get(); }
AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; }
AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return m_jsonRegistrationContext.get(); }
const char* GetAppRoot() const override { return nullptr; }
const char* GetEngineRoot() const override { return nullptr; }
const char* GetExecutableFolder() const override { return nullptr; }
Debug::DrillerManager* GetDrillerManager() override { return nullptr; }
void EnumerateEntities(const EntityCallback& /*callback*/) override {}
AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; }
void EnumerateEntities(const AZ::ComponentApplicationRequests::EntityCallback& /*callback*/) override {}
void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {}
//////////////////////////////////////////////////////////////////////////
@@ -15,6 +15,7 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
@@ -166,6 +167,18 @@ namespace AZ
RPI::RPISystemInterface::Get()->InitializeSystemAssets();
if (!RPI::RPISystemInterface::Get()->IsInitialized())
{
AZ::OSString msgBoxMessage;
msgBoxMessage.append("RPI System could not initialize correctly. Check log for detail.");
AZ::NativeUI::NativeUIRequestBus::Broadcast(
&AZ::NativeUI::NativeUIRequestBus::Events::DisplayOkDialog, "O3DE Fatal Error", msgBoxMessage.c_str(), false);
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop);
return;
}
// In the case of the game we want to call create and register the scene as a soon as we can
// because a level could be loaded in autoexec.cfg and that will assert if there is no scene registered
// to get the feature processors for the components. So we can't wait until the tick (whereas the Editor wants to wait)
@@ -37,8 +37,6 @@ float3 TextureBlend_Overlay(float3 target, float3 blend)
//! @return the resulting blended color
float3 ApplyTextureBlend(float3 color, float3 blendColor, float factor, TextureBlendMode blendMode)
{
// More info to help understand some of these blend modes: https://wiki.agscollab.com/pages/viewpage.action?pageId=15764930
if(blendMode == TextureBlendMode::Multiply)
{
return factor * color * blendColor;
@@ -25,7 +25,7 @@ class LightCullingTileIterator
float viewz = abs(svPosition.w);
// https://jira.agscollab.com/browse/ATOM-4198
// ATOM-4198
// Replace GetDimensions() with a cbuffer uint read. Reading it from a cbuffer should be faster
uint tileWidth, tileHeight;
tileLightDataTex.GetDimensions(tileWidth, tileHeight);
@@ -13,6 +13,49 @@
#pragma once
#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;
const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y)));
if (toPoint.x == -maxElement)
{
return 0;
}
else if (toPoint.x == maxElement)
{
return 1;
}
else if (toPoint.y == -maxElement)
{
return 2;
}
else if (toPoint.y == maxElement)
{
return 3;
}
else if (toPoint.z == -maxElement)
{
return 4;
}
else
{
return 5;
}
}
// PointLight::m_shadowIndices actually consists of uint16_t x 6 on the CPU, but visible as a uint32_t x 3 on the GPU.
// This function returns the proper uint16_t value given an input face in the range 0-5
int UnpackPointLightShadowIndex(const ViewSrg::PointLight light, const int face)
{
const int index = face >> 1;
const int shiftAmount = (face & 1) * 16;
return (light.m_shadowIndices[index] >> shiftAmount) & 0xFFFF;
}
void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData)
{
@@ -31,11 +74,38 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD
d2 = max(0.001 * 0.001, d2); // clamp the light to at least 1mm away to avoid extreme values.
float3 lightIntensity = (light.m_rgbIntensityCandelas / d2) * radiusAttenuation;
// shadow
float litRatio = 1.0;
// How much is back face shadowed, it's set to the reverse of litRatio to share the same default value with thickness, which should be 0 if no shadow map available
float backShadowRatio = 0.0;
if (o_enableShadows)
{
const int shadowCubemapFace = GetPointLightShadowCubemapFace(surface.position, light.m_position);
const int shadowIndex = UnpackPointLightShadowIndex(light, shadowCubemapFace);
litRatio *= ProjectedShadow::GetVisibility(
shadowIndex,
light.m_position,
surface.position,
PointLightShadowCubemapDirections[shadowCubemapFace],
surface.normal);
// Use backShadowRatio to carry thickness from shadow map for thick mode
backShadowRatio = 1.0 - litRatio;
if (o_transmission_mode == TransmissionMode::ThickObject)
{
backShadowRatio = ProjectedShadow::GetThickness(
shadowIndex,
surface.position);
}
}
// Diffuse contribution
lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight));
lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio;
// Tranmission contribution
lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0);
lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), backShadowRatio);
// Adjust the light direcion for specular based on bulb size
@@ -61,6 +61,8 @@ ShaderResourceGroup RayTracingSceneSrg : SRG_RayTracingScene
float m_invAttenuationRadiusSquared;
float3 m_rgbIntensity;
float m_bulbRadius;
uint3 m_shadowIndices;
uint m_padding;
};
StructuredBuffer<PointLight> m_pointLights;
@@ -73,6 +73,8 @@ partial ShaderResourceGroup ViewSrg
float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2.
float3 m_rgbIntensityCandelas;
float m_bulbRadius;
uint3 m_shadowIndices;
uint m_padding;
};
StructuredBuffer<PointLight> m_pointLights;
@@ -17,7 +17,7 @@
#include <Atom/RPI/Math.azsli>
#include <Atom/Features/LightCulling/LightCullingShared.azsli>
enum QuadLightFlag // Copied from QuadLight.azsli. See https://jira.agscollab.com/browse/ATOM-3731
enum QuadLightFlag // Copied from QuadLight.azsli. See ATOM-3731
{
None = 0x00,
EmitsBothDirections = 0x01, // 1 << 0, // Quad should emit light from both sides
@@ -33,7 +33,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass
{
// Figure out how to remove duplicate struct definitions.
// These are also defined in View.srg
// https://jira.agscollab.com/browse/ATOM-3731
// ATOM-3731
struct SimplePointLight
{
@@ -59,6 +59,8 @@ ShaderResourceGroup PassSrg : SRG_PerPass
float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2.
float3 m_rgbIntensityCandelas;
float m_bulbRadius;
uint3 m_shadowIndices;
uint m_padding;
};
struct DiskLight
@@ -370,7 +372,7 @@ void CullDecals(uint groupIndex, TileLightData tileLightData, float3 aabb_center
float3 decalPosition = WorldToView_Point(decal.m_position);
// just wrapping a bounding sphere around a cube for now to get a minor perf boost. i.e. the sphere radius is sqrt(x*x + y*y + z*z)
// https://jira.agscollab.com/browse/ATOM-4224 - try AABB-AABB and implement depth binning for the decals
// ATOM-4224 - try AABB-AABB and implement depth binning for the decals
float maxHalfSize = max(max(decal.m_halfSize.x, decal.m_halfSize.y), decal.m_halfSize.z);
float boundingSphereRadiusSqr = maxHalfSize * maxHalfSize * 3;
@@ -378,7 +380,7 @@ void CullDecals(uint groupIndex, TileLightData tileLightData, float3 aabb_center
if (potentiallyIntersects)
{
// Implement and profile fine-grained light culling testing
// https://jira.agscollab.com/browse/ATOM-3732
// ATOM-3732
MarkLightAsVisibleInSharedMemory(decalIndex, 0xFFFF);
}
}
@@ -391,7 +393,7 @@ void CullPointLight(uint lightIndex, float3 lightPosition, float invLightRadius,
if (potentiallyIntersects)
{
// Implement and profile fine-grained light culling testing
// https://jira.agscollab.com/browse/ATOM-3732
// ATOM-3732
uint inside = 0;
float2 minmax = ComputePointLightMinMaxZ(rsqrt(invLightRadius), lightPosition);
@@ -432,7 +434,7 @@ void CullSimpleSpotLights(uint groupIndex, TileLightData tileLightData, float3 a
if (potentiallyIntersects)
{
// Implement and profile fine-grained light culling testing
// https://jira.agscollab.com/browse/ATOM-3732
// ATOM-3732
uint inside = 0;
float2 minmax = ComputeSimpleSpotLightMinMax(light, lightPosition);
@@ -477,7 +479,7 @@ void CullDiskLights(uint groupIndex, TileLightData tileLightData, float3 aabb_ce
if (potentiallyIntersects)
{
// Implement and profile fine-grained light culling testing
// https://jira.agscollab.com/browse/ATOM-3732
// ATOM-3732
uint inside = 0;
float2 minmax = ComputeDiskLightMinMax(light, lightPosition);
@@ -505,7 +507,7 @@ void CullCapsuleLights(uint groupIndex, TileLightData tileLightData, float3 aabb
if (potentiallyIntersects)
{
// Implement and profile fine-grained light culling testing
// https://jira.agscollab.com/browse/ATOM-3732
// ATOM-3732
uint inside = 0;
float2 minmax = ComputeCapsuleLightMinMax(light, lightMiddleView, lightFalloffRadius);
@@ -520,7 +522,7 @@ void CullCapsuleLights(uint groupIndex, TileLightData tileLightData, float3 aabb
void CullQuadLights(uint groupIndex, TileLightData tileLightData, float3 aabb_center, float3 aabb_extents)
{
// Implement and profile fine-grained light culling testing
// https://jira.agscollab.com/browse/ATOM-3732
// ATOM-3732
for (uint lightIndex = groupIndex ; lightIndex < PassSrg::m_quadLightCount ; lightIndex += TILE_DIM_X * TILE_DIM_Y)
{
@@ -242,7 +242,7 @@ PSOutput MainPS(VSOutput IN)
// Set this value to > 0 to actually see this pass. It is currently always active.
OUT.m_color.w = PassSrg::m_heatmapOpacity;
// https://jira.agscollab.com/browse/ATOM-3682 (improve heatmap integration with the pass system)
// ATOM-3682 (improve heatmap integration with the pass system)
return OUT;
}
@@ -186,7 +186,7 @@ void InitWriteIndices(uint3 groupID, uint baseBin, out uint writeIndices[NVLC_MA
// light indices until it hits an END_OF_X marker
// Note that this code could probably be made faster with wave intrinsics
// https://jira.agscollab.com/browse/ATOM-4104
// ATOM-4104
[numthreads(NUM_THREADS, 1, 1)]
void MainCS(
uint3 dispatchThreadID : SV_DispatchThreadID,
@@ -181,7 +181,7 @@ void WriteTileLightDataToMainMemory(uint groupIndex, uint3 groupID, float2 minma
// Note that Nvidia Light Culling framework has some additional code to better calculate this ratio
// See cb_perFrame.fRangeThreshold in their framework. This code might be something we want to port over.
// https://jira.agscollab.com/browse/ATOM-5554
// ATOM-5554
float ratio = tileZ / 1.0f;
float logMaxBins = clamp(log2(ratio), 0.0, LOG_MAX_BINS);
uint ulogMaxBins = uint(logMaxBins + 0.5);
@@ -41,7 +41,6 @@ ShaderResourceGroup PassSrg : SRG_PerDraw
// The number of points to sample.
// Sample 6 points around center pixel.
// Similarly, sample around it as 12,18,24 points.
// Please refer to “https://wiki.agscollab.com/display/ATOM/Pencil+Map” for details.
option enum class SampleNumber
{
Sample6, // 6
@@ -52,7 +51,6 @@ option enum class SampleNumber
o_sampleNumber = SampleNumber::Sample6;
// Get CocRadius from dofFactor.
// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for CocRadius.
inline float GetCocRadius(float dofFactor)
{
float cocRadius = dofFactor * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f;
@@ -61,14 +59,12 @@ inline float GetCocRadius(float dofFactor)
}
// Calculate the texcoord U of the pencil map from cocRadius.
// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for the pencil map.
inline float GetPencilMapTexcoordU(float cocRadius)
{
return cocRadius * ViewSrg::m_dof.m_pencilMapTexcoordToCocRadius + ViewSrg::m_dof.m_pencilMapFocusPointTexcoordU;
}
// Get the color from the coordinate array.
// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for details of coordinates.
inline float4 SampleColorAndDofFactor(float2 centerTexCoord, float cocRadius, int sampleIndex)
{
float2 sampleTexcoordOffset = PassSrg::m_sampleTexcoordsRadius[sampleIndex].xy * cocRadius;
@@ -78,7 +74,6 @@ inline float4 SampleColorAndDofFactor(float2 centerTexCoord, float cocRadius, in
}
// Load the pencil map. Since the colors are square rooted, they are decoded (linearized). This is for accuracy.
// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for the pencil map.
inline float4 SamplePencilMap(float lensCoordX, float radius)
{
float2 bokehTexcoord = float2(lensCoordX, radius);
@@ -77,7 +77,6 @@ PSOutput MainPS(VSOutput IN)
float3 colorSum = (float3)0;
// Combine from the back buffer to the front.
// Please refer to https://wiki.agscollab.com/pages/viewpage.action?spaceKey=ATOM&title=Dof+factor+and+Buffer+composition for details
////////////////////////////////////////////////////////////////////////
// Background
@@ -1,19 +1,20 @@
/*
* 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.
*
*/
* 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/FeatureProcessor.h>
#include <Atom/Feature/CoreLights/PhotometricValue.h>
#include <Atom/Feature/CoreLights/ShadowConstants.h>
#include <Atom/RPI.Public/FeatureProcessor.h>
namespace AZ
{
@@ -22,9 +23,25 @@ namespace AZ
namespace Render
{
struct PointLightData
{
AZStd::array<float, 3> m_position = {{0.0f, 0.0f, 0.0f}};
// Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations.
float m_invAttenuationRadiusSquared = 0.0f;
AZStd::array<float, 3> m_rgbIntensity = {{0.0f, 0.0f, 0.0f}};
// Radius of spherical light in meters.
float m_bulbRadius = 0.0f;
static const int NumShadowFaces = 6;
AZStd::array<uint16_t, NumShadowFaces> m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}};
uint32_t m_padding;
};
//! PointLightFeatureProcessorInterface provides an interface to acquire, release, and update a point light.
class PointLightFeatureProcessorInterface
: public RPI::FeatureProcessor
class PointLightFeatureProcessorInterface : public RPI::FeatureProcessor
{
public:
AZ_RTTI(AZ::Render::PointLightFeatureProcessorInterface, "{D3E0B016-F3C6-4C7A-A29E-0B3A4FA87806}", AZ::RPI::FeatureProcessor);
@@ -33,7 +50,8 @@ namespace AZ
using LightHandle = RHI::Handle<uint16_t, class PointLight>;
static constexpr PhotometricUnit PhotometricUnitType = PhotometricUnit::Candela;
//! Creates a new point light which can be referenced by the returned LightHandle. Must be released via ReleaseLight() when no longer needed.
//! Creates a new point light which can be referenced by the returned LightHandle. Must be released via ReleaseLight() when no
//! longer needed.
virtual LightHandle AcquireLight() = 0;
//! Releases a LightHandle which removes the point light.
virtual bool ReleaseLight(LightHandle& handle) = 0;
@@ -48,6 +66,24 @@ namespace AZ
virtual void SetAttenuationRadius(LightHandle handle, float attenuationRadius) = 0;
//! Sets the bulb radius for the provided LightHandle. Values greater than zero effectively make it a spherical light.
virtual void SetBulbRadius(LightHandle handle, float bulbRadius) = 0;
//! Sets if shadows are enabled
virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0;
//! Sets the shadowmap size (width and height) of the light.
virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0;
//! Specifies filter method of shadows.
virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0;
//! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on
//! the boundary. 0 disables softening.
virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0;
//! Sets sample count to predict boundary of shadow (up to 16). It will be clamped to be less than or equal to the filtering
//! sample count.
virtual void SetPredictionSampleCount(LightHandle handle, uint16_t count) = 0;
//! Sets sample count for filtering of shadow boundary (up to 64)
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
//! Sets the shadowmap Pcf (percentage closer filtering) method.
virtual void SetPcfMethod(LightHandle handle, PcfMethod method) = 0;
//! Sets all of the the point data for the provided LightHandle.
virtual void SetPointData(LightHandle handle, const PointLightData& data) = 0;
};
} // namespace Render
} // namespace AZ
@@ -1487,7 +1487,6 @@ namespace AZ
float depthNear,
float depthFar) const
{
// For calculation, refer https://wiki.agscollab.com/display/ATOM/Cascaded+Shadowmaps
// This calculates the center of bounding sphere for a camera view frustum.
// By this, on the camera view (2D), the bounding sphere's center
// shifts to the remarkable point.
@@ -380,7 +380,7 @@ namespace AZ
const float invRadiusSquared = diskLight.m_invAttenuationRadiusSquared;
if (invRadiusSquared <= 0.f)
{
AZ_Assert(false, "Attenuation radius have to be set before use the light.");
AZ_Assert(false, "Attenuation radius must be set before using the light.");
return;
}
const float attenuationRadius = sqrtf(1.f / invRadiusSquared);
@@ -59,7 +59,7 @@ namespace AZ
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
void SetPredictionSampleCount(LightHandle handle, uint16_t count) override;
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
void SetPcfMethod(LightHandle handle, PcfMethod method);
void SetPcfMethod(LightHandle handle, PcfMethod method) override;
void SetDiskData(LightHandle handle, const DiskLightData& data) override;
@@ -84,7 +84,7 @@ namespace AZ
template <typename Functor, typename ParamType>
void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param);
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor;
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr;
IndexedDataVector<DiskLightData> m_diskLightData;
GpuBufferHandler m_lightBufferHandler;
@@ -34,7 +34,7 @@ namespace AZ
const size_t NumBins = 8;
const size_t MaxLightsPerTile = 256;
// TODO convert this to R16_UINT. It just needs RHI support
// https://jira.agscollab.com/browse/ATOM-3975
// ATOM-3975
const RHI::Format LightListRemappedFormat = RHI::Format::R32_UINT;
RPI::Ptr<LightCullingRemap> LightCullingRemap::Create(const RPI::PassDescriptor& descriptor)
@@ -44,6 +44,13 @@ namespace AZ
PointLightFeatureProcessor::PointLightFeatureProcessor()
: PointLightFeatureProcessorInterface()
{
// Note must match PointShadowDirections in PointLight.azsli
m_pointShadowTransforms[0] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisX());
m_pointShadowTransforms[1] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisX());
m_pointShadowTransforms[2] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisY());
m_pointShadowTransforms[3] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisY());
m_pointShadowTransforms[4] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisZ());
m_pointShadowTransforms[5] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisZ());
}
void PointLightFeatureProcessor::Activate()
@@ -54,6 +61,7 @@ namespace AZ
desc.m_elementCountSrgName = "m_pointLightCount";
desc.m_elementSize = sizeof(PointLightData);
desc.m_srgLayout = RPI::RPISystemInterface::Get()->GetViewSrgAsset()->GetLayout();
m_shadowFeatureProcessor = GetParentScene()->GetFeatureProcessor<ProjectedShadowFeatureProcessor>();
m_lightBufferHandler = GpuBufferHandler(desc);
}
@@ -83,6 +91,15 @@ namespace AZ
{
if (handle.IsValid())
{
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
{
ShadowId shadowId = ShadowId(m_pointLightData.GetData(handle.GetIndex()).m_shadowIndices[i]);
if (shadowId.IsValid())
{
m_shadowFeatureProcessor->ReleaseShadow(shadowId);
}
}
m_pointLightData.RemoveIndex(handle.GetIndex());
m_deviceBufferNeedsUpdate = true;
handle.Reset();
@@ -148,6 +165,7 @@ namespace AZ
lightPosition.StoreToFloat3(position.data());
m_deviceBufferNeedsUpdate = true;
UpdateShadow(handle);
}
void PointLightFeatureProcessor::SetAttenuationRadius(LightHandle handle, float attenuationRadius)
@@ -177,5 +195,122 @@ namespace AZ
return m_lightBufferHandler.GetElementCount();
}
void PointLightFeatureProcessor::SetShadowsEnabled(LightHandle handle, bool enabled)
{
auto& light = m_pointLightData.GetData(handle.GetIndex());
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
{
ShadowId shadowId = ShadowId(light.m_shadowIndices[i]);
if (shadowId.IsValid() && !enabled)
{
// Disable shadows
m_shadowFeatureProcessor->ReleaseShadow(shadowId);
shadowId.Reset();
light.m_shadowIndices[i] = shadowId.GetIndex();
m_deviceBufferNeedsUpdate = true;
}
else if (shadowId.IsNull() && enabled)
{
// Enable shadows
light.m_shadowIndices[i] = m_shadowFeatureProcessor->AcquireShadow().GetIndex();
UpdateShadow(handle);
m_deviceBufferNeedsUpdate = true;
}
}
}
void PointLightFeatureProcessor::SetPointData(LightHandle handle, const PointLightData& data)
{
AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetPointData().");
m_pointLightData.GetData(handle.GetIndex()) = data;
m_deviceBufferNeedsUpdate = true;
UpdateShadow(handle);
}
void PointLightFeatureProcessor::UpdateShadow(LightHandle handle)
{
constexpr float SqrtHalf = 0.707106781187f; // sqrt(0.5);
const auto& pointLight = m_pointLightData.GetData(handle.GetIndex());
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
{
ShadowId shadowId = ShadowId(pointLight.m_shadowIndices[i]);
if (shadowId.IsNull())
{
// Early out if shadows are disabled.
return;
}
ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId);
// Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces
desc.m_fieldOfViewYRadians = DegToRad(91.0f);
desc.m_transform = m_pointShadowTransforms[i];
desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]);
desc.m_aspectRatio = 1.0f;
desc.m_nearPlaneDistance = SqrtHalf * pointLight.m_bulbRadius;
const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared;
if (invRadiusSquared <= 0.f)
{
AZ_Assert(false, "Attenuation radius must be set before using the light.");
return;
}
const float attenuationRadius = sqrtf(1.f / invRadiusSquared);
desc.m_farPlaneDistance = attenuationRadius + pointLight.m_bulbRadius;
m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc);
}
}
template<typename Functor, typename ParamType>
void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param)
{
AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetShadowSetting().");
auto& light = m_pointLightData.GetData(handle.GetIndex());
for (int lightIndex = 0; lightIndex < PointLightData::NumShadowFaces; ++lightIndex)
{
ShadowId shadowId = ShadowId(light.m_shadowIndices[lightIndex]);
AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled.");
if (shadowId.IsValid())
{
AZStd::invoke(AZStd::forward<Functor>(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward<ParamType>(param));
}
}
}
void PointLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize);
}
void PointLightFeatureProcessor::SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method);
}
void PointLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians);
}
void PointLightFeatureProcessor::SetPredictionSampleCount(LightHandle handle, uint16_t count)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetPredictionSampleCount, count);
}
void PointLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetFilteringSampleCount, count);
}
void PointLightFeatureProcessor::SetPcfMethod(LightHandle handle, PcfMethod method)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetPcfMethod, method);
}
} // namespace Render
} // namespace AZ
@@ -16,6 +16,7 @@
#include <Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h>
#include <Atom/Feature/Utils/GpuBufferHandler.h>
#include <CoreLights/IndexedDataVector.h>
#include <Shadows/ProjectedShadowFeatureProcessor.h>
namespace AZ
{
@@ -24,15 +25,6 @@ namespace AZ
namespace Render
{
struct PointLightData
{
AZStd::array<float, 3> m_position = { { 0.0f, 0.0f, 0.0f } };
float m_invAttenuationRadiusSquared = 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations.
AZStd::array<float, 3> m_rgbIntensity = { { 0.0f, 0.0f, 0.0f } };
float m_bulbRadius = 0.0f; // Radius of spherical light in meters.
};
class PointLightFeatureProcessor final
: public PointLightFeatureProcessorInterface
{
@@ -58,18 +50,34 @@ namespace AZ
void SetPosition(LightHandle handle, const AZ::Vector3& lightPosition) override;
void SetAttenuationRadius(LightHandle handle, float attenuationRadius) override;
void SetBulbRadius(LightHandle handle, float bulbRadius) override;
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
void SetPredictionSampleCount(LightHandle handle, uint16_t count) override;
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
void SetPcfMethod(LightHandle handle, PcfMethod method) override;
void SetPointData(LightHandle handle, const PointLightData& data) override;
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
uint32_t GetLightCount()const;
private:
PointLightFeatureProcessor(const PointLightFeatureProcessor&) = delete;
using ShadowId = ProjectedShadowFeatureProcessor::ShadowId;
static constexpr const char* FeatureProcessorName = "PointLightFeatureProcessor";
void UpdateShadow(LightHandle handle);
// Convenience function for forwarding requests to the ProjectedShadowFeatureProcessor
template<typename Functor, typename ParamType>
void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param);
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr;
IndexedDataVector<PointLightData> m_pointLightData;
GpuBufferHandler m_lightBufferHandler;
bool m_deviceBufferNeedsUpdate = false;
AZStd::array<AZ::Transform, PointLightData::NumShadowFaces> m_pointShadowTransforms;
};
} // namespace Render
} // namespace AZ
@@ -50,7 +50,7 @@ namespace AZ
static constexpr Quality QualitySet[DepthOfField::QualityLevelMax] =
{
// It is the radial division count of blur kernel. See "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details.
// It is the radial division count of blur kernel.
{2, 3, 4},
{4, 4, 4}
};
@@ -205,7 +205,6 @@ namespace AZ
float scaledDiameter = ScreenApertureDiameter * 0.25f;
// This is the conversion factor for calculating the blend ratio from DofFactor.
// Please refer to "https://wiki.agscollab.com/display/ATOM/Dof+factor+and+Buffer+composition" for blending of DofFactor and buffer.
// coc0 : Confusion circle diameter screen ratio
// coc1 : Confusion circle diameter screen ratio of one lower blur level;
@@ -139,7 +139,6 @@ namespace AZ
float m_minBokehRadiusDivision8 = 0.0f;
// Radial division count of bokeh blur kernel.
// See "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details.
uint32_t m_sampleRadialDivision2 = 0;
uint32_t m_sampleRadialDivision4 = 0;
uint32_t m_sampleRadialDivision8 = 0;
@@ -194,7 +194,6 @@ namespace AZ
// calculate sampling texcoords.
// sample 6 points around center pixel.
// Similarly, sample around it as 12,18,24 points.
// Please refer to "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details.
AZ_Assert(radialDivisionCount >= 1 && radialDivisionCount <= 4, "DepthOfFieldBokehBlurPass : radialDivisionCount is illegal value.");
@@ -18,8 +18,6 @@ namespace AZ
{
namespace PencilMap
{
// Please refer to "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details.
// PencilMap 35mm Film
static constexpr unsigned int TextureWidth = 128;
static constexpr unsigned int TextureHeight = 64;
@@ -124,6 +124,8 @@ namespace AZ
// This lock will only be contested when the CpuProfiler's Shutdown() method has been called
AZStd::shared_mutex m_shutdownMutex;
bool m_initialized = false;
};
}; // namespace RPI
@@ -82,10 +82,15 @@ namespace AZ
void CpuProfilerImpl::Init()
{
Interface<CpuProfiler>::Register(this);
m_initialized = true;
}
void CpuProfilerImpl::Shutdown()
{
if (!m_initialized)
{
return;
}
// When this call is made, no more thread profiling calls can be performed anymore
Interface<CpuProfiler>::Unregister(this);
@@ -97,6 +102,7 @@ namespace AZ
// Cleanup all TLS
m_registeredThreads.clear();
m_timeRegionMap.clear();
m_initialized = false;
}
void CpuProfilerImpl::BeginTimeRegion(TimeRegion& timeRegion)
+6 -3
View File
@@ -200,9 +200,12 @@ namespace AZ
m_platformLimitsDescriptor = nullptr;
m_pipelineStateCache = nullptr;
m_device->PreShutdown();
AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count());
m_device = nullptr;
if (m_device)
{
m_device->PreShutdown();
AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count());
m_device = nullptr;
}
m_cpuProfiler.Shutdown();
}
@@ -90,12 +90,16 @@ namespace AZ
void AsyncUploadQueue::Shutdown()
{
m_copyQueue->Shutdown();
if (m_copyQueue)
{
m_copyQueue->Shutdown();
m_copyQueue = nullptr;
}
m_commandList = nullptr;
for (size_t i = 0; i < m_descriptor.m_frameCount; ++i)
for (auto& framePacket : m_framePackets)
{
m_framePackets[i].m_fence.Shutdown();
framePacket.m_fence.Shutdown();
}
m_framePackets.clear();
m_uploadFence.Shutdown();
@@ -109,7 +109,10 @@ namespace AZ
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
for (uint32_t hardwareQueueIdx = 0; hardwareQueueIdx < RHI::HardwareQueueClassCount; ++hardwareQueueIdx)
{
m_commandQueues[hardwareQueueIdx]->WaitForIdle();
if (m_commandQueues[hardwareQueueIdx])
{
m_commandQueues[hardwareQueueIdx]->WaitForIdle();
}
}
}
@@ -45,6 +45,8 @@ namespace AZ
private:
RHI::Ptr<RHI::BufferPool> m_commonPools[static_cast<uint8_t>(CommonBufferPoolType::Count)];
bool m_initialized = false;
};
} // namespace RPI
} // namespace AZ
@@ -80,6 +80,8 @@ namespace AZ
Data::Asset<DefaultStreamingImageControllerAsset> m_defaultStreamingImageControllerAsset;
AZStd::fixed_vector<Data::Instance<Image>, static_cast<uint32_t>(SystemImage::Count)> m_systemImages;
bool m_initialized = false;
};
}
}
@@ -82,7 +82,7 @@ namespace AZ
void RemovePassFromLibrary(Pass* pass);
//! Load pass templates which are list in an AssetAliases
void LoadPassTemplateMappings(const AZStd::string& templateMappingPath);
bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath);
bool LoadPassTemplateMappings(Data::Asset<AnyAsset> mappingAsset);
//! Returns a list of passes found in the pass name mapping using the provided pass filter
@@ -66,7 +66,7 @@ namespace AZ
// PassSystemInterface functions...
void ProcessQueuedChanges() override;
void LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override;
bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override;
void WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath) override;
void DebugPrintPassHierarchy() override;
bool IsBuilding() const override;
@@ -65,7 +65,7 @@ namespace AZ
virtual void ProcessQueuedChanges() = 0;
//! Load pass templates listed in a name-assetid mapping asset
virtual void LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0;
virtual bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0;
//! Writes a pass template to a .pass file which can then be used as a pass asset. Useful for
//! quickly authoring a pass template in code and then outputting it as a pass asset using JSON
@@ -70,6 +70,7 @@ namespace AZ
void Shutdown();
// RPISystemInterface overrides...
bool IsInitialized() const override;
void InitializeSystemAssets() override;
void RegisterScene(ScenePtr scene) override;
void UnregisterScene(ScenePtr scene) override;
@@ -40,6 +40,9 @@ namespace AZ
//! Note: can't rely on the AzFramework::AssetCatalogEventBus's OnCatalogLoaded since the order of calling handlers is undefined.
virtual void InitializeSystemAssets() = 0;
//! Was the RPI system initialized properly
virtual bool IsInitialized() const = 0;
//! Register a created scene to RPISystem. Registered scene will be simulated and rendered in RPISystem ticks
virtual void RegisterScene(ScenePtr scene) = 0;
@@ -15,6 +15,8 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzFramework/Asset/AssetSystemBus.h>
namespace AZ
{
namespace RPI
@@ -48,6 +50,12 @@ namespace AZ
//! @return a null asset if the asset could not be found or loaded.
template<typename AssetDataT>
Data::Asset<AssetDataT> LoadAssetById(Data::AssetId assetId, TraceLevel reporting = TraceLevel::Warning);
//! Loads a critial asset using a file path (both source and product path should be same), on the current thread.
//! If the asset wasn't compiled, wait until the asset is compiled.
//! @return a null asset if the asset could not be compiled or loaded.
template<typename AssetDataT>
Data::Asset<AssetDataT> LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting = TraceLevel::Error);
template<typename AssetDataT>
bool LoadBlocking(AZ::Data::Asset<AssetDataT>& asset, TraceLevel reporting = TraceLevel::Warning);
@@ -89,7 +97,7 @@ namespace AZ
assetId, AZ::Data::AssetLoadBehavior::PreLoad);
asset.BlockUntilLoadComplete();
if (!asset.Get())
if (!asset.IsReady())
{
AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load '%s'", productPath).c_str());
return {};
@@ -117,7 +125,7 @@ namespace AZ
);
asset.BlockUntilLoadComplete();
if (!asset.Get())
if (!asset.IsReady())
{
AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load '%s'", assetId.ToString<AZStd::string>().c_str()).c_str());
return {};
@@ -126,6 +134,21 @@ namespace AZ
return asset;
}
template<typename AssetDataT>
Data::Asset<AssetDataT> LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting)
{
AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown;
AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath);
if (status != AzFramework::AssetSystem::AssetStatus_Compiled)
{
AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str());
return {};
}
return LoadAssetByProductPath<AssetDataT>(assetFilePath.c_str(), reporting);
}
template<typename AssetDataT>
bool LoadBlocking(AZ::Data::Asset<AssetDataT>& asset, TraceLevel reporting)
{
@@ -61,10 +61,16 @@ namespace AZ
Data::InstanceDatabase<BufferPool>::Create(azrtti_typeid<ResourcePoolAsset>(), handler);
}
Interface<BufferSystemInterface>::Register(this);
m_initialized = true;
}
void BufferSystem::Shutdown()
{
if (!m_initialized)
{
return;
}
for (uint8_t index = 0; index < static_cast<uint8_t>(CommonBufferPoolType::Count); index++)
{
m_commonPools[index] = nullptr;
@@ -72,6 +78,7 @@ namespace AZ
Interface<BufferSystemInterface>::Unregister(this);
Data::InstanceDatabase<Buffer>::Destroy();
Data::InstanceDatabase<BufferPool>::Destroy();
m_initialized = false;
}
RHI::Ptr<RHI::BufferPool> BufferSystem::GetCommonBufferPool(CommonBufferPoolType poolType)
@@ -87,6 +94,10 @@ namespace AZ
bool BufferSystem::CreateCommonBufferPool(CommonBufferPoolType poolType)
{
if (!m_initialized)
{
return false;
}
auto* device = RHI::RHISystemInterface::Get()->GetDevice();
RHI::Ptr<RHI::BufferPool> bufferPool = RHI::Factory::Get().CreateBufferPool();
@@ -148,10 +148,16 @@ namespace AZ
CreateDefaultResources(desc);
Interface<ImageSystemInterface>::Register(this);
m_initialized = true;
}
void ImageSystem::Shutdown()
{
if (!m_initialized)
{
return;
}
Interface<ImageSystemInterface>::Unregister(this);
m_defaultStreamingImageControllerAsset.Release();
@@ -167,6 +173,7 @@ namespace AZ
Data::InstanceDatabase<StreamingImageController>::Destroy();
m_activeStreamingPools.clear();
m_initialized = false;
}
void ImageSystem::Update()
@@ -327,14 +327,15 @@ namespace AZ
}
}
void PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath)
bool PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath)
{
Data::Asset<AnyAsset> mappingAsset = AssetUtils::LoadAssetByProductPath<AnyAsset>(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error);
Data::Asset<AnyAsset> mappingAsset = AssetUtils::LoadCriticalAsset<AnyAsset>(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error);
bool success = LoadPassTemplateMappings(mappingAsset);
if (success)
{
Data::AssetBus::MultiHandler::BusConnect(mappingAsset->GetId());
}
return success;
}
bool PassLibrary::LoadPassTemplateMappings(Data::Asset<AnyAsset> mappingAsset)
@@ -100,9 +100,9 @@ namespace AZ
m_rootPass->m_flags.m_partOfHierarchy = true;
}
void PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath)
bool PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath)
{
m_passLibrary.LoadPassTemplateMappings(templateMappingPath);
return m_passLibrary.LoadPassTemplateMappings(templateMappingPath);
}
void PassSystem::WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath)
@@ -334,7 +334,6 @@ namespace AZ
void RPISystem::InitializeSystemAssets()
{
AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown;
if (m_systemAssetsInitialized)
{
AZ_Warning("RPISystem", false , "InitializeSystemAssets should only be called once'");
@@ -344,36 +343,47 @@ namespace AZ
//[GFX TODO][ATOM-5867] - Move file loading code within RHI to reduce coupling with RPI
AZStd::string platformLimitsFilePath = AZStd::string::format("config/platform/%s/%s/platformlimits.azasset", AZ_TRAIT_OS_PLATFORM_NAME, GetRenderApiName().GetCStr());
AZStd::to_lower(platformLimitsFilePath.begin(), platformLimitsFilePath.end());
// Wait for the platformlimits asset to be compiled (if it exists)
AzFramework::AssetSystemRequestBus::BroadcastResult(
status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, platformLimitsFilePath);
Data::Asset<RPI::AnyAsset> platformLimitsAsset = RPI::AssetUtils::LoadAssetByProductPath<RPI::AnyAsset>(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::Error);
m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset<RHI::PlatformLimits>(platformLimitsAsset);
Data::Asset<AnyAsset> platformLimitsAsset;
platformLimitsAsset = RPI::AssetUtils::LoadCriticalAsset<AnyAsset>(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::None);
// Only read the m_platformLimits if the platformLimitsAsset is ready.
// The platformLimitsAsset may not exist for null renderer which is allowed
if (platformLimitsAsset.IsReady())
{
m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset<RHI::PlatformLimits>(platformLimitsAsset);
}
m_viewSrgAsset = AssetUtils::LoadCriticalAsset<ShaderResourceGroupAsset>( m_descriptor.m_viewSrgAssetPath.c_str());
if (!m_viewSrgAsset.IsReady())
{
return;
}
m_sceneSrgAsset = AssetUtils::LoadCriticalAsset<ShaderResourceGroupAsset>(m_descriptor.m_sceneSrgAssetPath.c_str());
if (!m_sceneSrgAsset.IsReady())
{
return;
}
m_rhiSystem.Init(m_descriptor.m_rhiSystemDescriptor);
m_imageSystem.Init(m_descriptor.m_imageSystemDescriptor);
m_bufferSystem.Init();
m_dynamicDraw.Init(m_descriptor.m_dynamicDrawSystemDescriptor);
// Wait for the assets be compiled
AzFramework::AssetSystemRequestBus::BroadcastResult(
status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_viewSrgAssetPath);
AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile view SRG at '%s'", m_descriptor.m_viewSrgAssetPath.c_str());
AzFramework::AssetSystemRequestBus::BroadcastResult(
status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_sceneSrgAssetPath);
AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile scene SRG at '%s'", m_descriptor.m_sceneSrgAssetPath.c_str());
AzFramework::AssetSystemRequestBus::BroadcastResult(
status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_passTemplatesMappingPath);
AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile pass template mapping at '%s'", m_descriptor.m_passTemplatesMappingPath.c_str());
m_viewSrgAsset = AssetUtils::LoadAssetByProductPath<ShaderResourceGroupAsset>(m_descriptor.m_viewSrgAssetPath.c_str(), AssetUtils::TraceLevel::Error);
m_sceneSrgAsset = AssetUtils::LoadAssetByProductPath<ShaderResourceGroupAsset>(m_descriptor.m_sceneSrgAssetPath.c_str(), AssetUtils::TraceLevel::Error);
// Have pass system load default pass template mapping
m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath);
bool passSystemReady = m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath);
if (!passSystemReady)
{
return;
}
m_systemAssetsInitialized = true;
}
bool RPISystem::IsInitialized() const
{
return m_systemAssetsInitialized;
}
void RPISystem::InitializeSystemAssetsForTests()
{
if (m_systemAssetsInitialized)
@@ -26,6 +26,7 @@ namespace AZ
, m_windowContext(AZStd::make_shared<WindowContext>())
, m_manager(manager)
, m_name(name)
, m_viewportSize(1, 1)
{
m_windowContext->Initialize(device, nativeWindow);
AzFramework::WindowRequestBus::EventResult(
@@ -41,7 +41,11 @@ namespace AZ
const RHI::ShaderResourceGroupLayout* ShaderResourceGroupAsset::GetLayout() const
{
AZ_Assert(m_currentAPITypeIndex < m_perAPILayout.size(), "Invalid API Type index");
AZ_Error("RHI::ShaderResourceGroupLayout", m_currentAPITypeIndex < m_perAPILayout.size(), "Invalid API Type index");
if (m_currentAPITypeIndex >= m_perAPILayout.size())
{
return nullptr;
}
return m_perAPILayout[m_currentAPITypeIndex].second.get();
}
@@ -112,7 +112,7 @@ namespace AZ
bool AreaLightComponentConfig::SupportsShadows() const
{
return m_shapeType == AZ_CRC_CE("DiskShape");
return m_lightType == LightType::SpotDisk || m_lightType == LightType::Sphere;
}
bool AreaLightComponentConfig::ShadowsDisabled() const
@@ -63,5 +63,64 @@ namespace AZ
debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity));
}
}
void SphereLightDelegate::SetEnableShadow(bool enabled)
{
Base::SetEnableShadow(enabled);
if (GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled);
}
}
void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
{
if (GetShadowsEnabled() && GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size);
}
}
void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method)
{
if (GetShadowsEnabled() && GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method);
}
}
void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
{
if (GetShadowsEnabled() && GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
}
}
void SphereLightDelegate::SetPredictionSampleCount(uint32_t count)
{
if (GetShadowsEnabled() && GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count);
}
}
void SphereLightDelegate::SetFilteringSampleCount(uint32_t count)
{
if (GetShadowsEnabled() && GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count);
}
}
void SphereLightDelegate::SetPcfMethod(PcfMethod method)
{
if (GetShadowsEnabled() && GetLightHandle().IsValid())
{
GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method);
}
}
} // namespace Render
} // namespace AZ
@@ -24,6 +24,8 @@ namespace AZ
class SphereLightDelegate final
: public LightDelegateBase<PointLightFeatureProcessorInterface>
{
using Base = LightDelegateBase<PointLightFeatureProcessorInterface>;
public:
SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible);
@@ -32,6 +34,13 @@ namespace AZ
void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const override;
float GetSurfaceArea() const override;
float GetEffectiveSolidAngle() const override { return PhotometricValue::OmnidirectionalSteradians; }
void SetEnableShadow(bool enabled) override;
void SetShadowmapMaxSize(ShadowmapSize size) override;
void SetShadowFilterMethod(ShadowFilterMethod method) override;
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
void SetPredictionSampleCount(uint32_t count) override;
void SetFilteringSampleCount(uint32_t count) override;
void SetPcfMethod(PcfMethod method) override;
private:
@@ -16,7 +16,7 @@ with Lumberyard. Note: this boostrap is only designed fo be py3 compatible.
If you need DCCsi access in py27 (Autodesk Maya for instance) you may need
to implement your own boostrapper module. Currently this is boostrapped
from add_dccsi.py, as a temporty measure related to this Jira:
https://jira.agscollab.com/browse/SPEC-2581"""
SPEC-2581"""
# standard imports
import sys
import os
@@ -25,7 +25,7 @@ the provided env and launcher bat files.
If you are developing for the DCCsi you can use this launcher to start Maya:
DccScriptingInterface\Launchers\Windows\Launch_Maya_2020.bat"
To Do: https://jira.agscollab.com/browse/ATOM-5861
To Do: ATOM-5861
"""
__project__ = 'DccScriptingInterface'
@@ -43,7 +43,7 @@ Note: to get this to work unfortunatley each user must configure the wingide pre
(there is no shared project / data-driven way that I know of to set this up otherwise)
Note: lumberyard is not currently generating __init__.pyi files in that package structure:
https://jira.agscollab.com/browse/SPEC-3315
SPEC-3315
The workaround is to create them yourself (they can be empty) and needs to be in the root of each package folder, like this:
dev\Cache\AtomTechArt\pc\user\python_symbols\azlmbr\__init__.pyi
@@ -63,4 +63,4 @@ You might need to reboot wing. Then you should have auto-complete for the lumbe
Note: the entirety of azlmbr api does not generate .pyi files currently,
all of the "Behaviour Context" based classes do
non-BC modules such as azlmbr.paths currently do not
https://jira.agscollab.com/browse/SPEC-3316
SPEC-3316
@@ -40,7 +40,7 @@ Module Documentation:
<to do: further document this module>
To Do:
https://jira.agscollab.com/browse/ATOM-5859
ATOM-5859
'''
# -------------------------------------------------------------------------
@@ -22,7 +22,7 @@ Module: <DCCsi>\azpy\shared\common\config_utils.py
<to do: further document this module>
To Do:
https://jira.agscollab.com/browse/ATOM-5859
ATOM-5859
'''
# -------------------------------------------------------------------------
@@ -168,8 +168,8 @@ namespace EMotionFX
// The skin attachment should now receive morph values from the main actor.
const Pose& attachPose = *m_attachmentActorInstance->GetTransformData()->GetCurrentPose();
ASSERT_EQ(attachPose.GetNumMorphWeights(), 4);
EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(0), 0.0f); // Once we auto register missing morphs this should be 0.5. See https://jira.agscollab.com/browse/LY-100212
EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(1), 0.0f); // Once we auto register missing morphs this should be 0.6. See https://jira.agscollab.com/browse/LY-100212
EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(0), 0.0f); // Once we auto register missing morphs this should be 0.5. See LY-100212
EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(1), 0.0f); // Once we auto register missing morphs this should be 0.6. See LY-100212
EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(2), 0.1f);
EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(3), 0.2f);
};
@@ -1,7 +0,0 @@
{
"Amazon": {
"AssetProcessor": {
"Settings": {}
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1a1623477f4e2e5ef0440ecfc0c08e775d9b5f12d8ebc6b434e8212bf3445bcd
size 224
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:31b247223c1116d4fc014189a9d8d86d4458b792c1120442673631136fd89520
size 222
@@ -1,11 +0,0 @@
<RCC>
<qresource>
<file>refresh-active.png</file>
<file>warning.png</file>
<file>refresh.png</file>
<file>info.png</file>
<file>Backward.png</file>
<file>Forward.png</file>
<file>reset.png</file>
</qresource>
</RCC>

Some files were not shown because too many files have changed in this diff Show More