Merge branch 'main' into cpack_installer

This commit is contained in:
scottr
2021-04-22 14:25:35 -07:00
214 changed files with 3074 additions and 2092 deletions
@@ -22,7 +22,7 @@ import ly_test_tools.environment.file_system as file_system
import ly_test_tools.log.log_monitor
import ly_test_tools.environment.waiter as waiter
@pytest.mark.SUITE_sandbox
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['auto_test'])
@@ -31,14 +31,13 @@ class TestPythonAssetProcessing(object):
unexpected_lines = []
expected_lines = [
'Mock asset exists',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_negative.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_positive.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found'
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found'
]
timeout = 180
halt_on_unexpected = False
@@ -26,8 +26,9 @@ assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdB
if (assetId.is_valid() is False):
raise_and_stop(f'Mock AssetId is not valid! Got {assetId.to_string()} instead')
if (assetId.to_string().endswith(':54c06b89') is False):
raise_and_stop(f'Mock AssetId has unexpected sub-id for {mockAssetPath}!')
assetIdString = assetId.to_string()
if (assetIdString.endswith(':528cca58') is False):
raise_and_stop(f'Mock AssetId {assetIdString} has unexpected sub-id for {mockAssetPath}!')
print ('Mock asset exists')
@@ -41,12 +42,12 @@ def test_azmodel_product(generatedModelAssetPath, expectedSubId):
else:
print(f'Expected subId for asset ({generatedModelAssetPath}) found')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel', '10412075')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_positive.azmodel', '10d16e68')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_negative.azmodel', '10a71973')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Y_positive.azmodel', '10130556')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Y_negative.azmodel', '1065724d')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Z_positive.azmodel', '1024be55')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Z_negative.azmodel', '1052c94e')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel', '10315ae0')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel', '10661093')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel', '10af8810')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel', '10f8c263')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel', '100ac47f')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel', '105d8e0c')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel', '1002d464')
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
@@ -1,7 +1,6 @@
"""
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
@@ -27,7 +26,10 @@ def get_mesh_node_names(sceneGraph):
nodeContent = sceneGraph.get_node_content(node)
if nodeContent is not None and nodeContent.CastWithTypeName('MeshData'):
if sceneGraph.is_node_end_point(node) is False:
meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node)))
nodeName = sceneData.SceneGraphName(sceneGraph.get_node_name(node))
nodePath = nodeName.get_path()
if (len(nodeName.get_path())):
meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node)))
# advance to next node
if sceneGraph.has_node_sibling(node):
@@ -54,17 +56,7 @@ def update_manifest(scene):
meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, sourceFilenameOnly + chunkPath)) + '}'
sceneManifest.mesh_group_add_comment(meshGroup, 'auto generated by scene manifest')
sceneManifest.mesh_group_add_advanced_coordinate_system(meshGroup, None, None, None, 1.0)
# create selection node list
pathSet = set()
for meshIndex in range(len(meshNameList)):
targetPath = meshNameList[meshIndex].get_path()
if (activeMeshIndex == meshIndex):
sceneManifest.mesh_group_select_node(meshGroup, targetPath)
else:
if targetPath not in pathSet:
pathSet.update(targetPath)
sceneManifest.mesh_group_unselect_node(meshGroup, targetPath)
sceneManifest.mesh_group_select_node(meshGroup, chunkPath)
return sceneManifest.export()
@@ -85,4 +77,4 @@ def main():
mySceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
if __name__ == "__main__":
main()
main()
@@ -117,7 +117,8 @@ class EditorTestHelper:
# Set the viewport back to whatever size it was at the start and restore the pane layout
general.set_viewport_size(int(self.viewport_size.x), int(self.viewport_size.y))
general.set_viewport_expansion_policy("AutoExpand")
general.set_view_pane_layout(self.viewport_layout)
# Temporarily disabling reset of view pane layout: LYN-3120
# general.set_view_pane_layout(self.viewport_layout)
general.update_viewport()
self.log("test finished")
@@ -53,6 +53,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
@@ -59,6 +59,8 @@ class TestAreaComponentsSliceCreationAndVisibilityToggle(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) C2627900 Verifies if a slice containing the Vegetation Layer Spawner component can be created.
# 2.1) Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
@@ -63,6 +63,8 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components
spawner_center_point = math.Vector3(520.0, 520.0, 32.0)
asset_path = os.path.join("Slices", "1m_cube.dynamicslice")
@@ -61,6 +61,8 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components
spawner_center_point = math.Vector3(520.0, 520.0, 32.0)
asset_path = os.path.join("Slices", "1m_cube.dynamicslice")
@@ -43,6 +43,7 @@ class TestDynamicSliceInstanceSpawner(EditorTestHelper):
use_terrain=False,
)
general.idle_wait(1.0)
general.set_current_view_position(512.0, 480.0, 38.0)
# Grab the UUID that we need for creating an Dynamic Slice Instance Spawner
dynamic_slice_spawner_uuid = azlmbr.math.Uuid_CreateString('{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}', 0)
@@ -65,6 +65,8 @@ class TestDynamicSliceInstanceSpawnerEmbeddedEditor(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
@@ -65,6 +65,8 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components and switch the Vegetation Asset List Source
# Type to External
entity_position = math.Vector3(512.0, 512.0, 32.0)
@@ -43,6 +43,7 @@ class TestEmptyInstanceSpawner(EditorTestHelper):
use_terrain=False,
)
general.idle_wait(1.0)
general.set_current_view_position(512.0, 480.0, 38.0)
# Grab the UUID that we need for creating an Empty Spawner
empty_spawner_uuid = azlmbr.math.Uuid_CreateString('{23C40FD4-A55F-4BD3-BE5B-DC5423F217C2}', 0)
@@ -60,6 +60,8 @@ class TestLayerSpawnerInheritBehavior(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# Create Emitter entity and add the required components
position = math.Vector3(512.0, 512.0, 32.0)
emitter_entity = dynveg.create_surface_entity("emitter_entity", position, 16.0, 16.0, 1.0)
@@ -61,6 +61,9 @@ class test_MeshBlocker_InstancesBlockedByMesh(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
# Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
@@ -90,7 +90,7 @@ class TestRotationModifierOverrides_InstancesRotateWithinRange(EditorTestHelper)
terrain_texture_resolution=4096,
use_terrain=False,
)
general.run_console("e_WaterOcean=0")
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create vegetation entity and add components
entity_position = math.Vector3(512.0, 512.0, 32.0)
@@ -103,7 +103,7 @@ class TestRotationModifier_InstancesRotateWithinRange(EditorTestHelper):
terrain_texture_resolution=4096,
use_terrain=False,
)
general.run_console("e_WaterOcean=0")
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Set up vegetation entities
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
@@ -17,6 +17,7 @@ import azlmbr.paths
import azlmbr.editor as editor
import azlmbr.entity as EntityId
import azlmbr.components as components
import azlmbr.legacy.general as general
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
import automatedtesting_shared.hydra_editor_utils as hydra
@@ -48,6 +49,8 @@ class TestSlopeFilterFilterStageToggle(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
@@ -103,6 +103,8 @@ class TestExclusiveSurfaceMasksTag(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
@@ -104,6 +104,8 @@ class TestInclusiveSurfaceMasksTag(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
@@ -15,6 +15,7 @@ import azlmbr.math as math
import azlmbr.paths
import azlmbr.editor as editor
import azlmbr.bus as bus
import azlmbr.legacy.general as general
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
import automatedtesting_shared.hydra_editor_utils as hydra
@@ -52,6 +53,8 @@ class TestSystemSettingsSectorPointDensity(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
@@ -15,6 +15,7 @@ import azlmbr.math as math
import azlmbr.paths
import azlmbr.editor as editor
import azlmbr.bus as bus
import azlmbr.legacy.general as general
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
import automatedtesting_shared.hydra_editor_utils as hydra
@@ -48,6 +49,8 @@ class TestSystemSettingsSectorSize(EditorTestHelper):
use_terrain=False,
)
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
+1 -352
View File
@@ -11,7 +11,7 @@
*/
#pragma once
#include <LyShine/ILyShine.h>
#include <IRenderer.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Color.h>
@@ -115,355 +115,4 @@ public: // member functions
//! Implement virtual destructor just for safety.
virtual ~IDraw2d() {}
//! Start a section of 2D drawing function calls. This will set appropriate render state.
//
//! \param deferCalls If true then actual render calls are deferred until the end of the frame
virtual void BeginDraw2d(bool deferCalls = false) = 0;
//! Start a section of 2D drawing function calls. This will set appropriate render state.
//! This variant allows the viewport size to be specified
//
//! \param viewportSize The size of the viewport being rendered to
//! \param deferCalls If true then actual render calls are deferred until the end of the frame
virtual void BeginDraw2d(AZ::Vector2 viewportSize, bool deferCalls = false) = 0;
//! End a section of 2D drawing function calls. This will reset some render state.
virtual void EndDraw2d() = 0;
//! Draw a textured quad with the top left corner at the given position.
//
//! The image is drawn with the color specified by SetShapeColor and the opacity
//! passed as an argument.
//! If rotation is non-zero then the quad is rotated. If the pivot point is
//! provided then the points of the quad are rotated about that point, otherwise
//! they are rotated about the top left corner of the quad.
//! \param texId The texture ID returned by ITexture::GetTextureID()
//! \param position Position of the top left corner of the quad (before rotation) in pixels
//! \param size The width and height of the quad. Use texture width and height to avoid minification,
//! magnification or stretching (assuming the minMaxTexCoords are left to the default)
//! \param opacity The alpha value used when blending
//! \param rotation Angle of rotation in degrees counter-clockwise
//! \param pivotPoint The point about which the quad is rotated
//! \param minMaxTexCoords An optional two component array. The first component is the UV coord for the top left
//! point of the quad and the second is the UV coord of the bottom right point of the quad
//! \param imageOptions Optional struct specifying options that tend to be the same from call to call
virtual void DrawImage(int texId, AZ::Vector2 position, AZ::Vector2 size, float opacity = 1.0f,
float rotation = 0.0f, const AZ::Vector2* pivotPoint = nullptr, const AZ::Vector2* minMaxTexCoords = nullptr,
ImageOptions* imageOptions = nullptr) = 0;
//! Draw a textured quad where the position specifies the point specified by the alignment.
//
//! Rotation is always around the position.
//! \param texId The texture ID returned by ITexture::GetTextureID()
//! \param position Position align point of the quad (before rotation) in pixels
//! \param size The width and height of the quad. Use texture width and height to avoid minification,
//! magnification or stretching (assuming the minMaxTexCoords are left to the default)
//! \param horizontalAlignment Specifies how the quad is horizontally aligned to the given position
//! \param verticalAlignment Specifies how the quad is vertically aligned to the given position
//! \param opacity The alpha value used when blending
//! \param rotation Angle of rotation in degrees counter-clockwise
//! \param minMaxTexCoords An optional two component array. The first component is the UV coord for the top left
//! point of the quad and the second is the UV coord of the bottom right point of the quad
//! \param imageOptions Optional struct specifying options that tend to be the same from call to call
virtual void DrawImageAligned(int texId, AZ::Vector2 position, AZ::Vector2 size,
HAlign horizontalAlignment, VAlign verticalAlignment,
float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* minMaxTexCoords = nullptr,
ImageOptions* imageOptions = nullptr) = 0;
//! Draw a textured quad where the position, color and uv of each point is specified explicitly
//
//! \param texId The texture ID returned by ITexture::GetTextureID()
//! \param verts An array of 4 vertices, in clockwise order (e.g. top left, top right, bottom right, bottom left)
//! \param blendMode UseDefault means default blend mode (currently GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA)
//! \param pixelRounding Whether and how to round pixel coordinates
//! \param baseState Additional render state to pass to or into value passed to renderer SetState
virtual void DrawQuad(int texId, VertexPosColUV* verts,
int blendMode = UseDefault,
Rounding pixelRounding = Rounding::Nearest,
int baseState = UseDefault) = 0;
//! Draw a line
//
//! \param start The start position
//! \param end The end position
//! \param color The color of the line
//! \param blendMode UseDefault means default blend mode (currently GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA)
//! \param pixelRounding Whether and how to round pixel coordinates
//! \param baseState Additional render state to pass to or into value passed to renderer SetState
virtual void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color,
int blendMode = UseDefault,
IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest,
int baseState = UseDefault) = 0;
//! Draw a line with a texture so it can be dotted or dashed
//
//! \param texId The texture ID returned by ITexture::GetTextureID()
//! \param verts An array of 2 vertices for the start and end points of the line
//! \param blendMode UseDefault means default blend mode (currently GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA)
//! \param pixelRounding Whether and how to round pixel coordinates
//! \param baseState Additional render state to pass to or into value passed to renderer SetState
virtual void DrawLineTextured(int texId, VertexPosColUV* verts,
int blendMode = UseDefault,
IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest,
int baseState = UseDefault) = 0;
//! Draw a text string. Only supports ASCII text.
//
//! The font and effect used to render the text are specified in the textOptions structure
//! \param textString A null terminated ASCII text string. May contain \n characters
//! \param position Position of the text in pixels. Alignment values in textOptions affect actual position
//! \param pointSize The size of the font to use
//! \param opacity The opacity (alpha value) to use to draw the text
//! \param textOptions Pointer to an options struct. If null the default options are used
virtual void DrawText(const char* textString, AZ::Vector2 position, float pointSize,
float opacity = 1.0f, TextOptions* textOptions = nullptr) = 0;
//! Get the width and height (in pixels) that would be used to draw the given text string.
//
//! Pass the same parameter values that would be used to draw the string
virtual AZ::Vector2 GetTextSize(const char* textString, float pointSize, TextOptions* textOptions = nullptr) = 0;
//! Get the width of the rendering viewport (in pixels).
//
//! If rendering full screen this is the native width from IRenderer
virtual float GetViewportWidth() const = 0;
//! Get the height of the rendering viewport (in pixels).
//
//! If rendering full screen this is the native width from IRenderer
virtual float GetViewportHeight() const = 0;
//! Get the default values that would be used if no image options were passed in
//
//! This is a convenient way to initialize the imageOptions struct
virtual const ImageOptions& GetDefaultImageOptions() const = 0;
//! Get the default values that would be used if no text options were passed in
//
//! This is a convenient way to initialize the textOptions struct
virtual const TextOptions& GetDefaultTextOptions() const = 0;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//! Helper class for using the IDraw2d interface
//!
//! The Draw2dHelper class is an inline wrapper that provides two convenience features:
//! 1. It automatically calls BeginDraw2d/EndDraw2d in its construction/destruction.
//! 2. It automatically sets member options structures to their defaults and provides set functions
//! to set them.
class Draw2dHelper
{
public: // member functions
//! Start a section of 2D drawing function calls. This will set appropriate render state.
Draw2dHelper(bool deferCalls = false)
: m_draw2d(GetDraw2d())
{
if (m_draw2d)
{
m_draw2d->BeginDraw2d(deferCalls);
m_imageOptions = m_draw2d->GetDefaultImageOptions();
m_textOptions = m_draw2d->GetDefaultTextOptions();
}
}
//! End a section of 2D drawing function calls. This will reset some render state.
~Draw2dHelper()
{
if (m_draw2d)
{
m_draw2d->EndDraw2d();
}
}
//! Draw a textured quad, optional rotation is counter-clockwise in degrees.
//
//! See IDraw2d:DrawImage for parameter descriptions
void DrawImage(int texId, AZ::Vector2 position, AZ::Vector2 size, float opacity = 1.0f,
float rotation = 0.0f, const AZ::Vector2* pivotPoint = nullptr, const AZ::Vector2* minMaxTexCoords = nullptr)
{
if (m_draw2d)
{
m_draw2d->DrawImage(texId, position, size, opacity, rotation, pivotPoint, minMaxTexCoords, &m_imageOptions);
}
}
//! Draw a textured quad where the position specifies the point specified by the alignment.
//
//! See IDraw2d:DrawImageAligned for parameter descriptions
void DrawImageAligned(int texId, AZ::Vector2 position, AZ::Vector2 size,
IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment,
float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* minMaxTexCoords = nullptr)
{
if (m_draw2d)
{
m_draw2d->DrawImageAligned(texId, position, size, horizontalAlignment, verticalAlignment,
opacity, rotation, minMaxTexCoords, &m_imageOptions);
}
}
//! Draw a textured quad where the position, color and uv of each point is specified explicitly
//
//! See IDraw2d:DrawQuad for parameter descriptions
void DrawQuad(int texId, IDraw2d::VertexPosColUV* verts, int blendMode = IDraw2d::UseDefault,
IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest,
int baseState = IDraw2d::UseDefault)
{
if (m_draw2d)
{
m_draw2d->DrawQuad(texId, verts, blendMode, pixelRounding, baseState);
}
}
//! Draw a line
//
//! See IDraw2d:DrawLine for parameter descriptions
void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color, int blendMode = IDraw2d::UseDefault,
IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest,
int baseState = IDraw2d::UseDefault)
{
if (m_draw2d)
{
m_draw2d->DrawLine(start, end, color, blendMode, pixelRounding, baseState);
}
}
//! Draw a line with a texture so it can be dotted or dashed
//
//! See IDraw2d:DrawLineTextured for parameter descriptions
void DrawLineTextured(int texId, IDraw2d::VertexPosColUV* verts, int blendMode = IDraw2d::UseDefault,
IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest,
int baseState = IDraw2d::UseDefault)
{
if (m_draw2d)
{
m_draw2d->DrawLineTextured(texId, verts, blendMode, pixelRounding, baseState);
}
}
//! Draw a text string. Only supports ASCII text.
//
//! See IDraw2d:DrawText for parameter descriptions
void DrawText(const char* textString, AZ::Vector2 position, float pointSize, float opacity = 1.0f)
{
if (m_draw2d)
{
m_draw2d->DrawText(textString, position, pointSize, opacity, &m_textOptions);
}
}
//! Get the width and height (in pixels) that would be used to draw the given text string.
//
//! See IDraw2d:GetTextSize for parameter descriptions
AZ::Vector2 GetTextSize(const char* textString, float pointSize)
{
if (m_draw2d)
{
return m_draw2d->GetTextSize(textString, pointSize, &m_textOptions);
}
else
{
return AZ::Vector2(0, 0);
}
}
// State management
//! Set the blend mode used for images, default is GS_BLSRC_SRCALPHA|GS_BLDST_ONEMINUSSRCALPHA.
void SetImageBlendMode(int mode) { m_imageOptions.blendMode = mode; }
//! Set the color used for DrawImage and other image drawing.
void SetImageColor(AZ::Vector3 color) { m_imageOptions.color = color; }
//! Set whether images are rounded to have the points on exact pixel boundaries.
void SetImagePixelRounding(IDraw2d::Rounding round) { m_imageOptions.pixelRounding = round; }
//! Set the base state (that blend mode etc is combined with) used for images, default is GS_NODEPTHTEST.
void SetImageBaseState(int state) { m_imageOptions.baseState = state; }
//! Set the text font.
void SetTextFont(IFFont* font) { m_textOptions.font = font; }
//! Set the text font effect index.
void SetTextEffectIndex(unsigned int effectIndex) { m_textOptions.effectIndex = effectIndex; }
//! Set the text color.
void SetTextColor(AZ::Vector3 color) { m_textOptions.color = color; }
//! Set the text alignment.
void SetTextAlignment(IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment)
{
m_textOptions.horizontalAlignment = horizontalAlignment;
m_textOptions.verticalAlignment = verticalAlignment;
}
//! Set a drop shadow for text drawing. An alpha of zero disables drop shadow.
void SetTextDropShadow(AZ::Vector2 offset, AZ::Color color)
{
m_textOptions.dropShadowOffset = offset;
m_textOptions.dropShadowColor = color;
}
//! Set a rotation for the text. The text rotates around its position (taking into account alignment).
void SetTextRotation(float rotation)
{
m_textOptions.rotation = rotation;
}
//! Set the base state (that blend mode etc is combined with) used for text, default is GS_NODEPTHTEST.
void SetTextBaseState(int state) { m_textOptions.baseState = state; }
public: // static member functions
//! Helper to get the IDraw2d interface
static IDraw2d* GetDraw2d() { return (gEnv && gEnv->pLyShine) ? gEnv->pLyShine->GetDraw2d() : nullptr; }
//! Get the width of the rendering viewport (in pixels).
static float GetViewportWidth()
{
IDraw2d* draw2d = GetDraw2d();
return (draw2d) ? draw2d->GetViewportWidth() : 0.0f;
}
//! Get the height of the rendering viewport (in pixels).
static float GetViewportHeight()
{
IDraw2d* draw2d = GetDraw2d();
return (draw2d) ? draw2d->GetViewportHeight() : 0.0f;
}
//! Round the X and Y coordinates of a point using the given rounding policy
template<typename T>
static T RoundXY(T value, IDraw2d::Rounding roundingType)
{
T result = value;
switch (roundingType)
{
case IDraw2d::Rounding::None:
// nothing to do
break;
case IDraw2d::Rounding::Nearest:
result.SetX(floor(value.GetX() + 0.5f));
result.SetY(floor(value.GetY() + 0.5f));
break;
case IDraw2d::Rounding::Down:
result.SetX(floor(value.GetX()));
result.SetY(floor(value.GetY()));
break;
case IDraw2d::Rounding::Up:
result.SetX(ceil(value.GetX()));
result.SetY(ceil(value.GetY()));
break;
}
return result;
}
protected: // attributes
IDraw2d::ImageOptions m_imageOptions; //!< image options are stored locally and updated by member functions
IDraw2d::TextOptions m_textOptions; //!< text options are stored locally and updated by member functions
IDraw2d* m_draw2d;
};
@@ -1,79 +0,0 @@
/*
* 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 <LyShine/IDraw2d.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
//! Interface used by UI components to render to the canvas
//
//! The IUiRenderer provides helper functions for UI rendering and also manages state that
//! persists between UI elements when rendering a UI canvas.
//! For example one UI component can turn on stencil test and that affects all UI rendering
//! until it is turned off.
//!
//! This is a singleton class that is accessed via IUiRenderer::Get() which is a shortcut for
//! gEnv->pLyShine()->GetUiRenderer();
class IUiRenderer
{
public: // types
public: // member functions
//! Implement virtual destructor for safety.
virtual ~IUiRenderer() {}
//! Start the rendering of a UI canvas
virtual void BeginCanvasRender(AZ::Vector2 viewportSize) = 0;
//! End the rendering of a UI canvas
virtual void EndCanvasRender() = 0;
//! Get the current base state
virtual int GetBaseState() = 0;
//! Set the base state
virtual void SetBaseState(int state) = 0;
//! Get the current stencil test reference value
virtual uint32 GetStencilRef() = 0;
//! Set the stencil test reference value
virtual void SetStencilRef(uint32) = 0;
//! Increment the current stencil reference value
virtual void IncrementStencilRef() = 0;
//! Decrement the current stencil reference value
virtual void DecrementStencilRef() = 0;
//! Get flag that indicates we are rendering into a mask. Used to avoid masks on child mask elements.
virtual bool IsRenderingToMask() = 0;
//! Set flag that we are rendering into a mask. Used to avoid masks on child mask elements.
virtual void SetIsRenderingToMask(bool isRenderingToMask) = 0;
//! Push an alpha fade, this is multiplied with any existing alpha fade from parents
virtual void PushAlphaFade(float alphaFadeValue) = 0;
//! Pop an alpha fade off the stack
virtual void PopAlphaFade() = 0;
//! Get the current alpha fade value
virtual float GetAlphaFade() const = 0;
public: // static member functions
//! Helper function to get the singleton UiRenderer
static IUiRenderer* Get() { return gEnv->pLyShine->GetUiRenderer(); }
};
@@ -20,6 +20,7 @@
#include <AzCore/Component/Entity.h>
#include <LyShine/UiAssetTypes.h>
#include <LyShine/UiBase.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
+1
View File
@@ -4094,6 +4094,7 @@ void CSystem::CreateSystemVars()
"0 = Suppress Asserts\n"
"1 = Log Asserts\n"
"2 = Show Assert Dialog\n"
"3 = Crashes the Application on Assert\n"
"Note: when set to '0 = Suppress Asserts', assert expressions are still evaluated. To turn asserts into a no-op, undefine AZ_ENABLE_TRACING and recompile.",
OnAssertLevelCvarChanged);
CSystem::SetAssertLevel(defaultAssertValue);
@@ -63,13 +63,13 @@ namespace AZ
static AssetTrackingImpl* GetSharedInstance();
static ThreadData& GetSharedThreadData();
using MasterAssets = AZStd::unordered_map<AssetTrackingId, AssetMasterInfo, AZStd::hash<AssetTrackingId>, AZStd::equal_to<AssetTrackingId>, AZStdAssetTrackingAllocator>;
using PrimaryAssets = AZStd::unordered_map<AssetTrackingId, AssetPrimaryInfo, AZStd::hash<AssetTrackingId>, AZStd::equal_to<AssetTrackingId>, AZStdAssetTrackingAllocator>;
using ThreadData = ThreadData;
using mutex_type = AZStd::mutex;
using lock_type = AZStd::lock_guard<mutex_type>;
mutex_type m_mutex;
MasterAssets m_masterAssets;
PrimaryAssets m_primaryAssets;
AssetTreeNodeBase* m_assetRoot = nullptr;
AssetAllocationTableBase* m_allocationTable = nullptr;
bool m_performingAnalysis = false;
@@ -118,7 +118,7 @@ namespace AZ
auto& threadData = GetSharedThreadData();
AssetTreeNodeBase* parentAsset = threadData.m_currentAssetStack.empty() ? nullptr : threadData.m_currentAssetStack.back();
AssetTreeNodeBase* childAsset;
AssetMasterInfo* assetMasterInfo;
AssetPrimaryInfo* assetPrimaryInfo;
if (!parentAsset)
{
@@ -128,22 +128,22 @@ namespace AZ
{
lock_type lock(m_mutex);
// Locate or create the master record for this asset
auto masterItr = m_masterAssets.find(assetId);
// Locate or create the primary record for this asset
auto primaryItr = m_primaryAssets.find(assetId);
if (masterItr != m_masterAssets.end())
if (primaryItr != m_primaryAssets.end())
{
assetMasterInfo = &masterItr->second;
assetPrimaryInfo = &primaryItr->second;
}
else
{
auto insertResult = m_masterAssets.emplace(assetId, AssetMasterInfo());
assetMasterInfo = &insertResult.first->second;
assetMasterInfo->m_id = &insertResult.first->first;
auto insertResult = m_primaryAssets.emplace(assetId, AssetPrimaryInfo());
assetPrimaryInfo = &insertResult.first->second;
assetPrimaryInfo->m_id = &insertResult.first->first;
}
// Add this asset to the stack for this thread's context
childAsset = parentAsset->FindOrAddChild(assetId, assetMasterInfo);
childAsset = parentAsset->FindOrAddChild(assetId, assetPrimaryInfo);
}
threadData.m_currentAssetStack.push_back(childAsset);
@@ -304,7 +304,7 @@ namespace AZ
char* pos = buffer;
for (auto itr = assetStack.rbegin(); itr != assetStack.rend(); ++itr)
{
pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetMasterInfo()->m_id->m_id.c_str());
pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetPrimaryInfo()->m_id->m_id.c_str());
if (pos >= buffer + BUFFER_SIZE)
{
@@ -79,9 +79,9 @@ namespace AZ
AssetTrackingString m_id;
};
// Master information about an asset.
// Primary information about an asset.
// Currently just contains the ID of the asset, but in the future may carry additional information about that asset (such as where in code it was initialized).
struct AssetMasterInfo
struct AssetPrimaryInfo
{
const AssetTrackingId* m_id;
};
@@ -90,8 +90,8 @@ namespace AZ
class AssetTreeNodeBase
{
public:
virtual const AssetMasterInfo* GetAssetMasterInfo() const = 0;
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetMasterInfo* info) = 0;
virtual const AssetPrimaryInfo* GetAssetPrimaryInfo() const = 0;
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) = 0;
};
// Base class for an asset tree. Implemented by the template AssetTree<>.
@@ -29,18 +29,18 @@ namespace AZ
class AssetTreeNode : public AssetTreeNodeBase
{
public:
AssetTreeNode(const AssetMasterInfo* masterInfo = nullptr, AssetTreeNode* parent = nullptr) :
m_masterInfo(masterInfo),
AssetTreeNode(const AssetPrimaryInfo* primaryInfo = nullptr, AssetTreeNode* parent = nullptr) :
m_primaryinfo(primaryInfo),
m_parent(parent)
{
}
const AssetMasterInfo* GetAssetMasterInfo() const override
const AssetPrimaryInfo* GetAssetPrimaryInfo() const override
{
return m_masterInfo;
return m_primaryinfo;
}
AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetMasterInfo* info) override
AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) override
{
AssetTreeNodeBase* result = nullptr;
auto childItr = m_children.find(id);
@@ -61,7 +61,7 @@ namespace AZ
using AssetMap = AssetTrackingMap<AssetTrackingId, AssetTreeNode>;
const AssetMasterInfo* m_masterInfo;
const AssetPrimaryInfo* m_primaryinfo;
AssetTreeNode* m_parent;
AssetMap m_children;
AssetDataT m_data;
+9 -2
View File
@@ -70,6 +70,7 @@ namespace AZ
static const char* logVerbosityUID = "sys_LogLevel";
static const int assertLevel_log = 1;
static const int assertLevel_nativeUI = 2;
static const int assertLevel_crash = 3;
static const int logLevel_errorWarning = 1;
static const int logLevel_full = 2;
static AZ::EnvironmentVariable<AZStd::unordered_set<size_t>> g_ignoredAsserts;
@@ -289,8 +290,8 @@ namespace AZ
}
#if AZ_ENABLE_TRACE_ASSERTS
//display native UI dialogs at verbosity level 2 or higher
if (currentLevel >= assertLevel_nativeUI)
//display native UI dialogs at verbosity level 2
if (currentLevel == assertLevel_nativeUI)
{
AZ::NativeUI::AssertAction buttonResult;
EBUS_EVENT_RESULT(buttonResult, AZ::NativeUI::NativeUIRequestBus, DisplayAssertDialog, dialogBoxText);
@@ -314,7 +315,13 @@ namespace AZ
break;
}
}
else
#endif //AZ_ENABLE_TRACE_ASSERTS
// Crash the application directly at assert level 3
if (currentLevel >= assertLevel_crash)
{
AZ_Crash();
}
}
g_alreadyHandlingAssertOrFatal = false;
}
+29 -2
View File
@@ -146,8 +146,8 @@ namespace AZ
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("GetTranslated", &Aabb::GetTranslated)
->Method("GetSurfaceArea", &Aabb::GetSurfaceArea)
->Method("GetTransformedObb", &Aabb::GetTransformedObb)
->Method("GetTransformedAabb", &Aabb::GetTransformedAabb)
->Method("GetTransformedObb", static_cast<Obb(Aabb::*)(const Transform&) const>(&Aabb::GetTransformedObb))
->Method("GetTransformedAabb", static_cast<Aabb(Aabb::*)(const Transform&) const>(&Aabb::GetTransformedAabb))
->Method("ApplyTransform", &Aabb::ApplyTransform)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("Clone", [](const Aabb& rhs) -> Aabb { return rhs; })
@@ -195,6 +195,20 @@ namespace AZ
}
Obb Aabb::GetTransformedObb(const Matrix3x4& matrix3x4) const
{
Matrix3x4 matrixNoScale = matrix3x4;
const AZ::Vector3 scale = matrixNoScale.ExtractScale();
const AZ::Quaternion rotation = AZ::Quaternion::CreateFromMatrix3x4(matrixNoScale);
return Obb::CreateFromPositionRotationAndHalfLengths(
matrix3x4 * GetCenter(),
rotation,
0.5f * scale * GetExtents()
);
}
void Aabb::ApplyTransform(const Transform& transform)
{
Vector3 a, b, axisCoeffs;
@@ -224,4 +238,17 @@ namespace AZ
m_min = newMin;
m_max = newMax;
}
void Aabb::ApplyMatrix3x4(const Matrix3x4& matrix3x4)
{
const AZ::Vector3 extents = GetExtents();
const AZ::Vector3 center = matrix3x4 * GetCenter();
AZ::Vector3 newHalfExtents(
0.5f * matrix3x4.GetRowAsVector3(0).GetAbs().Dot(extents),
0.5f * matrix3x4.GetRowAsVector3(1).GetAbs().Dot(extents),
0.5f * matrix3x4.GetRowAsVector3(2).GetAbs().Dot(extents));
m_min = center - newHalfExtents;
m_max = center + newHalfExtents;
}
}
+12 -2
View File
@@ -129,11 +129,21 @@ namespace AZ
void ApplyTransform(const Transform& transform);
void ApplyMatrix3x4(const Matrix3x4& matrix3x4);
void MultiplyByScale(const Vector3& scale);
//! Transforms an Aabb and returns the resulting Obb.
class Obb GetTransformedObb(const Transform& transform) const;
[[nodiscard]] Obb GetTransformedObb(const Transform& transform) const;
//! Transforms an Aabb and returns the resulting Obb.
[[nodiscard]] Obb GetTransformedObb(const Matrix3x4& matrix3x4) const;
//! Returns a new AABB containing the transformed AABB.
Aabb GetTransformedAabb(const Transform& transform) const;
[[nodiscard]] Aabb GetTransformedAabb(const Transform& transform) const;
//! Returns a new AABB containing the transformed AABB.
[[nodiscard]] Aabb GetTransformedAabb(const Matrix3x4& matrix3x4) const;
//! Checks if this aabb is equal to another within a floating point tolerance.
bool IsClose(const Aabb& rhs, float tolerance = Constants::Tolerance) const;
@@ -292,6 +292,14 @@ namespace AZ
}
AZ_MATH_INLINE void Aabb::MultiplyByScale(const Vector3& scale)
{
m_min *= scale;
m_max *= scale;
AZ_MATH_ASSERT(IsValid(), "Min must be less than Max");
}
AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Transform& transform) const
{
Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max);
@@ -300,6 +308,14 @@ namespace AZ
}
AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Matrix3x4& matrix3x4) const
{
Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max);
aabb.ApplyMatrix3x4(matrix3x4);
return aabb;
}
AZ_MATH_INLINE bool Aabb::IsClose(const Aabb& rhs, float tolerance) const
{
return m_min.IsClose(rhs.m_min, tolerance) && m_max.IsClose(rhs.m_max, tolerance);
@@ -105,7 +105,7 @@ namespace UnitTest
EXPECT_EQ(&rootAsset, &m_env->m_tree.GetRoot());
ASSERT_NE(itr, rootAsset.m_children.end());
EXPECT_EQ(itr->second.m_masterInfo->m_id->m_id, "TestScopedAllocation.1");
EXPECT_EQ(itr->second.m_primaryinfo->m_id->m_id, "TestScopedAllocation.1");
EXPECT_EQ(&itr->second, m_env->m_table.FindAllocation(TEST_POINTER));
@@ -15,6 +15,7 @@
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
using namespace AZ;
@@ -385,4 +386,77 @@ namespace UnitTest
EXPECT_TRUE(aabb.GetMin().IsClose(transAabb.GetMin()));
EXPECT_TRUE(aabb.GetMax().IsClose(transAabb.GetMax()));
}
TEST(MATH_AabbTransform, GetTransformedObbMatrix3x4)
{
Vector3 min(-1.0f, -2.0f, -3.0f);
Vector3 max(4.0f, 3.0f, 2.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Quaternion rotation(0.46f, 0.26f, 0.58f, 0.62f);
Vector3 translation(5.0f, 7.0f, 9.0f);
Matrix3x4 matrix3x4 = Matrix3x4::CreateFromQuaternionAndTranslation(rotation, translation);
matrix3x4.MultiplyByScale(Vector3(0.5f, 1.5f, 2.0f));
Obb obb = aabb.GetTransformedObb(matrix3x4);
EXPECT_THAT(obb.GetRotation(), IsClose(rotation));
EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(1.25f, 3.75f, 5.0f)));
EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(3.928f, 7.9156f, 9.3708f)));
}
TEST(MATH_AabbTransform, GetTransformedAabbMatrix3x4)
{
Vector3 min(2.0f, 3.0f, 5.0f);
Vector3 max(6.0f, 5.0f, 11.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Quaternion rotation(0.34f, 0.46f, 0.58f, 0.58f);
Vector3 translation(-3.0f, -4.0f, -5.0f);
Matrix3x4 matrix3x4 = Matrix3x4::CreateFromQuaternionAndTranslation(rotation, translation);
matrix3x4.MultiplyByScale(Vector3(1.2f, 0.8f, 2.0f));
Aabb transformedAabb = aabb.GetTransformedAabb(matrix3x4);
EXPECT_THAT(transformedAabb.GetMin(), IsClose(Vector3(4.1488f, -0.01216f, -0.31904f)));
EXPECT_THAT(transformedAabb.GetMax(), IsClose(Vector3(16.3216f, 6.54272f, 5.98112f)));
}
TEST(MATH_AabbTransform, GetTransformedObbFitsInsideTransformedAabb)
{
Vector3 min(4.0f, 3.0f, 1.0f);
Vector3 max(7.0f, 6.0f, 8.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Quaternion rotation(0.40f, 0.40f, 0.64f, 0.52f);
Vector3 translation(-2.0f, 4.0f, -3.0f);
Matrix3x4 matrix3x4 = Matrix3x4::CreateFromQuaternionAndTranslation(rotation, translation);
matrix3x4.MultiplyByScale(Vector3(2.2f, 0.6f, 1.4f));
Aabb transformedAabb = aabb.GetTransformedAabb(matrix3x4);
Obb transformedObb = aabb.GetTransformedObb(matrix3x4);
Aabb aabbContainingTransformedObb = Aabb::CreateFromObb(transformedObb);
EXPECT_THAT(transformedAabb.GetMin(), IsClose(aabbContainingTransformedObb.GetMin()));
EXPECT_THAT(transformedAabb.GetMax(), IsClose(aabbContainingTransformedObb.GetMax()));
}
TEST(MATH_AabbTransform, MultiplyByScale)
{
Vector3 min(2.0f, 6.0f, 8.0f);
Vector3 max(6.0f, 9.0f, 10.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Vector3 scale(0.5f, 2.0f, 1.5f);
aabb.MultiplyByScale(scale);
EXPECT_THAT(aabb.GetMin(), IsClose(Vector3(1.0f, 12.0f, 12.0f)));
EXPECT_THAT(aabb.GetMax(), IsClose(Vector3(3.0f, 18.0f, 15.0f)));
}
}
@@ -29,6 +29,20 @@ namespace AzFramework::AssetSystem::Platform
bool LaunchAssetProcessor(AZStd::string_view executableDirectory, AZStd::string_view engineRoot,
AZStd::string_view projectPath)
{
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
pid_t firstChildPid = fork();
if (firstChildPid == 0)
{
@@ -47,9 +61,6 @@ namespace AzFramework::AssetSystem::Platform
pid_t secondChildPid = fork();
if (secondChildPid == 0)
{
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor";
AZStd::array args {
assetProcessorPath.c_str(), assetProcessorPath.c_str(), "--start-hidden",
static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), static_cast<const char*>(nullptr)
@@ -11,6 +11,7 @@
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <sys/types.h>
@@ -20,6 +21,7 @@ namespace AzFramework::AssetSystem::Platform
{
void AllowAssetProcessorToForeground()
{}
bool LaunchAssetProcessor(AZStd::string_view executableDirectory, AZStd::string_view engineRoot,
AZStd::string_view projectPath)
{
@@ -29,6 +31,17 @@ namespace AzFramework::AssetSystem::Platform
assetProcessorPath /= "../../../AssetProcessor.app";
assetProcessorPath = assetProcessorPath.LexicallyNormal();
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.app";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"(open -g "%s" --args --start-hidden)", assetProcessorPath.c_str());
// Add the engine path to the launch command if not empty
if (!engineRoot.empty())
@@ -12,6 +12,7 @@
#include <AzCore/PlatformIncl.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <Psapi.h>
@@ -67,6 +68,17 @@ namespace AzFramework::AssetSystem::Platform
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor.exe";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.exe";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"("%s" --start-hidden)", assetProcessorPath.c_str());
// Add the engine path to the launch command if not empty
@@ -140,7 +140,7 @@ namespace AzToolsFramework
else
{
QPixmap pixmap = thumbnail->GetPixmap(size);
painter->drawPixmap(point.x(), point.y(), size.width(), size.height(), pixmap);
painter->drawPixmap(point, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
return m_iconSize;
}
@@ -10,12 +10,14 @@
*
*/
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
AZ_PUSH_DISABLE_WARNING(4127 4251 4800 4244, "-Wunknown-warning-option") // 4127: conditional expression is constant
// 4251: 'QTextCodec::ConverterState::flags': class 'QFlags<QTextCodec::ConversionFlag>' needs to have dll-interface to be used by clients of struct 'QTextCodec::ConverterState'
// 4800: 'QTextBoundaryFinderPrivate *const ': forcing value to bool 'true' or 'false' (performance warning)
// 4244: conversion from 'int' to 'qint8', possible loss of data
#include <QtConcurrent/QtConcurrent>
#include <QThreadPool>
AZ_POP_DISABLE_WARNING
namespace AzToolsFramework
@@ -80,7 +82,11 @@ namespace AzToolsFramework
if (m_state == State::Unloaded)
{
m_state = State::Loading;
QFuture<void> future = QtConcurrent::run([this](){ LoadThread(); });
QThreadPool* threadPool;
ThumbnailContextRequestBus::BroadcastResult(
threadPool,
&ThumbnailContextRequestBus::Handler::GetThreadPool);
QFuture<void> future = QtConcurrent::run(threadPool, [this](){ LoadThread(); });
m_watcher.setFuture(future);
}
}
@@ -28,10 +28,15 @@ namespace AzToolsFramework
: m_missingThumbnail(new MissingThumbnail(thumbnailSize))
, m_loadingThumbnail(new LoadingThumbnail(thumbnailSize))
, m_thumbnailSize(thumbnailSize)
, m_threadPool(this)
{
ThumbnailContextRequestBus::Handler::BusConnect();
}
ThumbnailContext::~ThumbnailContext() = default;
ThumbnailContext::~ThumbnailContext()
{
ThumbnailContextRequestBus::Handler::BusDisconnect();
}
bool ThumbnailContext::IsLoading(SharedThumbnailKey key)
{
@@ -53,6 +58,11 @@ namespace AzToolsFramework
AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AzToolsFramework::AssetBrowser::AssetBrowserViewRequests::Update);
}
QThreadPool* ThumbnailContext::GetThreadPool()
{
return &m_threadPool;
}
SharedThumbnail ThumbnailContext::GetThumbnail(SharedThumbnailKey key)
{
SharedThumbnail thumbnail;
@@ -19,6 +19,7 @@
#include <QObject>
#include <QList>
#include <QThreadPool>
#endif
class QString;
@@ -40,6 +41,7 @@ namespace AzToolsFramework
*/
class ThumbnailContext
: public QObject
, public ThumbnailContextRequestBus::Handler
{
Q_OBJECT
public:
@@ -58,10 +60,13 @@ namespace AzToolsFramework
void UnregisterThumbnailProvider(const char* providerName);
void RedrawThumbnail();
//! Default context used for most thumbnails
static constexpr const char* DefaultContext = "Default";
// ThumbnailContextRequestBus::Handler interface overrides...
QThreadPool* GetThreadPool() override;
private:
struct ProviderCompare {
bool operator() (const SharedThumbnailProvider& lhs, const SharedThumbnailProvider& rhs) const
@@ -79,6 +84,9 @@ namespace AzToolsFramework
SharedThumbnail m_loadingThumbnail;
//! Thumbnail size (width and height in pixels)
int m_thumbnailSize;
//! There is only a limited number of threads on global threadPool, because there can be many thumbnails rendering at once
//! an individual threadPool is needed to avoid deadlocks
QThreadPool m_threadPool;
};
} // namespace Thumbnailer
} // namespace AzToolsFramework
@@ -81,6 +81,9 @@ namespace AzToolsFramework
int x = (originalWidth - realWidth) / 2;
// pixmap needs to be manually scaled to produce smoother result and avoid looking pixelated
// using painter.setRenderHint(QPainter::SmoothPixmapTransform); does not seem to work
// Note: there is a potential issue with pixmap.scaled:
// it is multithreaded (using global threadPool) and blocking until finished.
// A deadlock will happen if global threadPool has no free threads available.
painter.drawPixmap(QPoint(x, 0), pixmap.scaled(realWidth, realHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
QWidget::paintEvent(event);
@@ -17,11 +17,23 @@
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
class QPixmap;
class QThreadPool;
namespace AzToolsFramework
{
namespace Thumbnailer
{
//! Interaction with thumbnail context
class ThumbnailContextRequests
: public AZ::EBusTraits
{
public:
//! Get thread pool for drawing thumbnails
virtual QThreadPool* GetThreadPool() = 0;
};
using ThumbnailContextRequestBus = AZ::EBus<ThumbnailContextRequests>;
//! Interaction with thumbnailer
class ThumbnailerRequests
: public AZ::EBusTraits
@@ -192,6 +192,10 @@ namespace LegacyFramework
// if we're in console mode, listen for CTRL+C
::SetConsoleCtrlHandler(CTRL_BREAK_HandlerRoutine, true);
#endif
m_ptrCommandLineParser = aznew AzFramework::CommandLine();
m_ptrCommandLineParser->Parse(m_desc.m_argc, m_desc.m_argv);
// If we don't have one create a serialize context
if (GetSerializeContext() == nullptr)
{
-1
View File
@@ -216,7 +216,6 @@ protected:
void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId, const AzFramework::SliceInstantiationTicket& /*ticket*/) override;
//////////////////////////////////////////////////////////////////////////
QString m_strMasterCDFolder;
bool m_bLoadFailed;
QColor m_waterColor;
XmlNodeRef m_fogTemplate;
+17 -17
View File
@@ -65,7 +65,7 @@ namespace
const float kTangentDelta = 0.01f;
const float kAspectRatio = 1.777778f;
const int kReserveCount = 7; // x,y,z,rot_x,rot_y,rot_z,fov
const QString kMasterCameraName = "MasterCamera";
const QString kPrimaryCameraName = "PrimaryCamera";
} // namespace
@@ -169,10 +169,10 @@ CExportManager::CExportManager()
, m_numberOfExportFrames(0)
, m_pivotEntityObject(0)
, m_bBakedKeysSequenceExport(true)
, m_animTimeExportMasterSequenceCurrentTime(0.0f)
, m_animTimeExportPrimarySequenceCurrentTime(0.0f)
, m_animKeyTimeExport(true)
, m_soundKeyTimeExport(true)
, m_bExportOnlyMasterCamera(false)
, m_bExportOnlyPrimaryCamera(false)
{
RegisterExporter(new COBJExporter());
RegisterExporter(new COCMExporter());
@@ -773,14 +773,14 @@ bool CExportManager::ShowFBXExportDialog()
return false;
}
SetFBXExportSettings(fpsDialog.GetExportCoordsLocalToTheSelectedObject(), fpsDialog.GetExportOnlyMasterCamera(), fpsDialog.GetFPS());
SetFBXExportSettings(fpsDialog.GetExportCoordsLocalToTheSelectedObject(), fpsDialog.GetExportOnlyPrimaryCamera(), fpsDialog.GetFPS());
return true;
}
bool CExportManager::ProcessObjectsForExport()
{
Export::CObject* pObj = new Export::CObject(kMasterCameraName.toUtf8().data());
Export::CObject* pObj = new Export::CObject(kPrimaryCameraName.toUtf8().data());
pObj->entityType = Export::eCamera;
m_data.m_objects.push_back(pObj);
@@ -808,13 +808,13 @@ bool CExportManager::ProcessObjectsForExport()
Export::CObject* pObj2 = m_data.m_objects[objectID];
CBaseObject* pObject = 0;
if (QString::compare(pObj2->name, kMasterCameraName) == 0)
if (QString::compare(pObj2->name, kPrimaryCameraName) == 0)
{
pObject = GetIEditor()->GetObjectManager()->FindObject(GetIEditor()->GetViewManager()->GetCameraObjectId());
}
else
{
if (m_bExportOnlyMasterCamera && pObj2->entityType != Export::eCameraTarget)
if (m_bExportOnlyPrimaryCamera && pObj2->entityType != Export::eCameraTarget)
{
continue;
}
@@ -952,7 +952,7 @@ void CExportManager::FillAnimTimeNode(XmlNodeRef writeNode, CTrackViewAnimNode*
if (numAllTracks > 0)
{
XmlNodeRef objNode = writeNode->createNode(CleanXMLText(pObjectNode->GetName()).toUtf8().data());
writeNode->setAttr("time", m_animTimeExportMasterSequenceCurrentTime);
writeNode->setAttr("time", m_animTimeExportPrimarySequenceCurrentTime);
for (unsigned int trackID = 0; trackID < numAllTracks; ++trackID)
{
@@ -1020,7 +1020,7 @@ void CExportManager::FillAnimTimeNode(XmlNodeRef writeNode, CTrackViewAnimNode*
XmlNodeRef keyNode = subNode->createNode(keyContentName.toUtf8().data());
float keyGlobalTime = m_animTimeExportMasterSequenceCurrentTime + keyTime;
float keyGlobalTime = m_animTimeExportPrimarySequenceCurrentTime + keyTime;
keyNode->setAttr("keyTime", keyGlobalTime);
if (keyStartTime > 0)
@@ -1123,13 +1123,13 @@ bool CExportManager::AddObjectsFromSequence(CTrackViewSequence* pSequence, XmlNo
const QString sequenceName = pSubSequence->GetName();
XmlNodeRef subSeqNode2 = seqNode->createNode(sequenceName.toUtf8().data());
if (sequenceName == m_animTimeExportMasterSequenceName)
if (sequenceName == m_animTimeExportPrimarySequenceName)
{
m_animTimeExportMasterSequenceCurrentTime = sequenceKey.time;
m_animTimeExportPrimarySequenceCurrentTime = sequenceKey.time;
}
else
{
m_animTimeExportMasterSequenceCurrentTime += sequenceKey.time;
m_animTimeExportPrimarySequenceCurrentTime += sequenceKey.time;
}
AddObjectsFromSequence(pSubSequence, subSeqNode2);
@@ -1336,7 +1336,7 @@ bool CExportManager::Export(const char* defaultName, const char* defaultExt, con
{
m_numberOfExportFrames = pSequence->GetTimeRange().end * m_FBXBakedExportFPS;
if (!m_bExportOnlyMasterCamera)
if (!m_bExportOnlyPrimaryCamera)
{
AddObjectsFromSequence(pSequence);
}
@@ -1365,10 +1365,10 @@ bool CExportManager::Export(const char* defaultName, const char* defaultExt, con
return returnRes;
}
void CExportManager::SetFBXExportSettings(bool bLocalCoordsToSelectedObject, bool bExportOnlyMasterCamera, const float fps)
void CExportManager::SetFBXExportSettings(bool bLocalCoordsToSelectedObject, bool bExportOnlyPrimaryCamera, const float fps)
{
m_bExportLocalCoords = bLocalCoordsToSelectedObject;
m_bExportOnlyMasterCamera = bExportOnlyMasterCamera;
m_bExportOnlyPrimaryCamera = bExportOnlyPrimaryCamera;
m_FBXBakedExportFPS = fps;
}
@@ -1439,10 +1439,10 @@ void CExportManager::SaveNodeKeysTimeToXML()
if (dlg.exec())
{
m_animTimeNode = XmlHelpers::CreateXmlNode(pSequence->GetName());
m_animTimeExportMasterSequenceName = pSequence->GetName();
m_animTimeExportPrimarySequenceName = pSequence->GetName();
m_data.Clear();
m_animTimeExportMasterSequenceCurrentTime = 0.0;
m_animTimeExportPrimarySequenceCurrentTime = 0.0;
AddObjectsFromSequence(pSequence, m_animTimeNode);
+4 -4
View File
@@ -171,7 +171,7 @@ private:
bool AddObjectsFromSequence(CTrackViewSequence* pSequence, XmlNodeRef seqNode = 0);
bool IsDuplicateObjectBeingAdded(const QString& newObject);
void SetFBXExportSettings(bool bLocalCoordsToSelectedObject, bool bExportOnlyMasterCamera, const float fps);
void SetFBXExportSettings(bool bLocalCoordsToSelectedObject, bool bExportOnlyPrimaryCamera, const float fps);
bool ProcessObjectsForExport();
bool ShowFBXExportDialog();
@@ -193,13 +193,13 @@ private:
float m_FBXBakedExportFPS;
bool m_bExportLocalCoords;
bool m_bExportOnlyMasterCamera;
bool m_bExportOnlyPrimaryCamera;
int m_numberOfExportFrames;
CEntityObject* m_pivotEntityObject;
bool m_bBakedKeysSequenceExport;
QString m_animTimeExportMasterSequenceName;
float m_animTimeExportMasterSequenceCurrentTime;
QString m_animTimeExportPrimarySequenceName;
float m_animTimeExportPrimarySequenceCurrentTime;
XmlNodeRef m_animTimeNode;
bool m_animKeyTimeExport;
+3 -3
View File
@@ -55,9 +55,9 @@ bool CFBXExporterDialog::GetExportCoordsLocalToTheSelectedObject() const
return m_ui->m_exportLocalCoordsCheckbox->isChecked();
}
bool CFBXExporterDialog::GetExportOnlyMasterCamera() const
bool CFBXExporterDialog::GetExportOnlyPrimaryCamera() const
{
return m_ui->m_exportOnlyMasterCameraCheckBox->isChecked();
return m_ui->m_exportOnlyPrimaryCameraCheckBox->isChecked();
}
void CFBXExporterDialog::SetExportLocalCoordsCheckBoxEnable(bool checked)
@@ -100,7 +100,7 @@ int CFBXExporterDialog::exec()
if (m_bDisplayOnlyFPSSetting)
{
m_ui->m_exportLocalCoordsCheckbox->setEnabled(false);
m_ui->m_exportOnlyMasterCameraCheckBox->setEnabled(false);
m_ui->m_exportOnlyPrimaryCameraCheckBox->setEnabled(false);
}
m_ui->m_fpsCombo->addItem("24");
+2 -2
View File
@@ -36,7 +36,7 @@ public:
float GetFPS() const;
bool GetExportCoordsLocalToTheSelectedObject() const;
bool GetExportOnlyMasterCamera() const;
bool GetExportOnlyPrimaryCamera() const;
void SetExportLocalCoordsCheckBoxEnable(bool checked);
int exec() override;
@@ -44,7 +44,7 @@ public:
protected:
void OnFPSChange();
void SetExportLocalToTheSelectedObjectCheckBox();
void SetExportOnlyMasterCameraCheckBox();
void SetExportOnlyPrimaryCameraCheckBox();
void accept() override;
+2 -2
View File
@@ -49,9 +49,9 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="m_exportOnlyMasterCameraCheckBox">
<widget class="QCheckBox" name="m_exportOnlyPrimaryCameraCheckBox">
<property name="text">
<string>Export Only Master Camera</string>
<string>Export Only Primary Camera</string>
</property>
</widget>
</item>
+1 -1
View File
@@ -20,7 +20,7 @@ class CEditorMock
: public IEditor
{
public:
// GMock does not work with a variadic function (https://github.com/google/googlemock/blob/master/googlemock/docs/FrequentlyAskedQuestions.md)
// GMock does not work with a variadic function
void ExecuteCommand(const char* sCommand, ...) override
{
va_list args;
@@ -73,7 +73,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<FbxImporter, SceneCore::LoadingComponent>()->Version(2); // SPEC-5776
}
}
@@ -51,7 +51,7 @@ namespace AZ
AZStd::unique_ptr<SDKScene::SceneWrapperBase> m_sceneWrapper;
AZStd::shared_ptr<FbxSceneSystem> m_sceneSystem;
bool m_useAssetImporterSDK = false;
bool m_useAssetImporterSDK = true;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
@@ -51,6 +51,7 @@ namespace AZ
AZ_Warning("AnimationImporter", false, "Animation ticks per second should not be zero, defaulting to %d keyframes for animation.", keysSize);
return keysSize;
}
const double totalTicks = duration / ticksPerSecond;
AZ::u32 numKeys = keysSize;
// +1 because the animation is from [0, duration] - we have a keyframe at the end of the duration which needs to be included
@@ -422,10 +423,12 @@ namespace AZ
// If there is no bone animation on the current node, then generate one here.
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
AZStd::make_shared<SceneData::GraphData::AnimationData>();
createdAnimationData->ReserveKeyFrames(
animation->mDuration +
1); // +1 because we start at 0 and the last keyframe is at mDuration instead of mDuration-1
createdAnimationData->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
const size_t numKeyframes = animation->mDuration + 1; // +1 because we start at 0 and the last keyframe is at mDuration instead of mDuration-1
createdAnimationData->ReserveKeyFrames(numKeyframes);
const double timeStepBetweenFrames = 1.0 / animation->mTicksPerSecond;
createdAnimationData->SetTimeStepBetweenFrames(timeStepBetweenFrames);
// Set every frame of the animation to the start location of the node.
aiMatrix4x4 combinedTransform = GetConcatenatedLocalTransform(currentNode);
@@ -527,7 +530,7 @@ namespace AZ
// are less predictable than just using a fixed time step.
// AssImp documentation claims animation->mDuration is the duration of the animation in ticks, but
// not all animations we've tested follow that pattern. Sometimes duration is in seconds.
const AZ::u32 numKeyFrames = GetNumKeyFrames(
const size_t numKeyFrames = GetNumKeyFrames(
AZStd::max(AZStd::max(anim->mNumScalingKeys, anim->mNumPositionKeys), anim->mNumRotationKeys),
animation->mDuration,
animation->mTicksPerSecond);
@@ -543,8 +546,10 @@ namespace AZ
for (AZ::u32 frame = 0; frame < numKeyFrames; ++frame)
{
const double time = GetTimeForFrame(frame, animation->mTicksPerSecond);
aiVector3D scale = aiVector3D(1.f, 1.f, 1.f), position = aiVector3D(0.f, 0.f, 0.f);
aiQuaternion rotation(1.f, 0.f, 0.f, 0.f);
aiVector3D scale(1.0f, 1.0f, 1.0f);
aiVector3D position(0.0f, 0.0f, 0.0f);
aiQuaternion rotation(1.0f, 0.0f, 0.0f, 0.0f);
if (!SampleKeyFrame(scale, anim->mScalingKeys, anim->mNumScalingKeys, time, lastScaleIndex) ||
!SampleKeyFrame(position, anim->mPositionKeys, anim->mNumPositionKeys, time, lastPositionIndex) ||
!SampleKeyFrame(rotation, anim->mRotationKeys, anim->mNumRotationKeys, time, lastRotationIndex))
@@ -553,7 +558,6 @@ namespace AZ
}
aiMatrix4x4 transform(scale, rotation, position);
DataTypes::MatrixType animTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(transform);
context.m_sourceSceneSystem.SwapTransformForUpAxis(animTransform);
@@ -618,7 +622,7 @@ namespace AZ
AZStd::shared_ptr<SceneData::GraphData::BlendShapeAnimationData> morphAnimNode =
AZStd::make_shared<SceneData::GraphData::BlendShapeAnimationData>();
const AZ::u32 numKeyFrames = GetNumKeyFrames(keys.size(), animation->mDuration, animation->mTicksPerSecond);
const size_t numKeyFrames = GetNumKeyFrames(keys.size(), animation->mDuration, animation->mTicksPerSecond);
morphAnimNode->ReserveKeyFrames(numKeyFrames);
morphAnimNode->SetTimeStepBetweenFrames(s_defaultTimeStepBetweenFrames);
@@ -627,7 +631,7 @@ namespace AZ
const AZ::u32 maxKeys = keys.size();
AZ::u32 keyIdx = 0;
for (AZ::u32 frame = 0; frame <= numKeyFrames; ++frame)
for (AZ::u32 frame = 0; frame < numKeyFrames; ++frame)
{
const double time = GetTimeForFrame(frame, animation->mTicksPerSecond);
@@ -640,7 +644,6 @@ namespace AZ
morphAnimNode->AddKeyFrame(weight);
}
const size_t dotIndex = nodeName.find_last_of('.');
nodeName = nodeName.substr(dotIndex + 1);
@@ -32,7 +32,7 @@ namespace AZ
{
namespace FbxSceneBuilder
{
const char* AssImpUvMapImporter::m_defaultNodeName = "UVMap";
const char* AssImpUvMapImporter::m_defaultNodeName = "UV";
AssImpUvMapImporter::AssImpUvMapImporter()
{
@@ -44,7 +44,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2506
}
}
@@ -84,7 +84,13 @@ namespace AZ
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> uvMap =
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexUVData>();
uvMap->ReserveContainerSpace(vertexCount);
AZStd::string name(AZStd::string::format("%s%d", m_defaultNodeName, texCoordIndex));
if (mesh->mTextureCoordsNames[texCoordIndex].length)
{
name = mesh->mTextureCoordsNames[texCoordIndex].C_Str();
}
uvMap->SetCustomName(name.c_str());
for (int v = 0; v < mesh->mNumVertices; ++v)
@@ -86,7 +86,7 @@ namespace AZ
if (sourceFileExists && !updateMaterial)
{
// Don't write to the cache if there's a source material as this will be the master material.
// Don't write to the cache if there's a source material as this will be the primary material.
continue;
}
@@ -84,7 +84,7 @@ namespace AZ
NoneCheckable, // No nodes can be checked.
OnlyFilterTypesCheckable // Only nodes in the filter type list can be checked.
};
// Updates the tree to include/exclude check boxes and the master selection. Call "BuildTree()" to rebuild the tree.
// Updates the tree to include/exclude check boxes and the primary selection. Call "BuildTree()" to rebuild the tree.
virtual void MakeCheckable(CheckableOption option);
// Add a type to filter for. Filter types are used to determine if a check box is added and/or to be shown if
// the type is an end point. See "IncludeEndPoints" and "MakeCheckable" for more details.
@@ -308,7 +308,7 @@ namespace AssetMemoryAnalyzer
AZStd::function<void(AssetInfo*, AssetTreeNode*, int)> recurse;
recurse = [&recurse](AssetInfo* outAsset, AssetTreeNode* inAsset, int depth)
{
outAsset->m_id = inAsset->m_masterInfo ? inAsset->m_masterInfo->m_id->m_id.c_str() : nullptr;
outAsset->m_id = inAsset->m_primaryinfo ? inAsset->m_primaryinfo->m_id->m_id.c_str() : nullptr;
// For every code point in this asset node, record its allocations
for (auto& codePointInfo : inAsset->m_data.m_codePointsToAllocations)
@@ -102,7 +102,7 @@ namespace AZ
// Register Shader Resource Group Layout Builder
AssetBuilderSDK::AssetBuilderDesc srgLayoutBuilderDescriptor;
srgLayoutBuilderDescriptor.m_name = "Shader Resource Group Layout Builder";
srgLayoutBuilderDescriptor.m_version = 53; // ATOM-15196
srgLayoutBuilderDescriptor.m_version = 54; // Enable Null Rhi for AutomatedTesting
srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsl", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsli", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
@@ -118,7 +118,7 @@ namespace AZ
// Register Shader Asset Builder
AssetBuilderSDK::AssetBuilderDesc shaderAssetBuilderDescriptor;
shaderAssetBuilderDescriptor.m_name = "Shader Asset Builder";
shaderAssetBuilderDescriptor.m_version = 97; // ATOM-15196
shaderAssetBuilderDescriptor.m_version = 98; // Enable Null Rhi for AutomatedTesting
// .shader file changes trigger rebuilds
shaderAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern( AZStd::string::format("*.%s", RPI::ShaderSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderAssetBuilder>();
@@ -133,7 +133,7 @@ namespace AZ
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
shaderVariantAssetBuilderDescriptor.m_version = 18; // ATOM-15196
shaderVariantAssetBuilderDescriptor.m_version = 19; // Enable Null Rhi for AutomatedTesting
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
@@ -405,12 +405,20 @@ namespace AZ
void ShaderVariantAssetBuilder::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const
{
const auto& jobParameters = request.m_jobDescription.m_jobParameters;
if (jobParameters.find(ShaderVariantLoadErrorParam) != jobParameters.end())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Error during CreateJobs: %s", jobParameters.at(ShaderVariantLoadErrorParam).c_str());
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
if (jobParameters.find(ShouldExitEarlyFromProcessJobParam) != jobParameters.end())
{
AZ_TracePrintf(ShaderVariantAssetBuilderName, "Doing nothing on behalf of [%s] because it's been overridden by game project.", jobParameters.at(ShaderVariantLoadErrorParam).c_str());
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
return;
}
if (jobParameters.find(ShouldExitEarlyFromProcessJobParam) != jobParameters.end())
{
@@ -401,38 +401,6 @@
"step": 0.1
}
],
"ambientOcclusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionFactor"
}
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMap"
}
}
],
"emissive": [
{
"id": "enable",
@@ -49,9 +49,9 @@
"description": "Properties for configuring UV transforms."
},
{
"id": "ambientOcclusion",
"displayName": "Ambient Occlusion",
"description": "Properties for baked AO texture."
"id": "occlusion",
"displayName": "Occlusion",
"description": "Properties for baked textures that represent geometric occlusion of light."
},
{
"id": "emissive",
@@ -780,47 +780,89 @@
"step": 0.1
}
],
"ambientOcclusion": [
"occlusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionFactor"
}
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"id": "diffuseTextureMap",
"displayName": "Diffuse AO",
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMap"
"id": "m_diffuseOcclusionMap"
}
},
{
"id": "textureMapUv",
"displayName": "UV",
"description": "Ambient occlusion texture map UV set",
"id": "diffuseUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Diffuse AO texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "diffuseTextureMapUv",
"displayName": " UV",
"description": "Diffuse AO texture map UV set.",
"type": "Enum",
"enumValues": [ "UV0", "UV1" ],
"defaultValue": "UV0",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMapUvIndex"
"id": "m_diffuseOcclusionMapUvIndex"
}
},
{
"id": "diffuseFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Diffuse AO",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_diffuseOcclusionFactor"
}
},
{
"id": "specularTextureMap",
"displayName": "Specular Cavity",
"description": "Texture map for defining occlusion area for specular lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionMap"
}
},
{
"id": "specularUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Specular Cavity texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "specularTextureMapUv",
"displayName": " UV",
"description": "Specular Cavity texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionMapUvIndex"
}
},
{
"id": "specularFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Specular Cavity",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionFactor"
}
}
],
@@ -1641,17 +1683,21 @@
}
},
{
// See the comment above for details.
"type": "UseTexture",
"args": {
"textureProperty": "ambientOcclusion.textureMap",
"dependentProperties": ["ambientOcclusion.textureMapUv"],
"useTextureProperty": "ambientOcclusion.enable",
"shaderTags": [
"ForwardPass",
"ForwardPass_EDS"
],
"shaderOption": "o_ambientOcclusion_useTexture"
"textureProperty": "occlusion.diffuseTextureMap",
"useTextureProperty": "occlusion.diffuseUseTexture",
"dependentProperties": ["occlusion.diffuseTextureMapUv", "occlusion.diffuseFactor"],
"shaderOption": "o_diffuseOcclusion_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "occlusion.specularTextureMap",
"useTextureProperty": "occlusion.specularUseTexture",
"dependentProperties": ["occlusion.specularTextureMapUv", "occlusion.specularFactor"],
"shaderOption": "o_specularOcclusion_useTexture"
}
},
{
@@ -1712,31 +1758,6 @@
"shaderOption": "o_transmission_useTexture"
}
},
{
// Controls visibility for properties in the editor.
// @param actions - a list of actions that are executed in order. visibility will be set when triggerProperty hits the triggerValue.
// @param affectedProperties - the properties that are affected by actions.
"type": "UpdatePropertyVisibility",
"args": {
"actions": [
{
"triggerProperty": "ambientOcclusion.enable",
"triggerValue": true,
"visibility": "Enabled"
},
{
"triggerProperty": "ambientOcclusion.enable",
"triggerValue": false,
"visibility": "Disabled"
}
],
"affectedProperties": [
"ambientOcclusion.factor",
"ambientOcclusion.textureMap",
"ambientOcclusion.textureMapUv"
]
}
},
{
// Controls visibility for properties in the editor.
// @param actions - a list of actions that are executed in order. visibility will be set when triggerProperty hits the triggerValue.
@@ -213,9 +213,9 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
float3 emissive = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture);
// ------- Occlusion -------
float2 occlusionUv = IN.m_uv[MaterialSrg::m_ambientOcclusionMapUvIndex];
float occlusion = GetOcclusionInput(MaterialSrg::m_ambientOcclusionMap, MaterialSrg::m_sampler, occlusionUv, MaterialSrg::m_ambientOcclusionFactor, o_ambientOcclusion_useTexture);
float diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
float specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Subsurface -------
@@ -252,7 +252,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
PbrLightingOutput lightingOutput = PbrLighting(IN,
baseColor, metallic, roughness, specularF0Factor,
normal, IN.m_tangent, IN.m_bitangent, anisotropy,
emissive, occlusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
emissive, diffuseAmbientOcclusion, specularOcclusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
// ------- Opacity -------
@@ -12,19 +12,23 @@
#pragma once
// This file provides utilities for common handling of inputs for ambient occlusion maps for PBR materials.
// This file provides utilities for common handling of inputs for baked occlusion maps for PBR materials.
// These macros can be used to declare common shader inputs for this feature.
// Use the COMMON_SRG_INPUTS_* macro in your material SRG definition, and use the COMMON_OPTIONS_* macro at the global scope in your shader. Then you can pass these variables to the Get*Input() function below.
// You can optionally provide a prefix for the set of inputs which corresponds to a prefix string supplied by the .materialtype file. This is common for multi-layered material types.
#define COMMON_SRG_INPUTS_OCCLUSION(prefix) \
float prefix##m_ambientOcclusionFactor; \
Texture2D prefix##m_ambientOcclusionMap; \
uint prefix##m_ambientOcclusionMapUvIndex;
float prefix##m_diffuseOcclusionFactor; \
Texture2D prefix##m_diffuseOcclusionMap; \
uint prefix##m_diffuseOcclusionMapUvIndex; \
float prefix##m_specularOcclusionFactor; \
Texture2D prefix##m_specularOcclusionMap; \
uint prefix##m_specularOcclusionMapUvIndex;
#define COMMON_OPTIONS_OCCLUSION(prefix) \
option bool prefix##o_ambientOcclusion_useTexture;
option bool prefix##o_diffuseOcclusion_useTexture; \
option bool prefix##o_specularOcclusion_useTexture;
float GetOcclusionInput(Texture2D map, sampler mapSampler, float2 uv, float factor, bool useTexture)
{
@@ -272,6 +272,11 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
float roughness = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor,
MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture);
// ------- Occlusion -------
float diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
float specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Specular -------
float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex];
@@ -300,7 +305,6 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
float metallic = 0;
float3 emissive = float3(0,0,0);
float occlusion = 1;
float2 anisotropy = float2(0,0);
float clearCoatFactor = 0.0;
float clearCoatRoughness = 0.0;
@@ -309,7 +313,7 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
PbrLightingOutput lightingOutput = PbrLighting(IN, baseColor, metallic, roughness, specularF0Factor,
normalWS, tangents[0], bitangents[0], anisotropy,
emissive, occlusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
emissive, diffuseAmbientOcclusion, specularOcclusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
// ------- Preparing output -------
@@ -24,9 +24,9 @@
"description": "Properties related to configuring surface normal."
},
{
"id": "ambientOcclusion",
"displayName": "Ambient Occlusion",
"description": "Properties for baked AO texture."
"id": "occlusion",
"displayName": "Occlusion",
"description": "Properties for baked textures that represent geometric occlusion of light."
},
{
"id": "subsurfaceScattering",
@@ -383,48 +383,89 @@
}
}
],
"ambientOcclusion": [
"occlusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"id": "diffuseTextureMap",
"displayName": "Diffuse AO",
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMap"
"id": "m_diffuseOcclusionMap"
}
},
{
"id": "textureMapUv",
"displayName": "UV",
"description": "Ambient occlusion texture map UV set",
"id": "diffuseUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Diffuse AO texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "diffuseTextureMapUv",
"displayName": " UV",
"description": "Diffuse AO texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Unwrapped",
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMapUvIndex"
"id": "m_diffuseOcclusionMapUvIndex"
}
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"id": "diffuseFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Diffuse AO",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionFactor"
"id": "m_diffuseOcclusionFactor"
}
},
{
"id": "specularTextureMap",
"displayName": "Specular Cavity",
"description": "Texture map for defining occlusion area for specular lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionMap"
}
},
{
"id": "specularUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Specular Cavity texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "specularTextureMapUv",
"displayName": " UV",
"description": "Specular Cavity texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionMapUvIndex"
}
},
{
"id": "specularFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Specular Cavity",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionFactor"
}
}
],
@@ -1021,9 +1062,21 @@
}
},
{
"type": "Lua",
"type": "UseTexture",
"args": {
"file": "StandardPBR_AoState.lua"
"textureProperty": "occlusion.diffuseTextureMap",
"useTextureProperty": "occlusion.diffuseUseTexture",
"dependentProperties": ["occlusion.diffuseTextureMapUv", "occlusion.diffuseFactor"],
"shaderOption": "o_diffuseOcclusion_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "occlusion.specularTextureMap",
"useTextureProperty": "occlusion.specularUseTexture",
"dependentProperties": ["occlusion.specularTextureMapUv", "occlusion.specularFactor"],
"shaderOption": "o_specularOcclusion_useTexture"
}
},
{
@@ -73,9 +73,9 @@
"description": "Properties for configuring gloss clear coat"
},
{
"id": "layer1_ambientOcclusion",
"displayName": "Layer 1: Ambient Occlusion",
"description": "Properties for baked AO texture."
"id": "layer1_occlusion",
"displayName": "Layer 1: Occlusion",
"description": "Properties for baked textures for diffuse and specular occlusion of ambient lighting."
},
{
"id": "layer1_emissive",
@@ -126,9 +126,9 @@
"description": "Properties for configuring gloss clear coat"
},
{
"id": "layer2_ambientOcclusion",
"displayName": "Layer 2: Ambient Occlusion",
"description": "Properties for baked AO texture."
"id": "layer2_occlusion",
"displayName": "Layer 2: Occlusion",
"description": "Properties for baked textures for diffuse and specular occlusion of ambient lighting."
},
{
"id": "layer2_emissive",
@@ -179,9 +179,9 @@
"description": "Properties for configuring gloss clear coat"
},
{
"id": "layer3_ambientOcclusion",
"displayName": "Layer 3: Ambient Occlusion",
"description": "Properties for baked AO texture."
"id": "layer3_occlusion",
"displayName": "Layer 3: Occlusion",
"description": "Properties for baked textures for diffuse and specular occlusion of ambient lighting."
},
{
"id": "layer3_emissive",
@@ -1169,47 +1169,89 @@
}
}
],
"layer1_ambientOcclusion": [
"layer1_occlusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"id": "diffuseTextureMap",
"displayName": "Diffuse AO",
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_layer1_m_ambientOcclusionMap"
"id": "m_layer1_m_diffuseOcclusionMap"
}
},
{
"id": "textureMapUv",
"displayName": "UV",
"description": "Ambient occlusion texture map UV set",
"id": "diffuseUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Diffuse AO texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "diffuseTextureMapUv",
"displayName": " UV",
"description": "Diffuse AO texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_layer1_m_ambientOcclusionMapUvIndex"
"id": "m_layer1_m_diffuseOcclusionMapUvIndex"
}
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"id": "diffuseFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Diffuse AO",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_layer1_m_ambientOcclusionFactor"
"id": "m_layer1_m_diffuseOcclusionFactor"
}
},
{
"id": "specularTextureMap",
"displayName": "Specular Cavity",
"description": "Texture map for defining occlusion area for specular lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_layer1_m_specularOcclusionMap"
}
},
{
"id": "specularUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Specular Cavity texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "specularTextureMapUv",
"displayName": " UV",
"description": "Specular Cavity texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_layer1_m_specularOcclusionMapUvIndex"
}
},
{
"id": "specularFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Specular Cavity",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_layer1_m_specularOcclusionFactor"
}
}
],
@@ -1820,47 +1862,89 @@
}
}
],
"layer2_ambientOcclusion": [
"layer2_occlusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"id": "diffuseTextureMap",
"displayName": "Diffuse AO",
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_layer2_m_ambientOcclusionMap"
"id": "m_layer2_m_diffuseOcclusionMap"
}
},
{
"id": "textureMapUv",
"displayName": "UV",
"description": "Ambient occlusion texture map UV set",
"id": "diffuseUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Diffuse AO texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "diffuseTextureMapUv",
"displayName": " UV",
"description": "Diffuse AO texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_layer2_m_ambientOcclusionMapUvIndex"
"id": "m_layer2_m_diffuseOcclusionMapUvIndex"
}
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"id": "diffuseFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Diffuse AO",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_layer2_m_ambientOcclusionFactor"
"id": "m_layer2_m_diffuseOcclusionFactor"
}
},
{
"id": "specularTextureMap",
"displayName": "Specular Cavity",
"description": "Texture map for defining occlusion area for specular lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_layer2_m_specularOcclusionMap"
}
},
{
"id": "specularUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Specular Cavity texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "specularTextureMapUv",
"displayName": " UV",
"description": "Specular Cavity texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_layer2_m_specularOcclusionMapUvIndex"
}
},
{
"id": "specularFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Specular Cavity",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_layer2_m_specularOcclusionFactor"
}
}
],
@@ -2471,47 +2555,89 @@
}
}
],
"layer3_ambientOcclusion": [
"layer3_occlusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"id": "diffuseTextureMap",
"displayName": "Diffuse AO",
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_layer3_m_ambientOcclusionMap"
"id": "m_layer3_m_diffuseOcclusionMap"
}
},
{
"id": "textureMapUv",
"displayName": "UV",
"description": "Ambient occlusion texture map UV set",
"id": "diffuseUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Diffuse AO texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "diffuseTextureMapUv",
"displayName": " UV",
"description": "Diffuse AO texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_layer3_m_ambientOcclusionMapUvIndex"
"id": "m_layer3_m_diffuseOcclusionMapUvIndex"
}
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"id": "diffuseFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Diffuse AO",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_layer3_m_ambientOcclusionFactor"
"id": "m_layer3_m_diffuseOcclusionFactor"
}
},
{
"id": "specularTextureMap",
"displayName": "Specular Cavity",
"description": "Texture map for defining occlusion area for specular lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_layer3_m_specularOcclusionMap"
}
},
{
"id": "specularUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Specular Cavity texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "specularTextureMapUv",
"displayName": " UV",
"description": "Specular Cavity texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_layer3_m_specularOcclusionMapUvIndex"
}
},
{
"id": "specularFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Specular Cavity",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_layer3_m_specularOcclusionFactor"
}
}
],
@@ -2894,12 +3020,21 @@
}
},
{
"type": "Lua",
"type": "UseTexture",
"args": {
"file": "StandardPBR_AoState.lua",
"propertyNamePrefix": "layer1_",
"srgNamePrefix": "m_layer1_",
"optionsNamePrefix": "o_layer1_"
"textureProperty": "layer1_occlusion.diffuseTextureMap",
"useTextureProperty": "layer1_occlusion.diffuseUseTexture",
"dependentProperties": ["layer1_occlusion.diffuseTextureMapUv", "layer1_occlusion.diffuseFactor"],
"shaderOption": "o_layer1_o_diffuseOcclusion_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "layer1_occlusion.specularTextureMap",
"useTextureProperty": "layer1_occlusion.specularUseTexture",
"dependentProperties": ["layer1_occlusion.specularTextureMapUv", "layer1_occlusion.specularFactor"],
"shaderOption": "o_layer1_o_specularOcclusion_useTexture"
}
},
{
@@ -3022,12 +3157,21 @@
}
},
{
"type": "Lua",
"type": "UseTexture",
"args": {
"file": "StandardPBR_AoState.lua",
"propertyNamePrefix": "layer2_",
"srgNamePrefix": "m_layer2_",
"optionsNamePrefix": "o_layer2_"
"textureProperty": "layer2_occlusion.diffuseTextureMap",
"useTextureProperty": "layer2_occlusion.diffuseUseTexture",
"dependentProperties": ["layer2_occlusion.diffuseTextureMapUv", "layer2_occlusion.diffuseFactor"],
"shaderOption": "o_layer2_o_diffuseOcclusion_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "layer2_occlusion.specularTextureMap",
"useTextureProperty": "layer2_occlusion.specularUseTexture",
"dependentProperties": ["layer2_occlusion.specularTextureMapUv", "layer2_occlusion.specularFactor"],
"shaderOption": "o_layer2_o_specularOcclusion_useTexture"
}
},
{
@@ -3150,12 +3294,21 @@
}
},
{
"type": "Lua",
"type": "UseTexture",
"args": {
"file": "StandardPBR_AoState.lua",
"propertyNamePrefix": "layer3_",
"srgNamePrefix": "m_layer3_",
"optionsNamePrefix": "o_layer3_"
"textureProperty": "layer3_occlusion.diffuseTextureMap",
"useTextureProperty": "layer3_occlusion.diffuseUseTexture",
"dependentProperties": ["layer3_occlusion.diffuseTextureMapUv", "layer3_occlusion.diffuseFactor"],
"shaderOption": "o_layer3_o_diffuseOcclusion_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "layer3_occlusion.specularTextureMap",
"useTextureProperty": "layer3_occlusion.specularUseTexture",
"dependentProperties": ["layer3_occlusion.specularTextureMapUv", "layer3_occlusion.specularFactor"],
"shaderOption": "o_layer3_o_specularOcclusion_useTexture"
}
},
{
@@ -268,10 +268,15 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// ------- Occlusion -------
float layer1_occlusion = GetOcclusionInput(MaterialSrg::m_layer1_m_ambientOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_ambientOcclusionMapUvIndex], MaterialSrg::m_layer1_m_ambientOcclusionFactor, o_layer1_o_ambientOcclusion_useTexture);
float layer2_occlusion = GetOcclusionInput(MaterialSrg::m_layer2_m_ambientOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_ambientOcclusionMapUvIndex], MaterialSrg::m_layer2_m_ambientOcclusionFactor, o_layer2_o_ambientOcclusion_useTexture);
float layer3_occlusion = GetOcclusionInput(MaterialSrg::m_layer3_m_ambientOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_ambientOcclusionMapUvIndex], MaterialSrg::m_layer3_m_ambientOcclusionFactor, o_layer3_o_ambientOcclusion_useTexture);
float occlusion = BlendLayers(layer1_occlusion, layer2_occlusion, layer3_occlusion, blendMaskValues);
float layer1_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer1_m_diffuseOcclusionFactor, o_layer1_o_diffuseOcclusion_useTexture);
float layer2_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer2_m_diffuseOcclusionFactor, o_layer2_o_diffuseOcclusion_useTexture);
float layer3_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer3_m_diffuseOcclusionFactor, o_layer3_o_diffuseOcclusion_useTexture);
float diffuseAmbientOcclusion = BlendLayers(layer1_diffuseAmbientOcclusion, layer2_diffuseAmbientOcclusion, layer3_diffuseAmbientOcclusion, blendMaskValues);
float layer1_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer1_m_specularOcclusionFactor, o_layer1_o_specularOcclusion_useTexture);
float layer2_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer2_m_specularOcclusionFactor, o_layer2_o_specularOcclusion_useTexture);
float layer3_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer3_m_specularOcclusionFactor, o_layer3_o_specularOcclusion_useTexture);
float specularOcclusion = BlendLayers(layer1_specularOcclusion, layer2_specularOcclusion, layer3_specularOcclusion, blendMaskValues);
// ------- Subsurface -------
@@ -350,7 +355,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
PbrLightingOutput lightingOutput = PbrLighting(IN,
baseColor, metallic, roughness, specularF0Factor,
normalWS, tangents[0], bitangents[0], anisotropy,
emissive, occlusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
emissive, diffuseAmbientOcclusion, specularOcclusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
// ------- Opacity -------
@@ -44,9 +44,9 @@
"description": "Properties for configuring UV transforms."
},
{
"id": "ambientOcclusion",
"displayName": "Ambient Occlusion",
"description": "Properties for baked AO texture."
"id": "occlusion",
"displayName": "Occlusion",
"description": "Properties for baked textures that represent geometric occlusion of light."
},
{
"id": "emissive",
@@ -724,47 +724,89 @@
"step": 0.1
}
],
"ambientOcclusion": [
"occlusion": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the ambient occlusion feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
"description": "Texture map for defining ambient occlusion area.",
"id": "diffuseTextureMap",
"displayName": "Diffuse AO",
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMap"
"id": "m_diffuseOcclusionMap"
}
},
{
"id": "textureMapUv",
"displayName": "UV",
"description": "Ambient occlusion texture map UV set",
"id": "diffuseUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Diffuse AO texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "diffuseTextureMapUv",
"displayName": " UV",
"description": "Diffuse AO texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionMapUvIndex"
"id": "m_diffuseOcclusionMapUvIndex"
}
},
{
"id": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"id": "diffuseFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Diffuse AO",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 2.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_ambientOcclusionFactor"
"id": "m_diffuseOcclusionFactor"
}
},
{
"id": "specularTextureMap",
"displayName": "Specular Cavity",
"description": "Texture map for defining occlusion area for specular lighting.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionMap"
}
},
{
"id": "specularUseTexture",
"displayName": " Use Texture",
"description": "Whether to use the Specular Cavity texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "specularTextureMapUv",
"displayName": " UV",
"description": "Specular Cavity texture map UV set.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionMapUvIndex"
}
},
{
"id": "specularFactor",
"displayName": " Factor",
"description": "Strength factor for scaling the values of Specular Cavity",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"id": "m_specularOcclusionFactor"
}
}
],
@@ -1270,9 +1312,21 @@
}
},
{
"type": "Lua",
"type": "UseTexture",
"args": {
"file": "StandardPBR_AoState.lua"
"textureProperty": "occlusion.diffuseTextureMap",
"useTextureProperty": "occlusion.diffuseUseTexture",
"dependentProperties": ["occlusion.diffuseTextureMapUv", "occlusion.diffuseFactor"],
"shaderOption": "o_diffuseOcclusion_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "occlusion.specularTextureMap",
"useTextureProperty": "occlusion.specularUseTexture",
"dependentProperties": ["occlusion.specularTextureMapUv", "occlusion.specularFactor"],
"shaderOption": "o_specularOcclusion_useTexture"
}
},
{
@@ -1,48 +0,0 @@
--------------------------------------------------------------------------------------
--
-- 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.
--
--
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"ambientOcclusion.enable", "ambientOcclusion.textureMap"}
end
function GetShaderOptionDependencies()
return {"o_ambientOcclusion_useTexture"}
end
function Process(context)
local enableAo = context:GetMaterialPropertyValue_bool("ambientOcclusion.enable")
local textureMap = context:GetMaterialPropertyValue_image("ambientOcclusion.textureMap")
context:SetShaderOptionValue_bool("o_ambientOcclusion_useTexture", enableAo and textureMap ~= nil)
end
function ProcessEditor(context)
local enableAo = context:GetMaterialPropertyValue_bool("ambientOcclusion.enable")
if(not enableAo) then
context:SetMaterialPropertyVisibility("ambientOcclusion.factor", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("ambientOcclusion.textureMap", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("ambientOcclusion.textureMapUv", MaterialPropertyVisibility_Hidden)
else
context:SetMaterialPropertyVisibility("ambientOcclusion.textureMap", MaterialPropertyVisibility_Enabled)
local textureMap = context:GetMaterialPropertyValue_image("ambientOcclusion.textureMap")
if(textureMap == nil) then
context:SetMaterialPropertyVisibility("ambientOcclusion.factor", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("ambientOcclusion.textureMapUv", MaterialPropertyVisibility_Hidden)
else
context:SetMaterialPropertyVisibility("ambientOcclusion.factor", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("ambientOcclusion.textureMapUv", MaterialPropertyVisibility_Enabled)
end
end
end
@@ -212,9 +212,9 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture);
// ------- Occlusion -------
float2 occlusionUv = IN.m_uv[MaterialSrg::m_ambientOcclusionMapUvIndex];
lightingData.occlusion = GetOcclusionInput(MaterialSrg::m_ambientOcclusionMap, MaterialSrg::m_sampler, occlusionUv, MaterialSrg::m_ambientOcclusionFactor, o_ambientOcclusion_useTexture);
lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Clearcoat -------
@@ -180,6 +180,13 @@
"Attachment": "SpecularF0Output"
}
},
{
"LocalSlot": "AlbedoInput",
"AttachmentRef": {
"Pass": "ForwardMSAAPass",
"Attachment": "AlbedoOutput"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
@@ -27,6 +27,12 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
// This is needed for the alpha channel which has specularOcclusion factor
"Name": "AlbedoInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
@@ -17,6 +17,11 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "AlbedoInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
@@ -127,6 +132,13 @@
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "AlbedoInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "AlbedoInput"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
@@ -12,19 +12,19 @@
struct ForwardPassOutput
{
// m_diffuseColor.a should be encoded with subsurface scattering's strength factor and quality factor if enabled
float4 m_diffuseColor : SV_Target0;
float4 m_specularColor : SV_Target1;
float4 m_albedo : SV_Target2;
float4 m_specularF0 : SV_Target3;
float4 m_normal : SV_Target4;
float4 m_clearCoatNormal : SV_Target5;
float4 m_diffuseColor : SV_Target0; //!< RGB = Diffuse Lighting, A = Blend Alpha (for blended surfaces) OR A = special encoding of surfaceScatteringFactor, m_subsurfaceScatteringQuality, o_enableSubsurfaceScattering
float4 m_specularColor : SV_Target1; //!< RGB = Specular Lighting, A = Unused
float4 m_albedo : SV_Target2; //!< RGB = Surface albedo pre-multiplied by other factors that will be multiplied later by diffuse GI, A = specularOcclusion
float4 m_specularF0 : SV_Target3; //!< RGB = Specular F0, A = roughness
float4 m_normal : SV_Target4; //!< RGB10 = EncodeNormalSignedOctahedron(worldNormal), A2 = multiScatterCompensationEnabled
float4 m_clearCoatNormal : SV_Target5; //!< RG = EncodeNormalSphereMap(clearCoatNormal), B = clearCoatFactor, A = clearCoatRoughness
float3 m_scatterDistance : SV_Target6;
};
struct ForwardPassOutputWithDepth
{
// m_diffuseColor.a should be encoded with subsurface scattering's strength factor and quality factor if enabled
// See above for descriptions of special encodings
float4 m_diffuseColor : SV_Target0;
float4 m_specularColor : SV_Target1;
float4 m_albedo : SV_Target2;
@@ -47,8 +47,10 @@ class LightingData
// Normal . View
float NdotV;
// Occlusion factors
// 0 = dark, 1 = light
float occlusion;
float diffuseAmbientOcclusion;
float specularOcclusion;
void Init(float3 positionWS, float3 normal, float roughnessLinear);
void CalculateMultiscatterCompensation(float3 specularF0, bool enabled);
@@ -62,7 +64,8 @@ void LightingData::Init(float3 positionWS, float3 normal, float roughnessLinear)
translucentBackLighting = 0;
multiScatterCompensation = 1.0f;
emissiveLighting = float3(0.0f, 0.0f, 0.0f);
occlusion = 1.0f;
diffuseAmbientOcclusion = 1.0f;
specularOcclusion = 1.0f;
dirToCamera = normalize(ViewSrg::m_worldPosition.xyz - positionWS);
@@ -79,6 +82,7 @@ void LightingData::CalculateMultiscatterCompensation(float3 specularF0, bool ena
void LightingData::FinalizeLighting(float3 transmissionTint)
{
specularLighting *= specularOcclusion;
specularLighting += emissiveLighting;
// Transmitted light
@@ -45,8 +45,8 @@ PbrLightingOutput GetPbrLightingOutput(Surface surface, LightingData lightingDat
// albedo, specularF0, roughness, and normals for later passes (specular IBL, Diffuse GI, SSR, AO, etc)
lightingOutput.m_specularF0 = float4(surface.specularF0, surface.roughnessLinear);
lightingOutput.m_albedo.rgb = surface.albedo * lightingData.diffuseResponse;
lightingOutput.m_albedo.a = lightingData.occlusion;
lightingOutput.m_albedo.rgb = surface.albedo * lightingData.diffuseResponse * lightingData.diffuseAmbientOcclusion;
lightingOutput.m_albedo.a = lightingData.specularOcclusion;
lightingOutput.m_normal.rgb = EncodeNormalSignedOctahedron(surface.normal);
lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f;
@@ -58,6 +58,3 @@ PbrLightingOutput GetPbrLightingOutput(Surface surface, LightingData lightingDat
@@ -66,7 +66,8 @@ PbrLightingOutput PbrLighting( VSOutput IN,
float3 vtxBitangent,
float2 anisotropy, // angle and factor
float3 emissive,
float occlusion,
float diffuseAmbientOcclusion,
float specularOcclusion,
float4 transmissionTintThickness,
float4 transmissionParams,
float clearCoatFactor,
@@ -108,7 +109,8 @@ PbrLightingOutput PbrLighting( VSOutput IN,
lightingData.Init(surface.position, surface.normal, surface.roughnessLinear);
lightingData.emissiveLighting = emissive;
lightingData.occlusion = occlusion;
lightingData.diffuseAmbientOcclusion = diffuseAmbientOcclusion;
lightingData.specularOcclusion = specularOcclusion;
// Directional light shadow coordinates
lightingData.shadowCoords = shadowCoords;
@@ -191,7 +193,7 @@ PbrLightingOutput MakeDebugOutput(VSOutput IN, float3 debugColor, float3 normalW
PbrLightingOutput lightingOutput = PbrLighting(IN, baseColor, metallic, roughness, specularF0Factor,
normal, IN.m_tangent, IN.m_bitangent, anisotropy,
emissive, occlusion, transmissionTintThickness, transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, OpacityMode::Opaque);
emissive, occlusion, occlusion, transmissionTintThickness, transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, OpacityMode::Opaque);
return lightingOutput;
}
@@ -76,7 +76,7 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
// Adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
lightingData.diffuseLighting += (iblDiffuse * iblExposureFactor * lightingData.occlusion);
lightingData.diffuseLighting += (iblDiffuse * iblExposureFactor * lightingData.diffuseAmbientOcclusion);
lightingData.specularLighting += (iblSpecular * iblExposureFactor);
}
}
@@ -24,7 +24,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2DMS<float4> m_downsampledProbeIrradiance;
Texture2DMS<float> m_downsampledDepth;
Texture2DMS<float4> m_downsampledNormal;
Texture2DMS<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2DMS<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2DMS<float> m_depth;
@@ -118,7 +118,7 @@ float3 SampleProbeIrradiance(uint sampleIndex, uint2 probeIrradianceCoords, floa
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
uint samples;
@@ -160,23 +160,19 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex);
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(screenCoords, sampleIndex);
float occlusion = albedo.a;
float useProbeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).a;
float3 diffuse = float3(0.0f, 0.0f, 0.0f);
if (useProbeIrradiance > 0.0f)
{
float3 irradiance = SampleProbeIrradiance(sampleIndex, probeIrradianceCoords, depth, normal, albedo, ImageScale);
diffuse = (albedo.rgb / PI) * irradiance * occlusion;
diffuse = (albedo.rgb / PI) * irradiance;
}
else
{
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -27,7 +27,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2D<float4> m_downsampledProbeIrradiance;
Texture2D<float> m_downsampledDepth;
Texture2D<float4> m_downsampledNormal;
Texture2D<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2D<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2D<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2D<float> m_depth;
@@ -121,7 +121,7 @@ float3 SampleProbeIrradiance(uint2 probeIrradianceCoords, float depth, float3 no
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
PassSrg::m_depth.GetDimensions(dimensions.x, dimensions.y);
@@ -162,23 +162,19 @@ PSOutput MainPS(VSOutput IN)
float4 encodedNormal = PassSrg::m_normal.Load(int3(screenCoords, 0));
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(int3(screenCoords, 0));
float occlusion = albedo.a;
float useProbeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(int3(probeIrradianceCoords,0)).a;
float3 diffuse = float3(0.0f, 0.0f, 0.0f);
if (useProbeIrradiance > 0.0f)
{
float3 irradiance = SampleProbeIrradiance(probeIrradianceCoords, depth, normal, albedo, ImageScale);
diffuse = (albedo.rgb / PI) * irradiance * occlusion;
diffuse = (albedo.rgb / PI) * irradiance;
}
else
{
float3 irradiance = SampleGlobalIBL(screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(screenCoords, depth, normal);
diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -21,7 +21,7 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2DMS<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2DMS<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2DMS<float> m_depth;
}
@@ -41,7 +41,7 @@ VSOutput MainVS(VSInput input)
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
uint samples;
@@ -76,14 +76,10 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex);
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(screenCoords, sampleIndex);
float occlusion = albedo.a;
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
float3 diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -24,7 +24,7 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2D<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2D<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2D<float> m_depth;
}
@@ -44,7 +44,7 @@ VSOutput MainVS(VSInput input)
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
PassSrg::m_depth.GetDimensions(dimensions.x, dimensions.y);
@@ -78,14 +78,10 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(int3(screenCoords, 0));
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(int3(screenCoords, 0));
float occlusion = albedo.a;
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
float3 diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -43,8 +43,9 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2DMS<float> m_depth;
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2DMS<float4> m_normal; // RGB10 = EncodeNormalSignedOctahedron(worldNormal), A2 = multiScatterCompensationEnabled
Texture2DMS<float4> m_specularF0; // RGB8 = SpecularF0, A8 = Roughness
Texture2DMS<float4> m_albedo; // RGB = Not used here, A = specularOcclusion
Texture2DMS<float4> m_clearCoatNormal; // R16G16 = Normal (Packed), B16A16 = (factor, perceptual roughness)
Texture2DMS<float> m_blendWeight;
Texture2D<float2> m_brdfMap;
@@ -80,6 +81,9 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(IN.m_position.xy, sampleIndex);
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
bool multiScatterCompensationEnabled = (encodedNormal.a > 0.0f);
float4 albedo = PassSrg::m_albedo.Load(IN.m_position.xy, sampleIndex);
float specularOcclusion = albedo.a;
// reconstruct world space position from the depth at this location in screenspace
float3 positionWS = ReconstructWorldPositionFromDepth(IN.m_position.xy, sampleIndex).xyz;
@@ -136,6 +140,9 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
// apply exposure setting
specular *= pow(2.0, SceneSrg::m_iblExposure);
// maybe attenuate the specular
specular *= specularOcclusion;
PSOutput OUT;
OUT.m_color = float4(specular, 1.0f);
return OUT;
@@ -41,7 +41,6 @@ set(FILES
Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl
Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.shader
Materials/Types/StandardPBR.materialtype
Materials/Types/StandardPBR_AoState.lua
Materials/Types/StandardPBR_ClearCoatEnableFeature.lua
Materials/Types/StandardPBR_ClearCoatState.lua
Materials/Types/StandardPBR_Common.azsli
@@ -145,8 +145,10 @@ namespace AZ
const MaterialAssignmentMap& GetMaterialAssignmentMap(const MeshHandle& meshHandle) const override;
void ConnectModelChangeEventHandler(const MeshHandle& meshHandle, ModelChangedEvent::Handler& handler) override;
void SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform) override;
void SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()) override;
Transform GetTransform(const MeshHandle& meshHandle) override;
Vector3 GetNonUniformScale(const MeshHandle& meshHandle) override;
void SetSortKey(const MeshHandle& meshHandle, RHI::DrawItemSortKey sortKey) override;
RHI::DrawItemSortKey GetSortKey(const MeshHandle& meshHandle) override;
@@ -62,9 +62,12 @@ namespace AZ
//! Connects a handler to any changes to an RPI::Model. Changes include loading and reloading.
virtual void ConnectModelChangeEventHandler(const MeshHandle& meshHandle, ModelChangedEvent::Handler& handler) = 0;
//! Sets the transform for a given mesh handle.
virtual void SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform) = 0;
virtual void SetTransform(const MeshHandle& meshHandle, const Transform& transform,
const Vector3& nonUniformScale = Vector3::CreateOne()) = 0;
//! Gets the transform for a given mesh handle.
virtual Transform GetTransform(const MeshHandle& meshHandle) = 0;
//! Gets the non-uniform scale for a given mesh handle.
virtual Vector3 GetNonUniformScale(const MeshHandle& meshHandle) = 0;
//! Sets the sort key for a given mesh handle.
virtual void SetSortKey(const MeshHandle& meshHandle, RHI::DrawItemSortKey sortKey) = 0;
//! Gets the sort key for a given mesh handle.
@@ -50,8 +50,10 @@ namespace AZ
// TransformServiceFeatureProcessorInterface overrides ...
ObjectId ReserveObjectId() override;
void ReleaseObjectId(ObjectId& id) override;
void SetTransformForId(ObjectId id, const AZ::Transform& transform) override;
void SetTransformForId(ObjectId id, const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()) override;
AZ::Transform GetTransformForId(ObjectId id) const override;
AZ::Vector3 GetNonUniformScaleForId(ObjectId id) const override;
private:
@@ -13,6 +13,7 @@
#pragma once
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
#include <Atom/RPI.Public/FeatureProcessor.h>
namespace AZ
@@ -34,11 +35,13 @@ namespace AZ
//! Releases an object ID to be used by others. The passed in handle is invalidated.
virtual void ReleaseObjectId(ObjectId& id) = 0;
//! Sets the transform for a given id. Id must be one reserved earlier.
virtual void SetTransformForId(ObjectId id, const AZ::Transform& transform) = 0;
//! Sets the transform (and optionally non-uniform scale) for a given id. Id must be one reserved earlier.
virtual void SetTransformForId(ObjectId id, const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()) = 0;
//! Gets the transform for a given id. Id must be one reserved earlier.
virtual AZ::Transform GetTransformForId(ObjectId) const = 0;
//! Gets the non-uniform scale for a given id. Id must be one reserved earlier.
virtual AZ::Vector3 GetNonUniformScaleForId(ObjectId id) const = 0;
};
}
}
@@ -31,11 +31,12 @@ namespace UnitTest
MOCK_CONST_METHOD1(GetModel, AZStd::intrusive_ptr<AZ::RPI::Model>(const MeshHandle&));
MOCK_CONST_METHOD1(GetMaterialAssignmentMap, const AZ::Render::MaterialAssignmentMap&(const MeshHandle&));
MOCK_METHOD2(ConnectModelChangeEventHandler, void(const MeshHandle&, ModelChangedEvent::Handler&));
MOCK_METHOD2(SetTransform, void(const MeshHandle&, const AZ::Transform&));
MOCK_METHOD3(SetTransform, void(const MeshHandle&, const AZ::Transform&, const AZ::Vector3&));
MOCK_METHOD2(SetExcludeFromReflectionCubeMaps, void(const MeshHandle&, bool));
MOCK_METHOD2(SetMaterialAssignmentMap, void(const MeshHandle&, const AZ::Data::Instance<AZ::RPI::Material>&));
MOCK_METHOD2(SetMaterialAssignmentMap, void(const MeshHandle&, const AZ::Render::MaterialAssignmentMap&));
MOCK_METHOD1(GetTransform, AZ::Transform (const MeshHandle&));
MOCK_METHOD1(GetTransform, AZ::Transform(const MeshHandle&));
MOCK_METHOD1(GetNonUniformScale, AZ::Vector3(const MeshHandle&));
MOCK_METHOD2(SetSortKey, void (const MeshHandle&, AZ::RHI::DrawItemSortKey));
MOCK_METHOD1(GetSortKey, AZ::RHI::DrawItemSortKey(const MeshHandle&));
MOCK_METHOD2(SetLodOverride, void(const MeshHandle&, AZ::RPI::Cullable::LodOverride));
@@ -504,7 +504,7 @@ namespace AZ
box.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
box.m_color = color;
box.m_scale = localMatrix3x4.ExtractScale() * extents;
box.m_position = localMatrix3x4.GetTranslation() + center;
box.m_position = matrix3x4 * center;
box.m_rotationMatrix = Matrix3x3::CreateFromMatrix3x4(localMatrix3x4);
box.m_pointSize = m_pointSize;
box.m_viewProjOverrideIndex = viewProjOverrideIndex;
@@ -1238,6 +1238,8 @@ namespace AZ
void DirectionalLightFeatureProcessor::SetFilterParameterToPass(LightHandle handle, const RPI::View* cameraView)
{
AZ_ATOM_PROFILE_FUNCTION("DirectionalLightFeatureProcessor", "DirectionalLightFeatureProcessor::SetFilterParameterToPass");
if (handle != m_shadowingLightHandle)
{
return;
@@ -256,7 +256,7 @@ namespace AZ
}
}
void MeshFeatureProcessor::SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform)
void MeshFeatureProcessor::SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform, const AZ::Vector3& nonUniformScale)
{
if (meshHandle.IsValid())
{
@@ -264,12 +264,12 @@ namespace AZ
meshData.m_cullBoundsNeedsUpdate = true;
meshData.m_objectSrgNeedsUpdate = true;
m_transformService->SetTransformForId(meshHandle->m_objectId, transform);
m_transformService->SetTransformForId(meshHandle->m_objectId, transform, nonUniformScale);
// ray tracing data needs to be updated with the new transform
if (m_rayTracingFeatureProcessor)
{
m_rayTracingFeatureProcessor->SetMeshTransform(meshHandle->m_objectId, transform);
m_rayTracingFeatureProcessor->SetMeshTransform(meshHandle->m_objectId, transform, nonUniformScale);
}
}
}
@@ -287,6 +287,19 @@ namespace AZ
}
}
Vector3 MeshFeatureProcessor::GetNonUniformScale(const MeshHandle& meshHandle)
{
if (meshHandle.IsValid())
{
return m_transformService->GetNonUniformScaleForId(meshHandle->m_objectId);
}
else
{
AZ_Assert(false, "Invalid mesh handle");
return Vector3::CreateOne();
}
}
void MeshFeatureProcessor::SetSortKey(const MeshHandle& meshHandle, RHI::DrawItemSortKey sortKey)
{
if (meshHandle.IsValid())
@@ -845,10 +858,13 @@ namespace AZ
AZ_Assert(m_model, "The model has not finished loading yet");
Transform localToWorld = transformService->GetTransformForId(m_objectId);
Vector3 nonUniformScale = transformService->GetNonUniformScaleForId(m_objectId);
Vector3 center;
float radius;
Aabb localAabb = m_model->GetAabb();
localAabb.MultiplyByScale(nonUniformScale);
localAabb.GetTransformedAabb(localToWorld).GetAsSphere(center, radius);
m_cullable.m_cullData.m_boundingSphere = Sphere(center, radius);
@@ -81,6 +81,7 @@ namespace AZ
->HitGroupIndex(blasIndex)
->Blas(rayTracingSubMesh.m_blas)
->Transform(rayTracingMesh.second.m_transform)
->NonUniformScale(rayTracingMesh.second.m_nonUniformScale)
;
}
@@ -143,7 +143,7 @@ namespace AZ
m_meshInfoBufferNeedsUpdate = true;
}
void RayTracingFeatureProcessor::SetMeshTransform(const ObjectId objectId, AZ::Transform transform)
void RayTracingFeatureProcessor::SetMeshTransform(const ObjectId objectId, const AZ::Transform transform, const AZ::Vector3 nonUniformScale)
{
if (!m_rayTracingEnabled)
{
@@ -154,6 +154,7 @@ namespace AZ
if (itMesh != m_meshes.end())
{
itMesh->second.m_transform = transform;
itMesh->second.m_nonUniformScale = nonUniformScale;
m_revision++;
}
@@ -68,6 +68,9 @@ namespace AZ
// mesh transform
AZ::Transform m_transform = AZ::Transform::CreateIdentity();
// mesh non-uniform scale
AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne();
// flag indicating if the Blas objects in the sub-meshes are built
bool m_blasBuilt = false;
};
@@ -85,7 +88,8 @@ namespace AZ
//! Sets the ray tracing mesh transform
//! This will cause an update to the RayTracing acceleration structure on the next frame
void SetMeshTransform(const ObjectId objectId, const AZ::Transform transform);
void SetMeshTransform(const ObjectId objectId, const AZ::Transform transform,
const AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne());
//! Retrieves ray tracing data for all meshes in the scene
const MeshMap& GetMeshes() const { return m_meshes; }
@@ -210,14 +210,14 @@ namespace AZ
}
}
void TransformServiceFeatureProcessor::SetTransformForId(ObjectId id, const AZ::Transform& transform)
void TransformServiceFeatureProcessor::SetTransformForId(ObjectId id, const AZ::Transform& transform, const AZ::Vector3& nonUniformScale)
{
AZ_Error("TransformServiceFeatureProcessor", m_isWriteable, "Transform data cannot be written to during this phase");
AZ_Error("TransformServiceFeatureProcessor", id.IsValid(), "Attempting to set the transform for an invalid handle.");
if (id.IsValid())
{
AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(transform);
matrix3x4.MultiplyByScale(nonUniformScale);
matrix3x4.StoreToRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform);
// Inverse transpose to take the non-uniform scale out of the transform for usage with normals.
@@ -228,8 +228,18 @@ namespace AZ
AZ::Transform TransformServiceFeatureProcessor::GetTransformForId(ObjectId id) const
{
AZ_Error("TransformServiceFeatureProcessor", id.IsValid(), "Attempting to set the transform for an invalid handle.");
return AZ::Transform::CreateFromMatrix3x4( Matrix3x4::CreateFromRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform) );
AZ_Error("TransformServiceFeatureProcessor", id.IsValid(), "Attempting to get the transform for an invalid handle.");
AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform);
AZ::Transform transform = AZ::Transform::CreateFromMatrix3x4(matrix3x4);
transform.ExtractScale();
return transform;
}
AZ::Vector3 TransformServiceFeatureProcessor::GetNonUniformScaleForId(ObjectId id) const
{
AZ_Error("TransformServiceFeatureProcessor", id.IsValid(), "Attempting to get the non-uniform scale for an invalid handle.");
AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform);
return matrix3x4.RetrieveScale();
}
}
}
@@ -111,6 +111,7 @@ namespace AZ
uint32_t m_instanceID = 0;
uint32_t m_hitGroupIndex = 0;
AZ::Transform m_transform = AZ::Transform::CreateIdentity();
AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne();
RHI::Ptr<RHI::RayTracingBlas> m_blas;
};
using RayTracingTlasInstanceVector = AZStd::vector<RayTracingTlasInstance>;
@@ -154,6 +155,7 @@ namespace AZ
RayTracingTlasDescriptor* InstanceID(uint32_t instanceID);
RayTracingTlasDescriptor* HitGroupIndex(uint32_t hitGroupIndex);
RayTracingTlasDescriptor* Transform(const AZ::Transform& transform);
RayTracingTlasDescriptor* NonUniformScale(const AZ::Vector3& nonUniformScale);
RayTracingTlasDescriptor* Blas(RHI::Ptr<RHI::RayTracingBlas>& blas);
RayTracingTlasDescriptor* InstancesBuffer(RHI::Ptr<RHI::Buffer>& tlasInstances);
RayTracingTlasDescriptor* NumInstances(uint32_t numInstancesInBuffer);
@@ -85,6 +85,13 @@ namespace AZ
return this;
}
RayTracingTlasDescriptor* RayTracingTlasDescriptor::NonUniformScale(const AZ::Vector3& nonUniformScale)
{
AZ_Assert(m_buildContext, "NonUniformSCale property can only be added to an Instance entry");
m_buildContext->m_nonUniformScale = nonUniformScale;
return this;
}
RayTracingTlasDescriptor* RayTracingTlasDescriptor::Blas(RHI::Ptr<RHI::RayTracingBlas>& blas)
{
AZ_Assert(m_buildContext, "Blas property can only be added to an Instance entry");

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