diff --git a/Code/CryEngine/CryCommon/BaseTypes.h b/Code/CryEngine/CryCommon/BaseTypes.h index 579eec944f..4abc9549bf 100644 --- a/Code/CryEngine/CryCommon/BaseTypes.h +++ b/Code/CryEngine/CryCommon/BaseTypes.h @@ -71,10 +71,14 @@ COMPILE_TIME_ASSERT(sizeof(uint32) == 4); COMPILE_TIME_ASSERT(sizeof(sint32) == 4); typedef slonglong int64; + +#ifndef O3DE_INT64_DEFINED +#define O3DE_INT64_DEFINED typedef slonglong sint64; typedef ulonglong uint64; COMPILE_TIME_ASSERT(sizeof(uint64) == 8); COMPILE_TIME_ASSERT(sizeof(sint64) == 8); +#endif typedef float f32; diff --git a/Code/CryEngine/CryFont/CMakeLists.txt b/Code/CryEngine/CryFont/CMakeLists.txt index 8d884bd299..9e2f29f7b6 100644 --- a/Code/CryEngine/CryFont/CMakeLists.txt +++ b/Code/CryEngine/CryFont/CMakeLists.txt @@ -19,6 +19,6 @@ ly_add_target( . BUILD_DEPENDENCIES PRIVATE - 3rdParty::FreeType2 + 3rdParty::freetype Legacy::CryCommon ) diff --git a/Code/CryEngine/CrySystem/ImageHandler.cpp b/Code/CryEngine/CrySystem/ImageHandler.cpp index 89f2700014..7444aebdc0 100644 --- a/Code/CryEngine/CrySystem/ImageHandler.cpp +++ b/Code/CryEngine/CrySystem/ImageHandler.cpp @@ -22,7 +22,7 @@ #endif #if !(defined(ANDROID) || defined(IOS) || defined(LINUX)) && AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO // Rally US1050 - Compile libtiff for Android and IOS - #include + #include static_assert(sizeof(thandle_t) >= sizeof(AZ::IO::HandleType), "Platform defines thandle_t to be smaller than required"); #endif diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h index 85f35f972f..6ba357cd29 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h @@ -43,6 +43,9 @@ namespace AZ { const static AZ::Crc32 RuntimeEBusAttribute = AZ_CRC("RuntimeEBus", 0x466b899b); ///< Signals that this reflected ebus should only be available at runtime, helps tools filter out data driven ebuses + constexpr const char* k_PropertyNameGetterSuffix = "::Getter"; + constexpr const char* k_PropertyNameSetterSuffix = "::Setter"; + /// Typedef for class unwrapping callback (i.e. used for things like smart_ptr to unwrap for T) using BehaviorClassUnwrapperFunction = void(*)(void* /*classPtr*/, void*& /*unwrappedClass*/, AZ::Uuid& /*unwrappedClassTypeId*/, void* /*userData*/); @@ -2525,7 +2528,7 @@ namespace AZ getterPropertyName += "::"; } getterPropertyName += m_name; - getterPropertyName += "::Getter"; + getterPropertyName += k_PropertyNameGetterSuffix; m_getter = aznew GetterType(getter, context, getterPropertyName); if (AZStd::is_class::value) @@ -2603,7 +2606,7 @@ namespace AZ setterPropertyName += "::"; } setterPropertyName += m_name; - setterPropertyName += "::Setter"; + setterPropertyName += k_PropertyNameSetterSuffix; m_setter = aznew SetterType(setter, context, setterPropertyName); if (AZStd::is_class::value) { diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp index 770960c509..c64b86ae0f 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp @@ -243,6 +243,28 @@ namespace AZ return variance; } + void RemovePropertyGetterNameArtifacts(AZStd::string& name) + { + if (name.ends_with(k_PropertyNameGetterSuffix)) + { + AZ::StringFunc::Replace(name, k_PropertyNameGetterSuffix, ""); + } + } + + void RemovePropertySetterNameArtifacts(AZStd::string& name) + { + if (name.ends_with(k_PropertyNameSetterSuffix)) + { + AZ::StringFunc::Replace(name, k_PropertyNameSetterSuffix, ""); + } + } + + void RemovePropertyNameArtifacts(AZStd::string& name) + { + RemovePropertyGetterNameArtifacts(name); + RemovePropertySetterNameArtifacts(name); + } + AZStd::string ReplaceCppArtifacts(AZStd::string_view sourceName) { using namespace AZ::StringFunc; diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h index dfd2d0827f..4663635cdf 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h @@ -68,6 +68,12 @@ namespace AZ AZStd::vector> OverloadsToVector(const BehaviorMethod&, const BehaviorClass*); + void RemovePropertyGetterNameArtifacts(AZStd::string& name); + + void RemovePropertySetterNameArtifacts(AZStd::string& name); + + void RemovePropertyNameArtifacts(AZStd::string& name); + AZStd::string ReplaceCppArtifacts(AZStd::string_view sourceName); void StripQualifiers(AZStd::string& name); diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp new file mode 100644 index 0000000000..ee49a95b23 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -0,0 +1,531 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include "CameraInput.h" + +#include +#include +#include +#include + +namespace AzFramework +{ + void CameraSystem::HandleEvents(const InputEvent& event) + { + if (const auto& cursor_motion = AZStd::get_if(&event)) + { + m_currentCursorPosition = cursor_motion->m_position; + } + else if (const auto& scroll = AZStd::get_if(&event)) + { + m_scrollDelta = scroll->m_delta; + } + + m_cameras.HandleEvents(event); + } + + Camera CameraSystem::StepCamera(const Camera& targetCamera, float deltaTime) + { + const auto cursorDelta = m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value() + ? m_currentCursorPosition.value() - m_lastCursorPosition.value() + : ScreenVector(0, 0); + + if (m_currentCursorPosition.has_value()) + { + m_lastCursorPosition = m_currentCursorPosition; + } + + const auto nextCamera = m_cameras.StepCamera(targetCamera, cursorDelta, m_scrollDelta, deltaTime); + + m_scrollDelta = 0.0f; + + return nextCamera; + } + + void Cameras::AddCamera(AZStd::shared_ptr camera_input) + { + m_idleCameraInputs.push_back(AZStd::move(camera_input)); + } + + void Cameras::HandleEvents(const InputEvent& event) + { + for (auto& camera_input : m_activeCameraInputs) + { + camera_input->HandleEvents(event); + } + + for (auto& camera_input : m_idleCameraInputs) + { + camera_input->HandleEvents(event); + } + } + + Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, const float deltaTime) + { + for (int i = 0; i < m_idleCameraInputs.size();) + { + auto& camera_input = m_idleCameraInputs[i]; + const bool can_begin = camera_input->Beginning() && + std::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(), + [](const auto& input) { return !input->Exclusive(); }) && + (!camera_input->Exclusive() || (camera_input->Exclusive() && m_activeCameraInputs.empty())); + if (can_begin) + { + m_activeCameraInputs.push_back(camera_input); + using AZStd::swap; + swap(m_idleCameraInputs[i], m_idleCameraInputs[m_idleCameraInputs.size() - 1]); + m_idleCameraInputs.pop_back(); + } + else + { + i++; + } + } + + // accumulate + Camera nextCamera = targetCamera; + for (auto& camera_input : m_activeCameraInputs) + { + nextCamera = camera_input->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime); + } + + for (int i = 0; i < m_activeCameraInputs.size();) + { + auto& camera_input = m_activeCameraInputs[i]; + if (camera_input->Ending()) + { + camera_input->ClearActivation(); + m_idleCameraInputs.push_back(camera_input); + using AZStd::swap; + swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]); + m_activeCameraInputs.pop_back(); + } + else + { + camera_input->ContinueActivation(); + i++; + } + } + + return nextCamera; + } + + void Cameras::Reset() + { + for (int i = 0; i < m_activeCameraInputs.size();) + { + m_activeCameraInputs[i]->Reset(); + m_idleCameraInputs.push_back(m_activeCameraInputs[i]); + m_activeCameraInputs[i] = m_activeCameraInputs[m_activeCameraInputs.size() - 1]; + m_activeCameraInputs.pop_back(); + } + } + + void RotateCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto& input = AZStd::get_if(&event)) + { + if (input->m_channelId == m_channelId) + { + if (input->m_state == InputChannel::State::Began) + { + BeginActivation(); + } + else if (input->m_state == InputChannel::State::Ended) + { + EndActivation(); + } + } + } + } + + Camera RotateCameraInput::StepCamera( + const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + [[maybe_unused]] const float deltaTime) + { + Camera nextCamera = targetCamera; + + nextCamera.m_pitch += float(cursorDelta.m_y) * m_props.m_rotateSpeed; + nextCamera.m_yaw += float(cursorDelta.m_x) * m_props.m_rotateSpeed; + + auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoOverPi, AZ::Constants::TwoOverPi); }; + + nextCamera.m_yaw = clamp_rotation(nextCamera.m_yaw); + // clamp pitch to be +-90 degrees + nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::Pi * 0.5f, AZ::Constants::Pi * 0.5f); + + return nextCamera; + } + + void PanCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto& input = AZStd::get_if(&event)) + { + if (input->m_channelId == InputDeviceMouse::Button::Middle) + { + if (input->m_state == InputChannel::State::Began) + { + BeginActivation(); + } + else if (input->m_state == InputChannel::State::Ended) + { + EndActivation(); + } + } + } + } + + Camera PanCameraInput::StepCamera( + const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + [[maybe_unused]] const float deltaTime) + { + Camera nextCamera = targetCamera; + + const auto pan_axes = m_panAxesFn(nextCamera); + + const auto delta_pan_x = float(cursorDelta.m_x) * pan_axes.m_horizontalAxis * m_props.m_panSpeed; + const auto delta_pan_y = float(cursorDelta.m_y) * pan_axes.m_verticalAxis * m_props.m_panSpeed; + + const auto inv = [](const bool invert) { + constexpr float Dir[] = {1.0f, -1.0f}; + return Dir[static_cast(invert)]; + }; + + nextCamera.m_lookAt += delta_pan_x * inv(m_props.m_panInvertX); + nextCamera.m_lookAt += delta_pan_y * -inv(m_props.m_panInvertY); + + return nextCamera; + } + + TranslateCameraInput::TranslationType TranslateCameraInput::translationFromKey(InputChannelId channelId) + { + // note: remove hard-coded InputDevice keys + if (channelId == InputDeviceKeyboard::Key::AlphanumericW) + { + return TranslationType::Forward; + } + + if (channelId == InputDeviceKeyboard::Key::AlphanumericS) + { + return TranslationType::Backward; + } + + if (channelId == InputDeviceKeyboard::Key::AlphanumericA) + { + return TranslationType::Left; + } + + if (channelId == InputDeviceKeyboard::Key::AlphanumericD) + { + return TranslationType::Right; + } + + if (channelId == InputDeviceKeyboard::Key::AlphanumericQ) + { + return TranslationType::Down; + } + + if (channelId == InputDeviceKeyboard::Key::AlphanumericE) + { + return TranslationType::Up; + } + + return TranslationType::Nil; + } + + void TranslateCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto& input = AZStd::get_if(&event)) + { + if (input->m_state == InputChannel::State::Began) + { + if (input->m_state == InputChannel::State::Updated) + { + return; + } + + m_translation |= translationFromKey(input->m_channelId); + if (m_translation != TranslationType::Nil) + { + BeginActivation(); + } + + if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL) + { + m_boost = true; + } + } + else if (input->m_state == InputChannel::State::Ended) + { + m_translation ^= translationFromKey(input->m_channelId); + if (m_translation == TranslationType::Nil) + { + EndActivation(); + } + if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL) + { + m_boost = false; + } + } + } + } + + Camera TranslateCameraInput::StepCamera( + const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + const float deltaTime) + { + Camera nextCamera = targetCamera; + + const auto translation_basis = m_translationAxesFn(nextCamera); + const auto axisX = translation_basis.GetBasisX(); + const auto axisY = translation_basis.GetBasisY(); + const auto axisZ = translation_basis.GetBasisZ(); + + const float speed = [boost = m_boost, props = m_props]() { + return props.m_translateSpeed * (boost ? props.m_boostMultiplier : 1.0f); + }(); + + if ((m_translation & TranslationType::Forward) == TranslationType::Forward) + { + nextCamera.m_lookAt += axisY * speed * deltaTime; + } + + if ((m_translation & TranslationType::Backward) == TranslationType::Backward) + { + nextCamera.m_lookAt -= axisY * speed * deltaTime; + } + + if ((m_translation & TranslationType::Left) == TranslationType::Left) + { + nextCamera.m_lookAt -= axisX * speed * deltaTime; + } + + if ((m_translation & TranslationType::Right) == TranslationType::Right) + { + nextCamera.m_lookAt += axisX * speed * deltaTime; + } + + if ((m_translation & TranslationType::Up) == TranslationType::Up) + { + nextCamera.m_lookAt += axisZ * speed * deltaTime; + } + + if ((m_translation & TranslationType::Down) == TranslationType::Down) + { + nextCamera.m_lookAt -= axisZ * speed * deltaTime; + } + + if (Ending()) + { + m_translation = TranslationType::Nil; + } + + return nextCamera; + } + + void TranslateCameraInput::ResetImpl() + { + m_translation = TranslationType::Nil; + m_boost = false; + } + + void OrbitCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto* input = AZStd::get_if(&event)) + { + if (input->m_channelId == InputDeviceKeyboard::Key::ModifierAltL) + { + if (input->m_state == InputChannel::State::Updated) + { + goto end; + } + if (input->m_state == InputChannel::State::Began) + { + BeginActivation(); + } + else if (input->m_state == InputChannel::State::Ended) + { + EndActivation(); + } + } + } + end: + if (Active()) + { + m_orbitCameras.HandleEvents(event); + } + } + + Camera OrbitCameraInput::StepCamera( + const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, float deltaTime) + { + Camera nextCamera = targetCamera; + + if (Beginning()) + { + float hit_distance = 0.0f; + if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateZero()) + .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY() * m_props.m_maxOrbitDistance, hit_distance)) + { + nextCamera.m_lookDist = -hit_distance; + nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance; + } + else + { + nextCamera.m_lookDist = -m_props.m_defaultOrbitDistance; + nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * m_props.m_defaultOrbitDistance; + } + } + + if (Active()) + { + // todo: need to return nested cameras to idle state when ending + nextCamera = m_orbitCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime); + } + + if (Ending()) + { + m_orbitCameras.Reset(); + + nextCamera.m_lookAt = nextCamera.Translation(); + nextCamera.m_lookDist = 0.0f; + } + + return nextCamera; + } + + void OrbitDollyScrollCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto* scroll = AZStd::get_if(&event)) + { + BeginActivation(); + } + } + + Camera OrbitDollyScrollCameraInput::StepCamera( + const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta, + [[maybe_unused]] float deltaTime) + { + Camera nextCamera = targetCamera; + nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * m_props.m_dollySpeed, 0.0f); + EndActivation(); + return nextCamera; + } + + void OrbitDollyCursorMoveCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto& input = AZStd::get_if(&event)) + { + if (input->m_channelId == InputDeviceMouse::Button::Right) + { + if (input->m_state == InputChannel::State::Began) + { + BeginActivation(); + } + else if (input->m_state == InputChannel::State::Ended) + { + EndActivation(); + } + } + } + } + + Camera OrbitDollyCursorMoveCameraInput::StepCamera( + const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + [[maybe_unused]] const float deltaTime) + { + Camera nextCamera = targetCamera; + nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * m_props.m_dollySpeed, 0.0f); + return nextCamera; + } + + void ScrollTranslationCameraInput::HandleEvents(const InputEvent& event) + { + if (const auto* scroll = AZStd::get_if(&event)) + { + BeginActivation(); + } + } + + Camera ScrollTranslationCameraInput::StepCamera( + const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, float scrollDelta, + [[maybe_unused]] const float deltaTime) + { + Camera nextCamera = targetCamera; + + const auto translation_basis = LookTranslation(nextCamera); + const auto axisY = translation_basis.GetBasisY(); + + nextCamera.m_lookAt += axisY * scrollDelta * m_props.m_translateSpeed; + + EndActivation(); + + return nextCamera; + } + + Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, const float deltaTime) + { + const auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; + + // keep yaw in 0 - 360 range + float target_yaw = clamp_rotation(targetCamera.m_yaw); + const float current_yaw = clamp_rotation(currentCamera.m_yaw); + + auto sign = [](const float value) { return static_cast((0.0f < value) - (value < 0.0f)); }; + + // ensure smooth transition when moving across 0 - 360 boundary + const float yaw_delta = target_yaw - current_yaw; + if (std::abs(yaw_delta) >= AZ::Constants::Pi) + { + target_yaw -= AZ::Constants::TwoPi * sign(yaw_delta); + } + + Camera camera; + // note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent + // article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php + const float lookRate = std::exp2(props.m_lookSmoothness); + const float lookT = std::exp2(-lookRate * deltaTime); + camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT); + camera.m_yaw = AZ::Lerp(target_yaw, current_yaw, lookT); + const float moveRate = std::exp2(props.m_moveSmoothness); + const float moveT = std::exp2(-moveRate * deltaTime); + camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT); + camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT); + return camera; + } + + InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize) + { + const auto& inputChannelId = inputChannel.GetInputChannelId(); + const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId(); + + if (inputChannelId == InputDeviceMouse::SystemCursorPosition) + { + AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero(); + InputSystemCursorRequestBus::EventResult( + systemCursorPositionNormalized, inputDeviceId, &InputSystemCursorRequestBus::Events::GetSystemCursorPositionNormalized); + + return CursorMotionEvent{ScreenPoint( + systemCursorPositionNormalized.GetX() * windowSize.m_width, systemCursorPositionNormalized.GetY() * windowSize.m_height)}; + } + else if (inputChannelId == InputDeviceMouse::Movement::Z) + { + return ScrollEvent{inputChannel.GetValue()}; + } + else if (InputDeviceMouse::IsMouseDevice(inputDeviceId) || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId)) + { + return DiscreteInputEvent{inputChannelId, inputChannel.GetState()}; + } + + return AZStd::monostate{}; + } +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h new file mode 100644 index 0000000000..736e2404d9 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -0,0 +1,420 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +namespace AzFramework +{ + struct WindowSize; + + struct Camera + { + AZ::Vector3 m_lookAt = AZ::Vector3::CreateZero(); //!< Position of camera when m_lookDist is zero, + //!< or position of m_lookAt when m_lookDist is greater + //!< than zero. + float m_yaw{0.0}; + float m_pitch{0.0}; + float m_lookDist{0.0}; //!< Zero gives first person free look, otherwise orbit about m_lookAt + + //! View camera transform (v in MVP). + AZ::Transform View() const; + //! World camera transform. + AZ::Transform Transform() const; + //! World rotation. + AZ::Matrix3x3 Rotation() const; + //! World translation. + AZ::Vector3 Translation() const; + }; + + inline AZ::Transform Camera::View() const + { + return Transform().GetInverse(); + } + + inline AZ::Transform Camera::Transform() const + { + return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationX(m_pitch) * + AZ::Transform::CreateRotationZ(m_yaw) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisZ(m_lookDist)); + } + + inline AZ::Matrix3x3 Camera::Rotation() const + { + return AZ::Matrix3x3::CreateFromQuaternion(Transform().GetRotation()); + } + + inline AZ::Vector3 Camera::Translation() const + { + return Transform().GetTranslation(); + } + + struct CursorMotionEvent + { + ScreenPoint m_position; + }; + + struct ScrollEvent + { + float m_delta; + }; + + struct DiscreteInputEvent + { + InputChannelId m_channelId; //!< Channel type. (e.g. Keyboard key, mouse button or other device input). + InputChannel::State m_state; //!< Channel state. (e.g. Begin/update/end event). + }; + + using InputEvent = AZStd::variant; + + class CameraInput + { + public: + enum class Activation + { + Idle, + Begin, + Active, + End + }; + + virtual ~CameraInput() = default; + + bool Beginning() const + { + return m_activation == Activation::Begin; + } + + bool Ending() const + { + return m_activation == Activation::End; + } + + bool Idle() const + { + return m_activation == Activation::Idle; + } + + bool Active() const + { + return m_activation == Activation::Active; + } + + void BeginActivation() + { + m_activation = Activation::Begin; + } + + void EndActivation() + { + m_activation = Activation::End; + } + + void ContinueActivation() + { + m_activation = Activation::Active; + } + + void ClearActivation() + { + m_activation = Activation::Idle; + } + + void Reset() + { + ClearActivation(); + ResetImpl(); + } + + virtual void HandleEvents(const InputEvent& event) = 0; + virtual Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) = 0; + + virtual bool Exclusive() const + { + return false; + } + + protected: + virtual void ResetImpl() + { + } + + private: + Activation m_activation = Activation::Idle; + }; + + struct SmoothProps + { + float m_lookSmoothness = 5.0f; + float m_moveSmoothness = 5.0f; + }; + + Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, float deltaTime); + + class Cameras + { + public: + void AddCamera(AZStd::shared_ptr cameraInput); + void HandleEvents(const InputEvent& event); + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime); + void Reset(); + + private: + AZStd::vector> m_activeCameraInputs; + AZStd::vector> m_idleCameraInputs; + }; + + class CameraSystem + { + public: + void HandleEvents(const InputEvent& event); + Camera StepCamera(const Camera& targetCamera, float deltaTime); + + Cameras m_cameras; + + private: + float m_scrollDelta = 0.0f; + AZStd::optional m_lastCursorPosition; + AZStd::optional m_currentCursorPosition; + }; + + class RotateCameraInput : public CameraInput + { + public: + explicit RotateCameraInput(const InputChannelId channelId) + : m_channelId(channelId) + { + } + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + + InputChannelId m_channelId; + + struct Props + { + float m_rotateSpeed = 0.005f; + } m_props; + }; + + struct PanAxes + { + AZ::Vector3 m_horizontalAxis; + AZ::Vector3 m_verticalAxis; + }; + + using PanAxesFn = AZStd::function; + + inline PanAxes LookPan(const Camera& camera) + { + const AZ::Matrix3x3 orientation = camera.Rotation(); + return {orientation.GetBasisX(), orientation.GetBasisZ()}; + } + + inline PanAxes OrbitPan(const Camera& camera) + { + const AZ::Matrix3x3 orientation = camera.Rotation(); + + const auto basisX = orientation.GetBasisX(); + const auto basisY = [&orientation] { + const auto forward = orientation.GetBasisY(); + return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized(); + }(); + + return {basisX, basisY}; + } + + class PanCameraInput : public CameraInput + { + public: + explicit PanCameraInput(PanAxesFn panAxesFn) + : m_panAxesFn(AZStd::move(panAxesFn)) + { + } + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + + struct Props + { + float m_panSpeed = 0.01f; + bool m_panInvertX = true; + bool m_panInvertY = true; + } m_props; + + private: + PanAxesFn m_panAxesFn; + }; + + using TranslationAxesFn = AZStd::function; + + inline AZ::Matrix3x3 LookTranslation(const Camera& camera) + { + const AZ::Matrix3x3 orientation = camera.Rotation(); + + const auto basisX = orientation.GetBasisX(); + const auto basisY = orientation.GetBasisY(); + const auto basisZ = AZ::Vector3::CreateAxisZ(); + + return AZ::Matrix3x3::CreateFromColumns(basisX, basisY, basisZ); + } + + inline AZ::Matrix3x3 OrbitTranslation(const Camera& camera) + { + const AZ::Matrix3x3 orientation = camera.Rotation(); + + const auto basisX = orientation.GetBasisX(); + const auto basisY = [&orientation] { + const auto forward = orientation.GetBasisY(); + return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized(); + }(); + const auto basisZ = AZ::Vector3::CreateAxisZ(); + + return AZ::Matrix3x3::CreateFromColumns(basisX, basisY, basisZ); + } + + class TranslateCameraInput : public CameraInput + { + public: + explicit TranslateCameraInput(TranslationAxesFn translationAxesFn) + : m_translationAxesFn(AZStd::move(translationAxesFn)) + { + } + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + void ResetImpl() override; + + struct Props + { + float m_translateSpeed = 10.0f; + float m_boostMultiplier = 3.0f; + } m_props; + + private: + enum class TranslationType + { + // clang-format off + Nil = 0, + Forward = 1 << 0, + Backward = 1 << 1, + Left = 1 << 2, + Right = 1 << 3, + Up = 1 << 4, + Down = 1 << 5, + // clang-format on + }; + + friend TranslationType operator|(const TranslationType lhs, const TranslationType rhs) + { + return static_cast( + static_cast>(lhs) | static_cast>(rhs)); + } + + friend TranslationType& operator|=(TranslationType& lhs, const TranslationType rhs) + { + lhs = lhs | rhs; + return lhs; + } + + friend TranslationType operator^(const TranslationType lhs, const TranslationType rhs) + { + return static_cast( + static_cast>(lhs) ^ static_cast>(rhs)); + } + + friend TranslationType& operator^=(TranslationType& lhs, const TranslationType rhs) + { + lhs = lhs ^ rhs; + return lhs; + } + + friend TranslationType operator&(const TranslationType lhs, const TranslationType rhs) + { + return static_cast( + static_cast>(lhs) & static_cast>(rhs)); + } + + friend TranslationType& operator&=(TranslationType& lhs, const TranslationType rhs) + { + lhs = lhs & rhs; + return lhs; + } + + static TranslationType translationFromKey(InputChannelId channelId); + + TranslationType m_translation = TranslationType::Nil; + TranslationAxesFn m_translationAxesFn; + bool m_boost = false; + }; + + class OrbitDollyScrollCameraInput : public CameraInput + { + public: + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + + struct Props + { + float m_dollySpeed = 0.2f; + } m_props; + }; + + class OrbitDollyCursorMoveCameraInput : public CameraInput + { + public: + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + + struct Props + { + float m_dollySpeed = 0.1f; + } m_props; + }; + + class ScrollTranslationCameraInput : public CameraInput + { + public: + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + + struct Props + { + float m_translateSpeed = 0.2f; + } m_props; + }; + + class OrbitCameraInput : public CameraInput + { + public: + void HandleEvents(const InputEvent& event) override; + Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; + bool Exclusive() const override + { + return true; + } + + Cameras m_orbitCameras; + + struct Props + { + float m_defaultOrbitDistance = 15.0f; + float m_maxOrbitDistance = 100.0f; + } m_props; + }; + + InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize); +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ViewportControllerInterface.h b/Code/Framework/AzFramework/AzFramework/Viewport/ViewportControllerInterface.h index 9bb4cdf3d5..8955a1df29 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/ViewportControllerInterface.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ViewportControllerInterface.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include #include @@ -60,17 +61,18 @@ namespace AzFramework { //! The viewport ID this event was dispatched to. ViewportId m_viewportId; + //! The native window handle for the application. + NativeWindowHandle m_windowHandle; //! The input channel data for this event. const AzFramework::InputChannel& m_inputChannel; //! The priority this event was dispatched at. ViewportControllerPriority m_priority; ViewportControllerInputEvent( - ViewportId viewportId, - const AzFramework::InputChannel& inputChannel, - ViewportControllerPriority priority = ViewportControllerPriority::DispatchToAllPriorities - ) + ViewportId viewportId, NativeWindowHandle windowHandle, const AzFramework::InputChannel& inputChannel, + ViewportControllerPriority priority = ViewportControllerPriority::DispatchToAllPriorities) : m_viewportId(viewportId) + , m_windowHandle(windowHandle) , m_inputChannel(inputChannel) , m_priority(priority) { diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index 5ec9ddacee..b37c1b259f 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -102,6 +102,8 @@ set(FILES Viewport/ScreenGeometry.cpp Viewport/CameraState.h Viewport/CameraState.cpp + Viewport/CameraInput.h + Viewport/CameraInput.cpp Viewport/DisplayContextRequestBus.h Entity/BehaviorEntity.cpp Entity/BehaviorEntity.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h index 6fdcd7eb59..c2ddbcf24f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h @@ -43,14 +43,12 @@ namespace AzToolsFramework const PrefabDom& modifiedState, const LinkId linkId) = 0; //! Updates the affected template for a given entityId using the providedPatch - virtual bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) = 0; - - virtual bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) = 0; + virtual bool PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) = 0; virtual void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) = 0; //! Updates the template links (updating instances) for the given templateId using the providedPatch - virtual void PatchTemplate(PrefabDomValue& providedPatch, const TemplateId& templateId) = 0; + virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) = 0; virtual void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index 9501b7e5a2..b1c5f64ef9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -107,7 +107,7 @@ namespace AzToolsFramework return result.GetProcessing() != AZ::JsonSerializationResult::Processing::Halted; } - bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) + bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) { InstanceOptionalReference instanceOptionalReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId); @@ -119,53 +119,10 @@ namespace AzToolsFramework return false; } - //get template space associated with instance - Instance& instance = instanceOptionalReference->get(); - TemplateId templateId = instance.GetTemplateId(); - - //alias entity goes by in template -> get via owning instance map - AZStd::optional entityAlias = instance.GetEntityAlias(entityId); - - if (!entityAlias) - { - AZ_Error("Prefab", false, "Failed to find an entity alias for the provided entity"); - return false; - } - - - return PatchEntityInTemplate(providedPatch, entityAlias.value(), templateId); - } - - bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) - { - PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId); - - //query into the template dom for the alias - PrefabDomValueReference entityList = PrefabDomUtils::FindPrefabDomValue(templateDomReference, PrefabDomUtils::EntitiesName); - - if (!entityList) - { - AZ_Error("Prefab", false, "Cannot patch entity in Template with id [%llu] because entity couldn't be found in the template", templateId); - return false; - } - - PrefabDomValueReference entity = PrefabDomUtils::FindPrefabDomValue(entityList->get(), entityAlias.c_str()); - - if (!entity) - { - AZ_Error("Prefab", false, "Failed to aquire entity value reference"); - return false; - } - - //apply patch to section - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(entity->get(), - templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch); - - AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, "Patch was not successfully applied") - - //trigger propagation - m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId); - return true; + //get template id associated with instance + TemplateId templateId = instanceOptionalReference->get().GetTemplateId(); + AppendEntityAliasToPatchPaths(providedPatch, entityId); + return PatchTemplate(providedPatch, templateId); } void InstanceToTemplatePropagator::AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) @@ -215,7 +172,7 @@ namespace AzToolsFramework } } - void InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, const TemplateId& templateId) + bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) { PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId); @@ -223,14 +180,17 @@ namespace AzToolsFramework AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference, templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch); - AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, - "Patch was not successfully applied"); - //trigger propagation if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success) { m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true); m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId); + return true; + } + else + { + AZ_Error("Prefab", false, "Patch was not successfully applied"); + return false; } } @@ -287,6 +247,8 @@ namespace AzToolsFramework AddPatchesToLink(patches, linkToApplyPatches); linkToApplyPatches.UpdateTarget(); + + m_prefabSystemComponentInterface->SetTemplateDirtyFlag(linkToApplyPatches.GetTargetTemplateId(), true); m_prefabSystemComponentInterface->PropagateTemplateChanges(linkToApplyPatches.GetTargetTemplateId()); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h index c094d6be3b..ca1f3a7c91 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h @@ -31,21 +31,19 @@ namespace AzToolsFramework bool GeneratePatch(PrefabDom& generatedPatch, const PrefabDom& initialState, const PrefabDom& modifiedState) override; bool GeneratePatchForLink(PrefabDom& generatedPatch, const PrefabDom& initialState, const PrefabDom& modifiedState, LinkId linkId) override; - bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) override; - bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) override; + bool PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) override; void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) override; InstanceOptionalReference GetTopMostInstanceInHierarchy(AZ::EntityId entityId); - void PatchTemplate(PrefabDomValue& providedPatch, const AzToolsFramework::Prefab::TemplateId& templateId) override; + bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) override; void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override; void AddPatchesToLink(PrefabDom& patches, Link& link); private: - InstanceEntityMapperInterface* m_instanceEntityMapperInterface; PrefabSystemComponentInterface* m_prefabSystemComponentInterface; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index f8f018f2f7..979d85151a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -127,12 +127,12 @@ namespace AzToolsFramework InstanceEntityScrubber instanceEntityScrubber(newlyAddedEntities); settings.m_metadata.Add(&instanceEntityScrubber); - AZ::JsonSerializationResult::ResultCode result = - AZ::JsonSerialization::Load(instance, prefabDom, settings); + AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Load(instance, prefabDom, settings); if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted) { - AZ_Error("Prefab", false, + AZ_Error( + "Prefab", false, "Failed to de-serialize Prefab Instance from Prefab DOM. " "Unable to proceed."); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp index f0d30dd106..7b4761c39a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp @@ -348,8 +348,7 @@ namespace AzToolsFramework "Prefab", false, "PrefabLoader::SaveTemplate - Unable to save Prefab Template with id: %llu. " "Template with that id is invalid", - templateId - ); + templateId); return AZStd::nullopt; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index 2fb428c4df..0d9f9f72a5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -79,13 +79,16 @@ namespace AzToolsFramework //generate undo/redo patches m_instanceToTemplateInterface->GeneratePatch(m_redoPatch, initialState, endState); + m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(m_redoPatch, entityId); m_instanceToTemplateInterface->GeneratePatch(m_undoPatch, endState, initialState); + m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(m_undoPatch, entityId); } void PrefabUndoEntityUpdate::Undo() { [[maybe_unused]] bool isPatchApplicationSuccessful = - m_instanceToTemplateInterface->PatchEntityInTemplate(m_undoPatch, m_entityAlias, m_templateId); + m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId); + AZ_Error( "Prefab", isPatchApplicationSuccessful, "Applying the undo patch on the entity with alias '%s' in template with id '%llu' was unsuccessful", m_entityAlias.c_str(), @@ -95,7 +98,8 @@ namespace AzToolsFramework void PrefabUndoEntityUpdate::Redo() { [[maybe_unused]] bool isPatchApplicationSuccessful = - m_instanceToTemplateInterface->PatchEntityInTemplate(m_redoPatch, m_entityAlias, m_templateId); + m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId); + AZ_Error( "Prefab", isPatchApplicationSuccessful, "Applying the redo patch on the entity with alias '%s' in template with id '%llu' was unsuccessful", m_entityAlias.c_str(), diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index 3fd0b6b0bb..7aaa26c01b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -21,7 +21,12 @@ #include #include -class QPoint; +class QPoint; // LYN-2315 in-progress, remove this + +namespace AzFramework +{ + struct ScreenPoint; +} namespace AzToolsFramework { @@ -235,12 +240,12 @@ namespace AzToolsFramework /// Restores the cursor and ends locking it in place, allowing it to be moved freely. virtual void EndCursorCapture() = 0; /// Gets the most recent recorded cursor position in the viewport in screen space coordinates. - virtual QPoint ViewportCursorScreenPosition() = 0; + virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0; /// Gets the cursor position recorded prior to the most recent cursor position. /// Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result /// from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse /// position delta. - virtual AZStd::optional PreviousViewportCursorScreenPosition() = 0; + virtual AZStd::optional PreviousViewportCursorScreenPosition() = 0; protected: ~ViewportMouseCursorRequests() = default; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h index 8893fa3636..250adc5b86 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h @@ -202,12 +202,18 @@ namespace AzToolsFramework return mouseInteractionEvent.m_wheelDelta; } - /// Return Qt QPoint from an Viewport ScreenPoint. + /// Return QPoint from AzFramework::ScreenPoint. inline QPoint QPointFromScreenPoint(const AzFramework::ScreenPoint& screenPoint) { return {screenPoint.m_x, screenPoint.m_y}; } + /// Return AzFramework::ScreenPoint from QPoint. + inline AzFramework::ScreenPoint ScreenPointFromQPoint(const QPoint& qpoint) + { + return AzFramework::ScreenPoint{qpoint.x(), qpoint.y()}; + } + /// Map from Qt -> Lumberyard buttons. inline AZ::u32 TranslateMouseButtons(const Qt::MouseButtons buttons) { diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp index 94dcfe59f6..b71b5b0c23 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp @@ -75,7 +75,7 @@ namespace UnitTest EntityAlias entityAlias = entityAliasRef.value(); //update template - ASSERT_TRUE(m_instanceToTemplateInterface->PatchEntityInTemplate(patch, entityAlias, templateId)); + ASSERT_TRUE(m_instanceToTemplateInterface->PatchEntityInTemplate(patch, entityId)); //undo change instanceEntityUndo.Undo(); diff --git a/Code/LauncherUnified/Platform/iOS/platform_ios.cmake b/Code/LauncherUnified/Platform/iOS/platform_ios.cmake index d026056e3d..a30ab76949 100644 --- a/Code/LauncherUnified/Platform/iOS/platform_ios.cmake +++ b/Code/LauncherUnified/Platform/iOS/platform_ios.cmake @@ -12,5 +12,5 @@ set(LY_BUILD_DEPENDENCIES PUBLIC - 3rdParty::FreeType2 + 3rdParty::freetype ) diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index 853e28db0c..1be7411f8a 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -76,6 +76,7 @@ #include "EditorPreferencesPageGeneral.h" #include "ViewportManipulatorController.h" #include "LegacyViewportCameraController.h" +#include "ModernViewportCameraController.h" #include "ViewPane.h" #include "CustomResolutionDlg.h" @@ -92,6 +93,7 @@ // Atom #include #include +#include #include #include @@ -106,6 +108,10 @@ void StartFixedCursorMode(QObject *viewport); #define RENDER_MESH_TEST_DISTANCE (0.2f) #define CURSOR_FONT_HEIGHT 8.0f +AZ_CVAR( + bool, ed_useNewCameraSystem, false, nullptr, AZ::ConsoleFunctorFlags::Null, + "Use the new Editor camera system (the Atom-native Editor viewport (experimental) must also be enabled)"); + namespace AZ::ViewportHelpers { static const char TextCantCreateCameraNoLevel[] = "Cannot create camera when no level is loaded."; @@ -1236,7 +1242,16 @@ void EditorViewportWidget::SetViewportId(int id) viewportContext->ConnectProjectionMatrixChangedHandler(m_cameraProjectionMatrixChangeHandler); m_renderViewport->GetControllerList()->Add(AZStd::make_shared()); - m_renderViewport->GetControllerList()->Add(AZStd::make_shared()); + + if (ed_useNewCameraSystem) + { + m_renderViewport->GetControllerList()->Add(AZStd::make_shared()); + } + else + { + m_renderViewport->GetControllerList()->Add(AZStd::make_shared()); + } + UpdateScene(); } diff --git a/Code/Sandbox/Editor/LegacyViewportCameraController.cpp b/Code/Sandbox/Editor/LegacyViewportCameraController.cpp index 1ff0838712..0c34706e24 100644 --- a/Code/Sandbox/Editor/LegacyViewportCameraController.cpp +++ b/Code/Sandbox/Editor/LegacyViewportCameraController.cpp @@ -11,8 +11,10 @@ */ #include "LegacyViewportCameraController.h" + #include #include +#include #include #include #include @@ -73,7 +75,8 @@ AZ::RPI::ViewportContextPtr LegacyViewportCameraControllerInstance::GetViewportC return viewportContextManager->GetViewportContextById(GetViewportId()); } -bool LegacyViewportCameraControllerInstance::HandleMouseMove(const QPoint& currentMousePos, const QPoint& previousMousePos) +bool LegacyViewportCameraControllerInstance::HandleMouseMove( + const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos) { if (previousMousePos == currentMousePos) { @@ -100,7 +103,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(const QPoint& curre Vec3 ydir = m.GetColumn1().GetNormalized(); Vec3 pos = m.GetTranslation(); - const float posDelta = 0.2f * (previousMousePos.y() - currentMousePos.y()) * speedScale; + const float posDelta = 0.2f * (previousMousePos.m_y - currentMousePos.m_y) * speedScale; pos = pos - ydir * posDelta; m_orbitDistance = m_orbitDistance + posDelta; m_orbitDistance = fabs(m_orbitDistance); @@ -111,7 +114,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(const QPoint& curre } else if (m_inRotateMode) { - Ang3 angles(-currentMousePos.y() + previousMousePos.y(), 0, -currentMousePos.x() + previousMousePos.x()); + Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x); angles = angles * 0.002f * gSettings.cameraRotateSpeed; if (gSettings.invertYRotation) { @@ -143,7 +146,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(const QPoint& curre } Vec3 pos = m.GetTranslation(); - pos += 0.1f * xdir * (currentMousePos.x() - previousMousePos.x()) * speedScale + 0.1f * zdir * (previousMousePos.y() - currentMousePos.y()) * speedScale; + pos += 0.1f * xdir * (currentMousePos.m_x - previousMousePos.m_x) * speedScale + 0.1f * zdir * (previousMousePos.m_y - currentMousePos.m_y) * speedScale; m.SetTranslation(pos); AZ::Transform transform = viewportContext->GetCameraTransform(); @@ -153,7 +156,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(const QPoint& curre } else if (m_inOrbitMode) { - Ang3 angles(-currentMousePos.y() + previousMousePos.y(), 0, -currentMousePos.x() + previousMousePos.x()); + Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x); angles = angles * 0.002f * gSettings.cameraRotateSpeed; if (gSettings.invertPan) @@ -289,14 +292,13 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra if (id == AzFramework::InputDeviceMouse::SystemCursorPosition) { - QPoint screenPosition = QPoint(); bool result = false; AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Event( GetViewportId(), [this, &result](AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequests* mouseRequests) { - auto previousMousePosition = mouseRequests->PreviousViewportCursorScreenPosition(); - if (previousMousePosition.has_value()) + if (auto previousMousePosition = mouseRequests->PreviousViewportCursorScreenPosition(); + previousMousePosition.has_value()) { result = HandleMouseMove(mouseRequests->ViewportCursorScreenPosition(), previousMousePosition.value()); } diff --git a/Code/Sandbox/Editor/LegacyViewportCameraController.h b/Code/Sandbox/Editor/LegacyViewportCameraController.h index 9e2f1e6dc8..3f211f49b7 100644 --- a/Code/Sandbox/Editor/LegacyViewportCameraController.h +++ b/Code/Sandbox/Editor/LegacyViewportCameraController.h @@ -21,6 +21,11 @@ #include #include +namespace AzFramework +{ + struct ScreenPoint; +} + namespace SandboxEditor { class LegacyViewportCameraControllerInstance final @@ -45,7 +50,7 @@ namespace SandboxEditor AZ::RPI::ViewportContextPtr GetViewportContext(); - bool HandleMouseMove(const QPoint& currentMousePos, const QPoint& previousMousePos); + bool HandleMouseMove(const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos); bool HandleMouseWheel(float zDelta); bool IsKeyDown(Qt::Key key) const; diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.cpp b/Code/Sandbox/Editor/ModernViewportCameraController.cpp new file mode 100644 index 0000000000..80bd9416f7 --- /dev/null +++ b/Code/Sandbox/Editor/ModernViewportCameraController.cpp @@ -0,0 +1,97 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include "ModernViewportCameraController.h" + +#include +#include +#include +#include +#include + +namespace SandboxEditor +{ + static AZ::RPI::ViewportContextPtr RetrieveViewportContext(const AzFramework::ViewportId viewportId) + { + auto viewportContextManager = AZ::Interface::Get(); + if (!viewportContextManager) + { + return nullptr; + } + + auto viewportContext = viewportContextManager->GetViewportContextById(viewportId); + if (!viewportContext) + { + return nullptr; + } + + return viewportContext; + } + + ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance(const AzFramework::ViewportId viewportId) + : MultiViewportControllerInstanceInterface(viewportId) + { + // LYN-2315 TODO - move setup out of constructor, pass cameras in + auto firstPersonRotateCamera = AZStd::make_shared(AzFramework::InputDeviceMouse::Button::Right); + auto firstPersonPanCamera = AZStd::make_shared(AzFramework::LookPan); + auto firstPersonTranslateCamera = AZStd::make_shared(AzFramework::LookTranslation); + auto firstPersonWheelCamera = AZStd::make_shared(); + + auto orbitCamera = AZStd::make_shared(); + auto orbitRotateCamera = AZStd::make_shared(AzFramework::InputDeviceMouse::Button::Left); + auto orbitTranslateCamera = AZStd::make_shared(AzFramework::OrbitTranslation); + auto orbitDollyWheelCamera = AZStd::make_shared(); + auto orbitDollyMoveCamera = AZStd::make_shared(); + auto orbitPanCamera = AZStd::make_shared(AzFramework::OrbitPan); + orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera); + orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera); + orbitCamera->m_orbitCameras.AddCamera(orbitDollyWheelCamera); + orbitCamera->m_orbitCameras.AddCamera(orbitDollyMoveCamera); + orbitCamera->m_orbitCameras.AddCamera(orbitPanCamera); + + m_cameraSystem.m_cameras.AddCamera(firstPersonRotateCamera); + m_cameraSystem.m_cameras.AddCamera(firstPersonPanCamera); + m_cameraSystem.m_cameras.AddCamera(firstPersonTranslateCamera); + m_cameraSystem.m_cameras.AddCamera(firstPersonWheelCamera); + m_cameraSystem.m_cameras.AddCamera(orbitCamera); + + if (const auto viewportContext = RetrieveViewportContext(viewportId)) + { + // set position but not orientation + m_targetCamera.m_lookAt = viewportContext->GetCameraTransform().GetTranslation(); + + // LYN-2315 TODO https://www.geometrictools.com/Documentation/EulerAngles.pdf + + m_camera = m_targetCamera; + } + } + + bool ModernViewportCameraControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) + { + AzFramework::WindowSize windowSize; + AzFramework::WindowRequestBus::EventResult( + windowSize, event.m_windowHandle, &AzFramework::WindowRequestBus::Events::GetClientAreaSize); + m_cameraSystem.HandleEvents(AzFramework::BuildInputEvent(event.m_inputChannel, windowSize)); + return true; // consume event + } + + void ModernViewportCameraControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) + { + if (auto viewportContext = RetrieveViewportContext(GetViewportId())) + { + m_targetCamera = m_cameraSystem.StepCamera(m_targetCamera, event.m_deltaTime.count()); + m_camera = AzFramework::SmoothCamera(m_camera, m_targetCamera, m_smoothProps, event.m_deltaTime.count()); + + viewportContext->SetCameraTransform(m_camera.Transform()); + } + } +} // namespace SandboxEditor diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.h b/Code/Sandbox/Editor/ModernViewportCameraController.h new file mode 100644 index 0000000000..c65dbc8b8a --- /dev/null +++ b/Code/Sandbox/Editor/ModernViewportCameraController.h @@ -0,0 +1,37 @@ +/* + * 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 +#include + +namespace SandboxEditor +{ + class ModernViewportCameraControllerInstance final : public AzFramework::MultiViewportControllerInstanceInterface + { + public: + explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId); + + // MultiViewportControllerInstanceInterface overrides ... + bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override; + void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override; + + private: + AzFramework::Camera m_camera; + AzFramework::Camera m_targetCamera; + AzFramework::SmoothProps m_smoothProps; + AzFramework::CameraSystem m_cameraSystem; + }; + + using ModernViewportCameraController = AzFramework::MultiViewportController; +} // namespace SandboxEditor diff --git a/Code/Sandbox/Editor/Util/ImageTIF.cpp b/Code/Sandbox/Editor/Util/ImageTIF.cpp index 114a72d619..0182d9654b 100644 --- a/Code/Sandbox/Editor/Util/ImageTIF.cpp +++ b/Code/Sandbox/Editor/Util/ImageTIF.cpp @@ -16,7 +16,7 @@ #include "ImageTIF.h" /// libTiff -#include // TIFF library +#include // TIFF library // Function prototypes static tsize_t libtiffDummyReadProc (thandle_t fd, tdata_t buf, tsize_t size); diff --git a/Code/Sandbox/Editor/ViewportManipulatorController.cpp b/Code/Sandbox/Editor/ViewportManipulatorController.cpp index 748fb81e6b..fd8ed4dfbf 100644 --- a/Code/Sandbox/Editor/ViewportManipulatorController.cpp +++ b/Code/Sandbox/Editor/ViewportManipulatorController.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -99,18 +100,16 @@ bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFram // Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after if (event.m_priority == ManipulatorPriority) { - QPoint screenPosition = QPoint(); + AzFramework::ScreenPoint screenPosition = AzFramework::ScreenPoint(0, 0); ViewportMouseCursorRequestBus::EventResult( - screenPosition, GetViewportId(), - &ViewportMouseCursorRequestBus::Events::ViewportCursorScreenPosition - ); - m_state.m_mousePick.m_screenCoordinates = AzFramework::ScreenPoint{screenPosition.x(), screenPosition.y()}; + screenPosition, GetViewportId(), &ViewportMouseCursorRequestBus::Events::ViewportCursorScreenPosition); + + m_state.m_mousePick.m_screenCoordinates = screenPosition; AZStd::optional ray; ViewportInteractionRequestBus::EventResult( - ray, GetViewportId(), - &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, - screenPosition - ); + ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, + QPoint(screenPosition.m_x, screenPosition.m_y)); + if (ray.has_value()) { m_state.m_mousePick.m_rayOrigin = ray.value().origin; diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index db39733434..9084a566ae 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -996,6 +996,8 @@ set(FILES ViewportManipulatorController.h LegacyViewportCameraController.cpp LegacyViewportCameraController.h + ModernViewportCameraController.cpp + ModernViewportCameraController.h RenderViewport.cpp RenderViewport.h TopRendererWnd.cpp diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp b/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp index 6cc75d7d2c..5ca6cf5ac6 100644 --- a/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp +++ b/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp @@ -41,6 +41,65 @@ #include +// Class to implement the WindowRequestBus::Handler instead of the QViewport class. +// This is to bypass a link warning that occurs in unity builds if EditorCommon dll +// is linked along with a gem that also implements WindowRequestBus::Handler. The +// issue is that QViewport has a dllexport so it causes duplicate code to be linked +// in and a warning that there will be two of the same symbol in memory +class QViewportRequests + : public AzFramework::WindowRequestBus::Handler +{ +public: + QViewportRequests(QViewport& viewport) + : m_viewport(viewport) + { + } + + ~QViewportRequests() override + { + AzFramework::WindowRequestBus::Handler::BusDisconnect(); + } + + // WindowRequestBus::Handler... + void SetWindowTitle(const AZStd::string& title) override + { + m_viewport.SetWindowTitle(title); + } + + AzFramework::WindowSize GetClientAreaSize() const override + { + return m_viewport.GetClientAreaSize(); + } + + void ResizeClientArea(AzFramework::WindowSize clientAreaSize) override + { + m_viewport.ResizeClientArea(clientAreaSize); + } + + bool GetFullScreenState() const override + { + return m_viewport.GetFullScreenState(); + } + + void SetFullScreenState(bool fullScreenState) override + { + m_viewport.SetFullScreenState(fullScreenState); + } + + bool CanToggleFullScreenState() const override + { + return m_viewport.CanToggleFullScreenState(); + } + + void ToggleFullScreenState() override + { + m_viewport.ToggleFullScreenState(); + } + +private: + QViewport& m_viewport; +}; + struct QViewport::SPreviousContext { CCamera renderCamera; @@ -188,6 +247,8 @@ QViewport::QViewport(QWidget* parent, StartupMode startupMode) , m_private(new SPrivate()) , m_cameraControlMode(CameraControlMode::NONE) { + m_viewportRequests = AZStd::make_unique(*this); + if (startupMode & StartupMode_Immediate) Startup(); } @@ -213,6 +274,8 @@ void QViewport::Startup() QViewport::~QViewport() { DestroyRenderContext(); + + m_viewportRequests.reset(); } void QViewport::UpdateBackgroundColor() @@ -316,7 +379,7 @@ bool QViewport::CreateRenderContext() if (AZ::Interface::Get()) { - AzFramework::WindowRequestBus::Handler::BusConnect(windowHandle); + m_viewportRequests.get()->BusConnect(windowHandle); AzFramework::WindowSystemNotificationBus::Broadcast(&AzFramework::WindowSystemNotificationBus::Handler::OnWindowCreated, windowHandle); m_lastHwnd = windowHandle; @@ -346,7 +409,7 @@ void QViewport::DestroyRenderContext() m_renderContextCreated = false; AzFramework::WindowNotificationBus::Event(windowHandle, &AzFramework::WindowNotificationBus::Handler::OnWindowClosed); - AzFramework::WindowRequestBus::Handler::BusDisconnect(); + m_viewportRequests.get()->BusDisconnect(); m_lastHwnd = 0; } } diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewport.h b/Code/Sandbox/Plugins/EditorCommon/QViewport.h index 0a1c247439..2b18724d01 100644 --- a/Code/Sandbox/Plugins/EditorCommon/QViewport.h +++ b/Code/Sandbox/Plugins/EditorCommon/QViewport.h @@ -41,6 +41,7 @@ struct SMouseEvent; struct SViewportSettings; struct SViewportState; class QElapsedTimer; +class QViewportRequests; class EDITOR_COMMON_API QViewport; struct SRenderContext @@ -66,7 +67,6 @@ AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING class EDITOR_COMMON_API QViewport : public QWidget - , public AzFramework::WindowRequestBus::Handler { Q_OBJECT AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING @@ -107,14 +107,14 @@ public: void SetSize(const QSize& size); void GetImageOffscreen(CImageEx& image, const QSize& customSize); - // WindowRequestBus::Handler... - void SetWindowTitle(const AZStd::string& title) override; - AzFramework::WindowSize GetClientAreaSize() const override; - void ResizeClientArea(AzFramework::WindowSize clientAreaSize) override; - bool GetFullScreenState() const override; - void SetFullScreenState(bool fullScreenState) override; - bool CanToggleFullScreenState() const override; - void ToggleFullScreenState() override; + // WindowRequestBus::Handler... (handler moved to cpp to resolve link issues in unity builds) + void SetWindowTitle(const AZStd::string& title); + AzFramework::WindowSize GetClientAreaSize() const; + void ResizeClientArea(AzFramework::WindowSize clientAreaSize); + bool GetFullScreenState() const; + void SetFullScreenState(bool fullScreenState); + bool CanToggleFullScreenState() const; + void ToggleFullScreenState(); public slots: void Update(); @@ -197,6 +197,7 @@ private: std::unique_ptr m_settings; std::unique_ptr m_state; std::vector m_consumers; + AZStd::unique_ptr m_viewportRequests; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING HWND m_lastHwnd = 0; bool m_resizeWindowEvent = false; diff --git a/Code/Tools/CrySCompileServer/CrySCompileServer/Core/Server/CrySimpleJob.cpp b/Code/Tools/CrySCompileServer/CrySCompileServer/Core/Server/CrySimpleJob.cpp index b3530290ca..1e7423dc69 100644 --- a/Code/Tools/CrySCompileServer/CrySCompileServer/Core/Server/CrySimpleJob.cpp +++ b/Code/Tools/CrySCompileServer/CrySCompileServer/Core/Server/CrySimpleJob.cpp @@ -170,7 +170,9 @@ bool CCrySimpleJob::ExecuteCommand(const std::string& rCmd, std::string& outErro threadIdStream << threadId; // Multiple threads could execute a command, therefore the temporary file has to be unique per thread. - std::string stdErrorTempFilename = SEnviropment::Instance().m_TempPath + "stderr_" + threadIdStream.str() + ".log"; + AZ::IO::Path errorTempFilePath = SEnviropment::Instance().m_TempPath / AZStd::string::format("stderr_%s.log", threadIdStream.str().c_str()); + std::string stdErrorTempFilename{ errorTempFilePath.c_str(), errorTempFilePath.Native().size() }; + CCrySimpleFileGuard FGTmpOutput(stdErrorTempFilename); // Delete file at the end of this function std::string systemCmd = rCmd; diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h index 3f7ad20bf1..3f68ac09cf 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h @@ -105,7 +105,7 @@ namespace ImageProcessingAtom { } - explicit ColorRGBA16(uint64 a_u) + explicit ColorRGBA16(AZ::u64 a_u) : u(a_u) { } @@ -152,7 +152,7 @@ namespace ImageProcessingAtom uint16 b; uint16 a; }; - uint64 u; + AZ::u64 u; }; }; diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/PVRTC.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/PVRTC.cpp index 34b3ae184a..67c7a7e27b 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/PVRTC.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Compressors/PVRTC.cpp @@ -224,7 +224,7 @@ namespace ImageProcessingAtom srcImage->GetImagePointer(mip, srcMem, srcPitch); const pvrtexture::CPVRTextureHeader srcHeader( - srcPixelType.PixelTypeID, // uint64 u64PixelFormat, + srcPixelType.PixelTypeID, // AZ::u64 u64PixelFormat, width, // uint32 u32Height=1, height, // uint32 u32Width=1, 1, // uint32 u32Depth=1, @@ -315,7 +315,7 @@ namespace ImageProcessingAtom // Preparing source compressed data const pvrtexture::CPVRTextureHeader compressedHeader( - FindPvrPixelFormat(fmtSrc), // uint64 u64PixelFormat, + FindPvrPixelFormat(fmtSrc), // AZ::u64 u64PixelFormat, width, // uint32 u32Height=1, height, // uint32 u32Width=1, 1, // uint32 u32Depth=1, diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderBaseType.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderBaseType.h index ca2826fd57..6340620506 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderBaseType.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderBaseType.h @@ -25,9 +25,5 @@ typedef AZ::s32 int32; typedef AZ::s32 sint32; typedef AZ::u32 uint32; -typedef AZ::s64 int64; -typedef AZ::s64 sint64; -typedef AZ::u64 uint64; - typedef float f32; typedef double f64; diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageLoader/TIFFLoader.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageLoader/TIFFLoader.cpp index ed9c5fac43..9b7c9b6c65 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageLoader/TIFFLoader.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageLoader/TIFFLoader.cpp @@ -20,7 +20,7 @@ #include -#include // TIFF library +#include // TIFF library namespace ImageProcessingAtom { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli index d72032dbaf..fd6961c50d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli @@ -106,4 +106,4 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial float GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy) { return SampleDepthOrHeightMap(MaterialSrg::m_depthInverted, MaterialSrg::m_depthMap, MaterialSrg::m_sampler, uv, uv_ddx, uv_ddy); -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index ff8b4b7778..a9d6f243c1 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -69,6 +69,7 @@ struct VSOutput #include #include +#include VSOutput EnhancedPbr_ForwardPassVS(VSInput IN) { @@ -88,7 +89,7 @@ VSOutput EnhancedPbr_ForwardPassVS(VSInput IN) OUT.m_detailUv[0] = mul(MaterialSrg::m_detailUvMatrix, float3(IN.m_uv0, 1.0)).xy; OUT.m_detailUv[1] = mul(MaterialSrg::m_detailUvMatrix, float3(IN.m_uv1, 1.0)).xy; - PbrVsHelper(IN, OUT, worldPosition, o_parallax_feature_enabled && o_parallax_enablePixelDepthOffset); + VertexHelper(IN, OUT, worldPosition, o_parallax_feature_enabled && o_parallax_enablePixelDepthOffset); return OUT; } @@ -248,7 +249,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // Convert the angle from [0..1] = [0 .. 180 degrees] to radians [0 .. PI] const float2 anisotropy = float2(MaterialSrg::m_anisotropicAngle * PI, MaterialSrg::m_anisotropicFactor); - PbrLightingOutput lightingOutput = PbrLighting(IN, baseColor, metallic, roughness, specularF0Factor, + 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); diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatInput.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatInput.azsli index 092a44278d..9bea6abc9d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatInput.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatInput.azsli @@ -57,7 +57,7 @@ void GetClearCoatInputs(Texture2D influenceMap, float2 influenceUV, float clearC if (useNormalMap) { float4 sampledValue = normalMap.Sample(mapSampler, normalUV); - clearCoatNormal = GetWorldSpaceNormal(sampledValue, normal, tangent, bitangent, uvMatrix, normalStrength); + clearCoatNormal = GetWorldSpaceNormal(sampledValue.xy, normal, tangent, bitangent, uvMatrix, normalStrength); } else { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl index aa8ae3a010..dc79a94007 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl @@ -91,6 +91,7 @@ struct VSOutput #include // TODO: Remove this after OpacityMode is removed from LightingModel #include +#include VSOutput SkinVS(VSInput IN) { @@ -125,7 +126,7 @@ VSOutput SkinVS(VSInput IN) OUT.m_blendMask = float4(0,1,0,0); } - PbrVsHelper(IN, OUT, worldPosition, false); + VertexHelper(IN, OUT, worldPosition, false); return OUT; } diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index 04407adf7d..9e5c29ba34 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -85,6 +85,7 @@ struct VSOutput #include #include +#include VSOutput ForwardPassVS(VSInput IN) { @@ -109,7 +110,7 @@ VSOutput ForwardPassVS(VSInput IN) // We can skip per-vertex shadow coords when parallax is enabled because we need to calculate per-pixel shadow coords anyway. // We cannot skip shadow coords when o_debugDrawMode is on because some debug draw modes return before parallax. bool skipShadowCoords = o_debugDrawMode == DebugDrawMode::None && o_parallax_feature_enabled && o_parallax_enablePixelDepthOffset; - PbrVsHelper(IN, OUT, worldPosition, skipShadowCoords); + VertexHelper(IN, OUT, worldPosition, skipShadowCoords); return OUT; } @@ -346,7 +347,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float const float2 anisotropy = 0.0; // Does not affect calculations unless 'o_enableAnisotropy' is enabled - PbrLightingOutput lightingOutput = PbrLighting(IN, baseColor, metallic, roughness, specularF0Factor, + 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); diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index 22e3da4572..999db3c5da 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -68,18 +68,19 @@ struct VSOutput #include #include +#include VSOutput StandardPbr_ForwardPassVS(VSInput IN) { VSOutput OUT; - + float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz; // By design, only UV0 is allowed to apply transforms. OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy; OUT.m_uv[1] = IN.m_uv1; - PbrVsHelper(IN, OUT, worldPosition, o_parallax_feature_enabled && o_parallax_enablePixelDepthOffset); + VertexHelper(IN, OUT, worldPosition, o_parallax_feature_enabled && o_parallax_enablePixelDepthOffset); return OUT; } @@ -126,6 +127,10 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float } } + Surface surface; + surface.position = IN.m_worldPosition.xyz; + + // ------- Alpha & Clip ------- float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex]; @@ -137,7 +142,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float float2 normalUv = IN.m_uv[MaterialSrg::m_normalMapUvIndex]; float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms. - float3 normalWS = GetNormalInputWS(MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, isFrontFace, IN.m_normal, + surface.normal = GetNormalInputWS(MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, isFrontFace, IN.m_normal, tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], uvMatrix, o_normal_useTexture, MaterialSrg::m_normalFactor); // ------- Base Color ------- @@ -154,26 +159,19 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture); } - // ------- Roughness ------- - - float2 roughnessUv = IN.m_uv[MaterialSrg::m_roughnessMapUvIndex]; - float roughness = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor, - MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture); - // ------- Specular ------- float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex]; - float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); + float specularF0 = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture); - // ------- Emissive ------- + surface.SetAlbedoAndSpecularF0(baseColor, specularF0, metallic); - float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex]; - float3 emissive = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture); + // ------- Roughness ------- - // ------- 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); + float2 roughnessUv = IN.m_uv[MaterialSrg::m_roughnessMapUvIndex]; + surface.roughnessLinear = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor, + MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture); + surface.CalculateRoughnessA(); // ------- Subsurface ------- @@ -184,31 +182,99 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float float2 transmissionUv = IN.m_uv[MaterialSrg::m_transmissionThicknessMapUvIndex]; float4 transmissionTintThickness = GeTransmissionInput(MaterialSrg::m_transmissionThicknessMap, MaterialSrg::m_sampler, transmissionUv, MaterialSrg::m_transmissionTintThickness); + surface.transmission.tint = transmissionTintThickness.rgb; + surface.transmission.thickness = transmissionTintThickness.w; + surface.transmission.transmissionParams = MaterialSrg::m_transmissionParams; + + // ------- Anisotropy ------- + + if (o_enableAnisotropy) + { + const float anisotropyAngle = 0.0f; + const float anisotropyFactor = 0.0f; + surface.anisotropy.Init(surface.normal, tangents[0], bitangents[0], anisotropyAngle, anisotropyFactor, surface.roughnessA); + } + + // ------- Lighting Data ------- + + LightingData lightingData; + + // Light iterator + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); + + // Directional light shadow coordinates + lightingData.shadowCoords = IN.m_shadowCoords; + + // ------- Emissive ------- + + float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex]; + lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture); + + // ------- Occlusion ------- + + float2 occlusionUv = IN.m_uv[MaterialSrg::m_ambientOcclusionMapUvIndex]; + lightingData.occlusion = GetOcclusionInput(MaterialSrg::m_ambientOcclusionMap, MaterialSrg::m_sampler, occlusionUv, MaterialSrg::m_ambientOcclusionFactor, o_ambientOcclusion_useTexture); // ------- Clearcoat ------- - float clearCoatFactor = 0.0; - float clearCoatRoughness = 0.0; - float3 clearCoatNormal = float3(0.0, 0.0, 0.0); // [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags - if(o_clearCoat_enabled && o_clearCoat_feature_enabled) + if(o_clearCoat_feature_enabled) { - float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); - GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, IN.m_uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture, - MaterialSrg::m_clearCoatRoughnessMap, IN.m_uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture, - MaterialSrg::m_clearCoatNormalMap, IN.m_uv[MaterialSrg::m_clearCoatNormalMapUvIndex], IN.m_normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength, - uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex], - MaterialSrg::m_sampler, isFrontFace, - clearCoatFactor, clearCoatRoughness, clearCoatNormal); + if(o_clearCoat_enabled) + { + float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); + GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, IN.m_uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture, + MaterialSrg::m_clearCoatRoughnessMap, IN.m_uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture, + MaterialSrg::m_clearCoatNormalMap, IN.m_uv[MaterialSrg::m_clearCoatNormalMapUvIndex], IN.m_normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength, + uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex], + MaterialSrg::m_sampler, isFrontFace, + surface.clearCoat.factor, surface.clearCoat.roughness, surface.clearCoat.normal); + } + + // manipulate base layer f0 if clear coat is enabled + // modify base layer's normal incidence reflectance + // for the derivation of the following equation please refer to: + // https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification + float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0)); + surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor); } + + // Diffuse and Specular response (used in IBL calculations) + lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); + lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; + + if(o_clearCoat_feature_enabled) + { + // Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04 + lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor); + } + + // Multiscatter compensation factor + lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation); + // ------- Lighting Calculation ------- - const float2 anisotropy = 0.0; // Does not affect calculations unless 'o_enableAnisotropy' is enabled + // Apply Decals + ApplyDecals(lightingData.tileIterator, surface); - 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); + // Apply Direct Lighting + ApplyDirectLighting(surface, lightingData); + + // Apply Image Based Lighting (IBL) + ApplyIBL(surface, lightingData); + + // Finalize Lighting + lightingData.FinalizeLighting(surface.transmission.tint); + + + if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) + { + alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. + } + + PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); // ------- Opacity ------- diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.shader b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.shader index 00f22643d7..ce444d9222 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.shader +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.shader @@ -30,6 +30,7 @@ } }, + "CompilerHints" : { "DisableOptimizations" : false }, diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli index be88527461..2df17a41a9 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli @@ -1,5 +1,6 @@ #pragma once +#include #include // Analytical integation (approximation) of diffusion profile over radius, could be replaced by other pre integrated kernels @@ -10,29 +11,36 @@ float3 TransmissionKernel(float t, float3 s) return 0.25 * (1.0 / exp(exponent) + 3.0 / exp(exponent / 3.0)); } -float3 GetBackLighting(Surface surface, float3 lightIntensity, float3 dirToCamera, float3 dirToLight, float shadowRatio) +float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight, float shadowRatio) { float3 result = float3(0.0, 0.0, 0.0); float thickness = 0.0; + float4 transmissionParams = surface.transmission.transmissionParams; switch(o_transmission_mode) { case TransmissionMode::None: break; - // Thick object mode, using back lighting approximation proposed by Brisebois B. C. and Bouchard M. 2011 - // https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ + case TransmissionMode::ThickObject: - thickness = max(shadowRatio, surface.thickness); - // (transmittance) * (Lambert's attenuation) * light intensity - result = (pow(saturate(dot(dirToCamera, -normalize(dirToLight + surface.normal * surface.transmissionParams.z))), surface.transmissionParams.y) * surface.transmissionParams.w) * - (exp(-thickness * surface.transmissionParams.x) * saturate(1.0 - thickness)) * - lightIntensity; + // Thick object mode, using back lighting approximation proposed by Brisebois B. C. and Bouchard M. 2011 + // https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ + + { + thickness = max(shadowRatio, surface.transmission.thickness); + float transmittance = pow( saturate( dot( lightingData.dirToCamera, -normalize( dirToLight + surface.normal * transmissionParams.z ) ) ), transmissionParams.y ) * transmissionParams.w; + float lamberAttenuation = exp(-thickness * transmissionParams.x) * saturate(1.0 - thickness); + result = transmittance * lamberAttenuation * lightIntensity; + } break; - // Thin object mode, using thin-film assumption proposed by Jimenez J. et al, 2010, "Real-Time Realistic Skin Translucency" - // http://www.iryoku.com/translucency/downloads/Real-Time-Realistic-Skin-Translucency.pdf + case TransmissionMode::ThinObject: - result = shadowRatio ? float3(0.0, 0.0, 0.0) : TransmissionKernel(surface.thickness * surface.transmissionParams.w, rcp(surface.transmissionParams.xyz)) * + // Thin object mode, using thin-film assumption proposed by Jimenez J. et al, 2010, "Real-Time Realistic Skin Translucency" + // http://www.iryoku.com/translucency/downloads/Real-Time-Realistic-Skin-Translucency.pdf + + result = shadowRatio ? float3(0.0, 0.0, 0.0) : TransmissionKernel(surface.transmission.thickness * transmissionParams.w, rcp(transmissionParams.xyz)) * saturate(dot(-surface.normal, dirToLight)) * lightIntensity * shadowRatio; + break; } return result; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli new file mode 100644 index 0000000000..507f613455 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli @@ -0,0 +1,14 @@ +/* +* 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 + diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli new file mode 100644 index 0000000000..aa5fa05bcf --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli @@ -0,0 +1,89 @@ +/* +* 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 +#include +#include + +class LightingData +{ + LightCullingTileIterator tileIterator; + + // Lighting outputs + float3 diffuseLighting; + float3 specularLighting; + float3 translucentBackLighting; + + // Factors for the amount of diffuse and specular lighting applied + float3 diffuseResponse; + float3 specularResponse; + + // Direction light shadow coordinates + float3 shadowCoords[ViewSrg::MaxCascadeCount]; + + // Normalized direction from surface to camera + float3 dirToCamera; + + // Scaling term to approximate multiscattering contribution in specular BRDF + float3 multiScatterCompensation; + + // Lighting emitted from the surface + float3 emissiveLighting; + + // BRDF texture values + float2 brdf; + + // Normal . View + float NdotV; + + // 0 = dark, 1 = light + float occlusion; + + void Init(float3 positionWS, float3 normal, float roughnessLinear); + void CalculateMultiscatterCompensation(float3 specularF0, bool enabled); + void FinalizeLighting(float3 transmissionTint); +}; + +void LightingData::Init(float3 positionWS, float3 normal, float roughnessLinear) +{ + diffuseLighting = 0; + specularLighting = 0; + translucentBackLighting = 0; + multiScatterCompensation = 1.0f; + emissiveLighting = float3(0.0f, 0.0f, 0.0f); + occlusion = 1.0f; + + dirToCamera = normalize(ViewSrg::m_worldPosition.xyz - positionWS); + + // sample BRDF map (indexed by smoothness values rather than roughness) + NdotV = saturate(dot(normal, dirToCamera)); + float2 brdfUV = float2(NdotV, (1.0f - roughnessLinear)); + brdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, brdfUV).rg; +} + +void LightingData::CalculateMultiscatterCompensation(float3 specularF0, bool enabled) +{ + multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, enabled); +} + +void LightingData::FinalizeLighting(float3 transmissionTint) +{ + specularLighting += emissiveLighting; + + // Transmitted light + if(o_transmission_mode != TransmissionMode::None) + { + diffuseLighting += translucentBackLighting * transmissionTint; + } +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli new file mode 100644 index 0000000000..31fbbd2138 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli @@ -0,0 +1,63 @@ +/* +* 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 options first +#include + +// Then include custom surface and lighting data types +#include +#include + +// Then include everything else +#include +#include + + +struct PbrLightingOutput +{ + float4 m_diffuseColor; + float4 m_specularColor; + float4 m_albedo; + float4 m_specularF0; + float4 m_normal; + float4 m_clearCoatNormal; + float3 m_scatterDistance; +}; + + +PbrLightingOutput GetPbrLightingOutput(Surface surface, LightingData lightingData, float alpha) +{ + PbrLightingOutput lightingOutput; + + lightingOutput.m_diffuseColor = float4(lightingData.diffuseLighting, alpha); + lightingOutput.m_specularColor = float4(lightingData.specularLighting, 1.0); + + // 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_normal.rgb = EncodeNormalSignedOctahedron(surface.normal); + lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f; + + // layout: (packedNormal.x, packedNormal.y, strength factor, clear coat roughness (not base material's roughness)) + lightingOutput.m_clearCoatNormal = float4(EncodeNormalSphereMap(surface.clearCoat.normal), o_clearCoat_feature_enabled ? surface.clearCoat.factor : 0.0, surface.clearCoat.roughness); + + return lightingOutput; +} + + + + + + diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingModel.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingModel.azsli index 678e8cf061..581ca2f172 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingModel.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingModel.azsli @@ -12,17 +12,7 @@ #pragma once -option bool o_specularF0_enableMultiScatterCompensation; -option bool o_enableShadows = true; -option bool o_enableDirectionalLights = true; -option bool o_enablePunctualLights = true; -option bool o_enableAreaLights = true; -option bool o_enableIBL = true; -option bool o_enableSubsurfaceScattering; -option bool o_clearCoat_feature_enabled; -option enum class TransmissionMode {None, ThickObject, ThinObject} o_transmission_mode; -option bool o_meshUseForwardPassIBLSpecular = false; -option bool o_materialUseForwardPassIBLSpecular = false; +#include #include #include @@ -35,26 +25,12 @@ option bool o_materialUseForwardPassIBLSpecular = false; #include #include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include - -/** -* The StandardPBR Material Template provides a foundation for creating PBR base materials. -* A default StandardPBR base material is provided as well, built on top of this template, and -* should suit many needs. Additional base materials can created as needed, using StandardPBR.material -* as a reference. -*/ // VSInput, VSOutput, ObjectSrg must be defined before including this file. +// DEPRECATED: Please use the VertexHelper(...) function in VertexHelper.azsli instead. //! @param skipShadowCoords can be useful for example when PixelDepthOffset is enable, because the pixel shader will have to run before the final world position is known void PbrVsHelper(in VSInput IN, inout VSOutput OUT, float3 worldPosition, bool skipShadowCoords = false) { @@ -77,18 +53,10 @@ void PbrVsHelper(in VSInput IN, inout VSOutput OUT, float3 worldPosition, bool s } } -struct PbrLightingOutput -{ - float4 m_diffuseColor; - float4 m_specularColor; - float4 m_albedo; - float4 m_specularF0; - float4 m_normal; - float4 m_clearCoatNormal; - float3 m_scatterDistance; -}; -PbrLightingOutput PbrLighting( in VSOutput IN, +// DEPRECATED: Please use the functions in StandardLighting.azsli instead. +// For an example on how to use those functions, see StandardPBR_forwardPass.azsl +PbrLightingOutput PbrLighting( VSOutput IN, float3 baseColor, float metallic, float roughness, @@ -107,24 +75,43 @@ PbrLightingOutput PbrLighting( in VSOutput IN, float alpha, OpacityMode opacityMode) { - static const float3 MaxDielectricSpecularF0 = 0.08f; - float3 dirToCamera = normalize(ViewSrg::m_worldPosition.xyz - IN.m_worldPosition); + float3 worldPosition = IN.m_worldPosition; + float4 position = IN.m_position; + float3 shadowCoords[ViewSrg::MaxCascadeCount] = IN.m_shadowCoords; - // sample BRDF map (indexed by smoothness values rather than roughness) - float NdotV = dot(normal, dirToCamera); - float2 brdfUV = float2(saturate(NdotV), (1.0f - roughness)); - float2 brdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, brdfUV).rg; + // ______________________________________________________________________________________________ + // Surface - // compute albedo and specularF0 based on metalness - float3 albedo = (o_enableSubsurfaceScattering) ? baseColor : lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic); + Surface surface; + + surface.position = worldPosition; + surface.normal = normal; + surface.roughnessLinear = roughness; + surface.transmission.tint = transmissionTintThickness.rgb; + surface.transmission.thickness = transmissionTintThickness.w; + surface.transmission.transmissionParams = transmissionParams; + surface.clearCoat.factor = clearCoatFactor; + surface.clearCoat.roughness = clearCoatRoughness; + surface.clearCoat.normal = clearCoatNormal; + + surface.CalculateRoughnessA(); + surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); + surface.anisotropy.Init(normal, vtxTangent, vtxBitangent, anisotropy.x, anisotropy.y, surface.roughnessA); + + // ______________________________________________________________________________________________ + // LightingData + + LightingData lightingData; + + // Light iterator + lightingData.tileIterator.Init(position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); - // since the left hand side value of this interpolation is achromatic color, this value doesn't convert a color space. - float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * specularF0Factor; + lightingData.emissiveLighting = emissive; + lightingData.occlusion = occlusion; - // because most of metal material theoratically conflicts with subsurface scattering - // (electrons hit to a conductor will be either 'absorbed' or reflected hence no chance to transmit), - // metallic is disabled if subsurface scattering turned on - float3 specularF0 = (o_enableSubsurfaceScattering) ? dielectricSpecularF0 : lerp(dielectricSpecularF0, baseColor, metallic); + // Directional light shadow coordinates + lightingData.shadowCoords = shadowCoords; // manipulate base layer f0 if clear coat is enabled if(o_clearCoat_feature_enabled) @@ -132,140 +119,44 @@ PbrLightingOutput PbrLighting( in VSOutput IN, // modify base layer's normal incidence reflectance // for the derivation of the following equation please refer to: // https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification - float3 f0 = (1.0 - 5.0 * sqrt(specularF0)) / (5.0 - sqrt(specularF0)); - specularF0 = lerp(specularF0, f0 * f0, clearCoatFactor); + float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0)); + surface.specularF0 = lerp(surface.specularF0, f0 * f0, clearCoatFactor); } - // compute specular and diffuse response - float3 specularResponse = FresnelSchlickWithRoughness(NdotV, specularF0, roughness); - float3 diffuseResponse = 1.0 - specularResponse; - - if (o_clearCoat_feature_enabled) + // Diffuse and Specular response (used in IBL calculations) + lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); + lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; + + if(o_clearCoat_feature_enabled) { // Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04 - diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(NdotV, float3(0.04, 0.04, 0.04), clearCoatRoughness) * clearCoatFactor); + lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor); } - // Set up the surface parameters. - Surface surface = (Surface)0.0; - surface.position = IN.m_worldPosition.xyz; - surface.normal = normal; - surface.albedo = albedo; - surface.specularF0 = specularF0; - surface.multiScatterCompensation = GetMultiScatterCompensation(NdotV, surface.specularF0, brdf, o_specularF0_enableMultiScatterCompensation); - // The roughness value in microfacet calculations (called "alpha" in the literature) does not give perceptually - // linear results. Disney found that squaring the roughness value before using it in microfacet equations causes - // the user-provided roughness parameter to be more perceptually linear. We keep both values available as some - // equations need roughnessLinear (i.e. IBL sampling) while others need roughnessA (i.e. GGX equations). - // See Burley's Disney PBR: https://pdfs.semanticscholar.org/eeee/3b125c09044d3e2f58ed0e4b1b66a677886d.pdf - surface.roughnessLinear = roughness; - surface.thickness = transmissionTintThickness.w; - - // Thick object mode: (attenuation coefficient, power, distortion, scale) - // Thin object mode: (float3 scatter distance, scale) - surface.transmissionParams = transmissionParams; + // Multiscatter compensation factor + lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation); - // Parameters: (clear coat factor, perceptual roughness) - surface.clearCoatFactor = clearCoatFactor; - surface.clearCoatRoughness = clearCoatRoughness; - surface.clearCoatNormal = clearCoatNormal; + // ______________________________________________________________________________________________ + // Lighting - // Make sure roughnessA is above 0 to avoid precision and divide by zero issues. 0.0005f is sufficient for directional lights since they tend to be quite bright. - surface.roughnessA = max(roughness * roughness, 0.0005f); + // Apply Decals + ApplyDecals(lightingData.tileIterator, surface); - if (o_enableAnisotropy) + // Apply Direct Lighting + ApplyDirectLighting(surface, lightingData); + + // Apply Image Based Lighting (IBL) + ApplyIBL(surface, lightingData); + + // Finalize Lighting + lightingData.FinalizeLighting(surface.transmission.tint); + + if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) { - CalculateSurfaceDirectionalAnisotropicData(surface, anisotropy, vtxTangent, vtxBitangent); + alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. } - float3 diffuseLighting = 0.0f; // accumulation of diffuse lighting - float3 specularLighting = 0.0f; // accumulation of specular lighting - float3 translucentBackLighting = 0.0f; // accumulation of transmitted light on the back face of object for back lighting - - LightCullingTileIterator tileIterator; - tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); - - ApplyDecals(tileIterator, surface); - - if (o_enablePunctualLights) - { - ApplyPointLights(tileIterator, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); - ApplySpotLights(tileIterator, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); - } - - if (o_enableAreaLights) - { - ApplyDiskLights(tileIterator, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); - ApplyCapsuleLights(tileIterator, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); - ApplyQuadLights(tileIterator, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); - ApplyPolygonLights(dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); - } - - if (opacityMode == OpacityMode::Blended || opacityMode == OpacityMode::TintedTransparent) - { - // transparencies currently require IBL in the forward pass - float3 iblDiffuse = 0.0f; - float3 iblSpecular = 0.0f; - if (o_enableIBL) - { - ApplyIblDiffuse(surface, diffuseResponse, iblDiffuse); - ApplyIblSpecular(surface, specularResponse, dirToCamera, brdf, iblSpecular); - } - - // Apply ambient occlusion to indirect diffuse - iblDiffuse *= occlusion; - - // Adjust IBL lighting by exposure. - float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure); - iblDiffuse *= iblExposureFactor; - iblSpecular *= iblExposureFactor; - diffuseLighting += iblDiffuse; - specularLighting += iblSpecular; - - alpha = FresnelSchlickWithRoughness(NdotV, alpha, roughness).x; // Increase opacity at grazing angles. - } - else if (o_meshUseForwardPassIBLSpecular || o_materialUseForwardPassIBLSpecular) - { - if (o_enableIBL) - { - float3 iblSpecular = 0.0f; - ApplyIblSpecular(surface, specularResponse, dirToCamera, brdf, iblSpecular); - - float iblExposureFactor = pow(2.0f, SceneSrg::m_iblExposure); - specularLighting += (iblSpecular * iblExposureFactor); - } - } - - // Emissive contribution - // Emissive light is apply to specular now, as diffuse will be used for subsurface scattering later down the pipeline - // We may change this if specular is also used for other processing - specularLighting += emissive; - - if (o_enableDirectionalLights) - { - ApplyDirectionalLights(dirToCamera, surface, IN.m_shadowCoords, diffuseLighting, specularLighting, translucentBackLighting); - } - - // Transmitted light - if(o_transmission_mode != TransmissionMode::None) - { - diffuseLighting += translucentBackLighting * transmissionTintThickness.xyz; - } - - PbrLightingOutput lightingOutput; - - lightingOutput.m_diffuseColor = float4(diffuseLighting, alpha); - lightingOutput.m_specularColor = float4(specularLighting, 1.0); - - // albedo, specularF0, roughness, and normals for later passes (specular IBL, Diffuse GI, SSR, AO, etc) - lightingOutput.m_specularF0 = float4(specularF0, roughness); - lightingOutput.m_albedo.rgb = surface.albedo * diffuseResponse; - lightingOutput.m_albedo.a = occlusion; - lightingOutput.m_normal.rgb = EncodeNormalSignedOctahedron(normal); - lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f; - - // layout: (packedNormal.x, packedNormal.y, strength factor, clear coat roughness (not base material's roughness)) - lightingOutput.m_clearCoatNormal = float4(EncodeNormalSphereMap(clearCoatNormal), o_clearCoat_feature_enabled ? clearCoatFactor : 0.0, clearCoatRoughness); + PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); return lightingOutput; } @@ -278,6 +169,7 @@ PbrLightingOutput PbrLighting( in VSOutput IN, //! @param debugColor the color to be drawn //! @param normalWS world space normal vector //! @return a PbrLightingOutput as returned by the main PbrLighting() function + PbrLightingOutput MakeDebugOutput(VSOutput IN, float3 debugColor, float3 normalWS) { // We happen to set this up initially using baseColor, but we could consider adding an option to use diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingOptions.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingOptions.azsli new file mode 100644 index 0000000000..e4de5d557e --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingOptions.azsli @@ -0,0 +1,26 @@ +/* +* 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 + +option bool o_specularF0_enableMultiScatterCompensation; +option bool o_enableShadows = true; +option bool o_enableDirectionalLights = true; +option bool o_enablePunctualLights = true; +option bool o_enableAreaLights = true; +option bool o_enableIBL = true; +option bool o_enableSubsurfaceScattering; +option bool o_clearCoat_feature_enabled; +option enum class TransmissionMode {None, ThickObject, ThinObject} o_transmission_mode; +option bool o_meshUseForwardPassIBLSpecular = false; +option bool o_materialUseForwardPassIBLSpecular = false; + diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli index 6304b67190..3b9e96c1c7 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli @@ -19,7 +19,7 @@ float3 GetCubemapCoords(float3 original) } //! Compute multiscatter compensation multiplier -float3 GetMultiScatterCompensation(float NdotV, float3 specularF0, float2 brdf, bool enabled) +float3 GetMultiScatterCompensation(float3 specularF0, float2 brdf, bool enabled) { if (!enabled) { @@ -66,4 +66,4 @@ float3 ApplyParallaxCorrection(float3 aabbMin, float3 aabbMax, float3 aabbPos, f float distance = min(min(furthestIntersect.x, furthestIntersect.y), furthestIntersect.z); float3 intersectPos = reflectDir * distance + positionWS; return (intersectPos - aabbPos); -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli index 523fad150c..df2bfda3e2 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli @@ -57,7 +57,7 @@ void SampleCapsule(float2 randomPoint, ViewSrg::CapsuleLight light, float capToC } } -void ApplyCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyCapsuleLight(ViewSrg::CapsuleLight light, Surface surface, inout LightingData lightingData) { float lightLength = light.m_length; float3 startPoint = light.m_startPoint; @@ -125,10 +125,10 @@ void ApplyCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surface intensity *= INV_PI; // normalize for lambert reflectance. float3 lightIntensity = (intensity * radiusAttenuation * ratioVisible) * light.m_rgbIntensityCandelas; - diffuseLighting += max(0.0, surface.albedo * lightIntensity); + lightingData.diffuseLighting += max(0.0, surface.albedo * lightIntensity); // Calculate the reflection of the normal from the view direction - float3 reflectionDir = reflect(-dirToCamera, surface.normal); + float3 reflectionDir = reflect(-lightingData.dirToCamera, surface.normal); // Find closest point on light to reflection vector. // See https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf @@ -140,7 +140,7 @@ void ApplyCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surface float3 posToLight = closestIntersectionPoint - surface.position; // Tranmission contribution - translucentBackLighting += GetBackLighting(surface, lightIntensity, dirToCamera, normalize(posToLight), 0.0); + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0); // Calculate the offset from the nearest point on the reflection vector to the nearest point on the capsule light float3 posToClosestPointAlongReflection = dot(posToLight, reflectionDir) * reflectionDir; @@ -169,11 +169,11 @@ void ApplyCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surface // Specular contribution lightIntensity = sphereToCapsuleAreaRatio * radiusAttenuation / d2; lightIntensity *= light.m_rgbIntensityCandelas; - specularLighting += sphereIntensityNormalization * GetSpecularLighting(surface, lightIntensity, dirToCamera, normalize(posToLight)); + lightingData.specularLighting += sphereIntensityNormalization * GetSpecularLighting(surface, lightingData, lightIntensity, normalize(posToLight)); } } -void ValidateCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ValidateCapsuleLight(ViewSrg::CapsuleLight light, Surface surface, inout LightingData lightingData) { const uint sampleCount = 1024; @@ -205,7 +205,7 @@ void ValidateCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surfa float3 direction; float2 randomPoint = GetHammersleyPoint(i, sampleCount); SampleCapsule(randomPoint, light, capToCylinderAreaRatio, localToWorld, position, direction); - AddSampleContribution(surface, position, direction, dirToCamera, 0.0, diffuseAcc, specularAcc, translucentAcc); + AddSampleContribution(surface, lightingData, position, direction, 0.0, diffuseAcc, specularAcc, translucentAcc); } // Lighting value is in Candela, convert to Lumen for total light output of the light @@ -214,28 +214,28 @@ void ValidateCapsuleLight(ViewSrg::CapsuleLight light, float3 dirToCamera, Surfa // equal directions across the hemisphere, so we need to account for that float3 intensity = intensityLumens * INV_PI; - diffuseLighting += (diffuseAcc / float(sampleCount)) * intensity; - translucentBackLighting += (translucentAcc / float(sampleCount)) * intensity; - specularLighting += (specularAcc / float(sampleCount)) * intensity; + lightingData.diffuseLighting += (diffuseAcc / float(sampleCount)) * intensity; + lightingData.translucentBackLighting += (translucentAcc / float(sampleCount)) * intensity; + lightingData.specularLighting += (specularAcc / float(sampleCount)) * intensity; } -void ApplyCapsuleLights(inout LightCullingTileIterator tileIterator, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyCapsuleLights(Surface surface, inout LightingData lightingData) { - tileIterator.LoadAdvance(); + lightingData.tileIterator.LoadAdvance(); - while(!tileIterator.IsDone()) - { - uint currLightIndex = tileIterator.GetValue(); - tileIterator.LoadAdvance(); + while(!lightingData.tileIterator.IsDone()) + { + uint currLightIndex = lightingData.tileIterator.GetValue(); + lightingData.tileIterator.LoadAdvance(); ViewSrg::CapsuleLight light = ViewSrg::m_capsuleLights[currLightIndex]; if (o_area_light_validation) { - ValidateCapsuleLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ValidateCapsuleLight(light, surface, lightingData); } else { - ApplyCapsuleLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ApplyCapsuleLight(light, surface, lightingData); } } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli index 334a415ab3..9764bfe01c 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli @@ -15,13 +15,7 @@ #include #include -void ApplyDirectionalLights( - float3 dirToCamera, - Surface surface, - float3 shadowCoords[ViewSrg::MaxCascadeCount], - inout float3 diffuseLighting, - inout float3 specularLighting, - inout float3 translucentBackLighting) +void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) { DirectionalLightShadow::DebugInfo debugInfo = {0, false}; @@ -33,13 +27,13 @@ void ApplyDirectionalLights( { litRatio = DirectionalLightShadow::GetVisibility( shadowIndex, - shadowCoords, + lightingData.shadowCoords, surface.normal, debugInfo); if (o_transmission_mode == TransmissionMode::ThickObject) { - backShadowRatio = DirectionalLightShadow::GetThickness(shadowIndex, shadowCoords); + backShadowRatio = DirectionalLightShadow::GetThickness(shadowIndex, lightingData.shadowCoords); } } @@ -50,7 +44,7 @@ void ApplyDirectionalLights( float3 dirToLight = normalize(-light.m_direction); // Adjust the direction of the light based on its angular diameter. - float3 reflectionDir = reflect(-dirToCamera, surface.normal); + float3 reflectionDir = reflect(-lightingData.dirToCamera, surface.normal); float3 lightDirToReflectionDir = reflectionDir - dirToLight; float lightDirToReflectionDirLen = length(lightDirToReflectionDir); lightDirToReflectionDir = lightDirToReflectionDir / lightDirToReflectionDirLen; // normalize the length @@ -72,16 +66,16 @@ void ApplyDirectionalLights( } } - diffuseLighting += GetDiffuseLighting(surface, light.m_rgbIntensityLux, dirToCamera, dirToLight) * currentLitRatio; - specularLighting += GetSpecularLighting(surface, light.m_rgbIntensityLux, dirToCamera, dirToLight) * currentLitRatio; - translucentBackLighting += GetBackLighting(surface, light.m_rgbIntensityLux, dirToCamera, dirToLight, currentBackShadowRatio); + lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; + lightingData.specularLighting += GetSpecularLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight, currentBackShadowRatio); } // Add debug coloring for directional light shadow if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) { - specularLighting = DirectionalLightShadow::AddDebugColoring( - specularLighting, + lightingData.specularLighting = DirectionalLightShadow::AddDebugColoring( + lightingData.specularLighting, ViewSrg::m_shadowIndexDirectionalLight, debugInfo); } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli index 5d6aafd06e..79c05fbe8b 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli @@ -14,7 +14,7 @@ #include -void ApplyDiskLight(ViewSrg::DiskLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingData lightingData) { float3 posToLight = light.m_position - surface.position; float distanceToLight2 = dot(posToLight, posToLight); // light distance squared @@ -64,15 +64,15 @@ void ApplyDiskLight(ViewSrg::DiskLight light, float3 dirToCamera, Surface surfac lightIntensity /= ((light.m_diskRadius / distanceToPlane) + 1.0); // Diffuse contribution - diffuseLighting += GetDiffuseLighting(surface, lightIntensity, dirToCamera, posToLightDir); + lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, posToLightDir); // Tranmission contribution - translucentBackLighting += GetBackLighting(surface, lightIntensity, dirToCamera, posToLightDir, 0.0); + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, posToLightDir, 0.0); // Adjust the light direction for specular based on disk size // Calculate the reflection off the normal from the view lightDirection - float3 reflectionDir = reflect(-dirToCamera, surface.normal); + float3 reflectionDir = reflect(-lightingData.dirToCamera, surface.normal); float reflectionDotLight = dot(reflectionDir, -lightDirection); // Let 'Intersection' denote the point where the reflection ray intersects the diskLight plane @@ -104,7 +104,7 @@ void ApplyDiskLight(ViewSrg::DiskLight light, float3 dirToCamera, Surface surfac float diskIntensityNormalization = GetIntensityAdjustedByRadiusAndRoughness(surface.roughnessA, light.m_diskRadius, distanceToLight2); // Specular contribution - specularLighting += diskIntensityNormalization * GetSpecularLighting(surface, lightIntensity, dirToCamera, normalize(posToLight)); + lightingData.specularLighting += diskIntensityNormalization * GetSpecularLighting(surface, lightingData, lightIntensity, normalize(posToLight)); } } @@ -135,7 +135,7 @@ float3 SampleDisk(float2 randomPoint, ViewSrg::DiskLight light) return outPoint; } -void ValidateDiskLight(ViewSrg::DiskLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ValidateDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingData lightingData) { const uint sampleCount = 512; @@ -147,31 +147,31 @@ void ValidateDiskLight(ViewSrg::DiskLight light, float3 dirToCamera, Surface sur { float2 randomPoint = GetHammersleyPoint(i, sampleCount); float3 samplePoint = SampleDisk(randomPoint, light); - AddSampleContribution(surface, samplePoint, light.m_direction, dirToCamera, light.m_bothDirectionsFactor, diffuseAcc, specularAcc, translucentAcc); + AddSampleContribution(surface, lightingData, samplePoint, light.m_direction, light.m_bothDirectionsFactor, diffuseAcc, specularAcc, translucentAcc); } - diffuseLighting += (diffuseAcc / float(sampleCount)) * light.m_rgbIntensityCandelas; - specularLighting += (specularAcc / float(sampleCount)) * light.m_rgbIntensityCandelas; + lightingData.diffuseLighting += (diffuseAcc / float(sampleCount)) * light.m_rgbIntensityCandelas; + lightingData.specularLighting += (specularAcc / float(sampleCount)) * light.m_rgbIntensityCandelas; } -void ApplyDiskLights(inout LightCullingTileIterator tileIterator, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyDiskLights(Surface surface, inout LightingData lightingData) { - tileIterator.LoadAdvance(); + lightingData.tileIterator.LoadAdvance(); - while( !tileIterator.IsDone() ) - { - uint currLightIndex = tileIterator.GetValue(); - tileIterator.LoadAdvance(); + while( !lightingData.tileIterator.IsDone() ) + { + uint currLightIndex = lightingData.tileIterator.GetValue(); + lightingData.tileIterator.LoadAdvance(); ViewSrg::DiskLight light = ViewSrg::m_diskLights[currLightIndex]; if (o_area_light_validation) { - ValidateDiskLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ValidateDiskLight(light, surface, lightingData); } else { - ApplyDiskLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ApplyDiskLight(light, surface, lightingData); } } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli index f591aafb27..f08acd2684 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli @@ -12,25 +12,27 @@ #pragma once +#include + #include #include #include -void ApplyIblDiffuse(Surface surface, float3 diffuseResponse, out float3 outDiffuse) +void ApplyIblDiffuse(float3 normal, float3 albedo, float3 diffuseResponse, out float3 outDiffuse) { - float3 irradianceDir = MultiplyVectorQuaternion(surface.normal, SceneSrg::m_iblOrientation); + float3 irradianceDir = MultiplyVectorQuaternion(normal, SceneSrg::m_iblOrientation); float3 diffuseSample = SceneSrg::m_diffuseEnvMap.Sample(SceneSrg::m_samplerEnv, GetCubemapCoords(irradianceDir)).rgb; - outDiffuse = diffuseResponse * surface.albedo * diffuseSample; + outDiffuse = diffuseResponse * albedo * diffuseSample; } -void ApplyIblSpecular(Surface surface, float3 specularResponse, float3 dirToCamera, float2 brdf, out float3 outSpecular) +void ApplyIblSpecular(float3 position, float3 normal, float3 specularF0, float roughnessLinear, float3 specularResponse, float3 dirToCamera, float2 brdf, out float3 outSpecular) { - float3 reflectDir = reflect(-dirToCamera, surface.normal); + float3 reflectDir = reflect(-dirToCamera, normal); // global - outSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(surface.roughnessLinear)).rgb; - outSpecular *= (surface.specularF0 * brdf.x + brdf.y); + outSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughnessLinear)).rgb; + outSpecular *= (specularF0 * brdf.x + brdf.y); // reflection probe if (ObjectSrg::m_reflectionProbeData.m_useReflectionProbe) @@ -38,24 +40,56 @@ void ApplyIblSpecular(Surface surface, float3 specularResponse, float3 dirToCame if (ObjectSrg::m_reflectionProbeData.m_useParallaxCorrection) { reflectDir = ApplyParallaxCorrection( - ObjectSrg::m_reflectionProbeData.m_outerAabbMin, - ObjectSrg::m_reflectionProbeData.m_outerAabbMax, - ObjectSrg::m_reflectionProbeData.m_aabbPos, - surface.position, + ObjectSrg::m_reflectionProbeData.m_outerAabbMin, + ObjectSrg::m_reflectionProbeData.m_outerAabbMax, + ObjectSrg::m_reflectionProbeData.m_aabbPos, + position, reflectDir); } - float3 probeSpecular = ObjectSrg::m_reflectionProbeCubeMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(surface.roughnessLinear)).rgb; - probeSpecular *= (surface.specularF0 * brdf.x + brdf.y); + float3 probeSpecular = ObjectSrg::m_reflectionProbeCubeMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughnessLinear)).rgb; + probeSpecular *= (specularF0 * brdf.x + brdf.y); // compute blend amount based on world position in the reflection probe volume float blendAmount = ComputeLerpBetweenInnerOuterAABBs( - ObjectSrg::m_reflectionProbeData.m_innerAabbMin, - ObjectSrg::m_reflectionProbeData.m_innerAabbMax, - ObjectSrg::m_reflectionProbeData.m_outerAabbMax, - ObjectSrg::m_reflectionProbeData.m_aabbPos, - surface.position); + ObjectSrg::m_reflectionProbeData.m_innerAabbMin, + ObjectSrg::m_reflectionProbeData.m_innerAabbMax, + ObjectSrg::m_reflectionProbeData.m_outerAabbMax, + ObjectSrg::m_reflectionProbeData.m_aabbPos, + position); outSpecular = lerp(outSpecular, probeSpecular, blendAmount); } -} \ No newline at end of file +} + +void ApplyIBL(Surface surface, inout LightingData lightingData) +{ + if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) + { + // transparencies currently require IBL in the forward pass + if (o_enableIBL) + { + float3 iblDiffuse = 0.0f; + float3 iblSpecular = 0.0f; + ApplyIblDiffuse(surface.normal, surface.albedo, lightingData.diffuseResponse, iblDiffuse); + ApplyIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.specularResponse, lightingData.dirToCamera, lightingData.brdf, iblSpecular); + + // Adjust IBL lighting by exposure. + float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure); + lightingData.diffuseLighting += (iblDiffuse * iblExposureFactor * lightingData.occlusion); + lightingData.specularLighting += (iblSpecular * iblExposureFactor); + } + } + else if (o_meshUseForwardPassIBLSpecular || o_materialUseForwardPassIBLSpecular) + { + if (o_enableIBL) + { + float3 iblSpecular = 0.0f; + ApplyIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.specularResponse, lightingData.dirToCamera, lightingData.brdf, iblSpecular); + + float iblExposureFactor = pow(2.0f, SceneSrg::m_iblExposure); + lightingData.specularLighting += (iblSpecular * iblExposureFactor); + } + } +} + diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli index f97703ba14..a668691b75 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli @@ -22,13 +22,13 @@ option bool o_area_light_validation = false; -float3 GetDiffuseLighting(Surface surface, float3 lightIntensity, float3 dirToCamera, float3 dirToLight) +float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight) { float3 diffuse; if(o_enableSubsurfaceScattering) { // Use diffuse brdf contains double Fresnel (enter/exit surface) terms if subsurface scattering is enabled - diffuse = NormalizedDisneyDiffuse(surface.albedo, surface.normal, dirToCamera, dirToLight, surface.roughnessLinear); + diffuse = NormalizedDisneyDiffuse(surface.albedo, surface.normal, lightingData.dirToCamera, dirToLight, surface.roughnessLinear); } else { @@ -38,29 +38,41 @@ float3 GetDiffuseLighting(Surface surface, float3 lightIntensity, float3 dirToCa if(o_clearCoat_feature_enabled) { // Attenuate diffuse term by clear coat's fresnel term to account for energy loss - float HdotV = saturate(dot(normalize(dirToLight + dirToCamera), dirToCamera)); - diffuse *= 1.0 - (FresnelSchlick(HdotV, 0.04) * surface.clearCoatFactor); + float HdotV = saturate(dot(normalize(dirToLight + lightingData.dirToCamera), lightingData.dirToCamera)); + diffuse *= 1.0 - (FresnelSchlick(HdotV, 0.04) * surface.clearCoat.factor); } diffuse *= lightIntensity; return diffuse; } -float3 GetSpecularLighting(Surface surface, const float3 lightIntensity, const float3 dirToCamera, const float3 dirToLight) +float3 GetSpecularLighting(Surface surface, LightingData lightingData, const float3 lightIntensity, const float3 dirToLight) { - float3 specular = SpecularGGX(surface, dirToCamera, dirToLight); + float3 specular; + if (o_enableAnisotropy) + { + //AnisotropicGGX( float3 dirToCamera, float3 dirToLight, float3 normal, float3 tangent, float3 bitangent, float2 anisotropyFactors, + // float3 specularF0, float NdotV, float multiScatterCompensation ) + + specular = AnisotropicGGX( lightingData.dirToCamera, dirToLight, surface.normal, surface.anisotropy.tangent, surface.anisotropy.bitangent, surface.anisotropy.anisotropyFactors, + surface.specularF0, lightingData.NdotV, lightingData.multiScatterCompensation ); + } + else + { + specular = SpecularGGX(lightingData.dirToCamera, dirToLight, surface.normal, surface.specularF0, lightingData.NdotV, surface.roughnessA2, lightingData.multiScatterCompensation); + } if(o_clearCoat_feature_enabled) { - float3 halfVector = normalize(dirToLight + dirToCamera); - float NdotH = saturate(dot(surface.clearCoatNormal, halfVector)); - float NdotL = saturate(dot(surface.clearCoatNormal, dirToLight)); + float3 halfVector = normalize(dirToLight + lightingData.dirToCamera); + float NdotH = saturate(dot(surface.clearCoat.normal, halfVector)); + float NdotL = saturate(dot(surface.clearCoat.normal, dirToLight)); float HdotL = saturate(dot(halfVector, dirToLight)); // HdotV = HdotL due to the definition of half vector - float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoatFactor; - float clearCoatRoughness = max(surface.clearCoatRoughness * surface.clearCoatRoughness, 0.0005f); - float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoatNormal, clearCoatRoughness, clearCoatF ); + float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoat.factor; + float clearCoatRoughness = max(surface.clearCoat.roughness * surface.clearCoat.roughness, 0.0005f); + float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF ); specular = specular * (1.0 - clearCoatF) * (1.0 - clearCoatF) + clearCoatSpecular; } @@ -81,9 +93,9 @@ float GetIntensityAdjustedByRadiusAndRoughness(float roughnessA, float radius, f //! Adds diffuse and specular contribution for a single sample of a lambertian emitter void AddSampleContribution( in Surface surface, + in LightingData lightingData, in float3 lightSamplePoint, in float3 lightSampleDirection, - in float3 dirToCamera, in float bothDirectionsFactor, inout float3 diffuseAcc, inout float3 specularAcc, @@ -102,7 +114,7 @@ void AddSampleContribution( float3 intensityRgb = float3(intensity, intensity, intensity); - diffuseAcc += GetDiffuseLighting(surface, intensityRgb, dirToCamera, posToLightSampleDir); - translucentAcc += GetBackLighting(surface, intensityRgb, dirToCamera, posToLightSampleDir, 0.0); - specularAcc += GetSpecularLighting(surface, intensityRgb, dirToCamera, posToLightSampleDir); + diffuseAcc += GetDiffuseLighting(surface, lightingData, intensityRgb, posToLightSampleDir); + translucentAcc += GetBackLighting(surface, lightingData, intensityRgb, posToLightSampleDir, 0.0); + specularAcc += GetSpecularLighting(surface, lightingData, intensityRgb, posToLightSampleDir); } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Lights.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Lights.azsli new file mode 100644 index 0000000000..37594cf553 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Lights.azsli @@ -0,0 +1,41 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include + +void ApplyDirectLighting(Surface surface, inout LightingData lightingData) +{ + if (o_enableDirectionalLights) + { + ApplyDirectionalLights(surface, lightingData); + } + if (o_enablePunctualLights) + { + ApplyPointLights(surface, lightingData); + ApplySpotLights(surface, lightingData); + } + if (o_enableAreaLights) + { + ApplyDiskLights(surface, lightingData); + ApplyCapsuleLights(surface, lightingData); + ApplyQuadLights(surface, lightingData); + ApplyPolygonLights(surface, lightingData); + } +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli index 60dbfa4016..1f8b97d6a3 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli @@ -359,7 +359,7 @@ float LtcPolygonEvaluate(in float3 pos, in float3 normal, in float3 dirToView, i // Find the previous clip point so it can be used when the polygon goes above the horizon by // searching backwards, updating the endIdx along the way to avoid reprocessing those points later - for (endIdx; endIdx > startIdx + 1; --endIdx) + for ( ; endIdx > startIdx + 1; --endIdx) { float3 prevPoint = mul(ltcMat, positions[endIdx - 1].xyz - pos); if (prevPoint.z > 0) @@ -392,4 +392,4 @@ float LtcPolygonEvaluate(in float3 pos, in float3 normal, in float3 dirToView, i // Note: negated due to winding order return -sum; -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 358425fadd..a59eb89dc7 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -14,7 +14,7 @@ #include -void ApplyPointLight(ViewSrg::PointLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) { float3 posToLight = light.m_position - surface.position; float d2 = dot(posToLight, posToLight); // light distance squared @@ -32,15 +32,15 @@ void ApplyPointLight(ViewSrg::PointLight light, float3 dirToCamera, Surface surf float3 lightIntensity = (light.m_rgbIntensityCandelas / d2) * radiusAttenuation; // Diffuse contribution - diffuseLighting += GetDiffuseLighting(surface, lightIntensity, dirToCamera, normalize(posToLight)); + lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)); // Tranmission contribution - translucentBackLighting += GetBackLighting(surface, lightIntensity, dirToCamera, normalize(posToLight), 0.0); + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0); // Adjust the light direcion for specular based on bulb size // Calculate the reflection off the normal from the view direction - float3 reflectionDir = reflect(-dirToCamera, surface.normal); + float3 reflectionDir = reflect(-lightingData.dirToCamera, surface.normal); // Calculate a vector from the reflection vector to the light float3 reflectionPosToLight = posToLight - dot(posToLight, reflectionDir) * reflectionDir; @@ -52,7 +52,7 @@ void ApplyPointLight(ViewSrg::PointLight light, float3 dirToCamera, Surface surf float sphereIntensityNormalization = GetIntensityAdjustedByRadiusAndRoughness(surface.roughnessA, light.m_bulbRadius, d2); // Specular contribution - specularLighting += sphereIntensityNormalization * GetSpecularLighting(surface, lightIntensity, dirToCamera, normalize(posToLight)); + lightingData.specularLighting += sphereIntensityNormalization * GetSpecularLighting(surface, lightingData, lightIntensity, normalize(posToLight)); } } @@ -65,7 +65,7 @@ float3 SampleSphere(float2 randomPoint) return float3(sinTheta * cos(angle), sinTheta * sin(angle), cosTheta); } -void ValidatePointLight(ViewSrg::PointLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ValidatePointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) { const uint sampleCount = 512; @@ -78,7 +78,7 @@ void ValidatePointLight(ViewSrg::PointLight light, float3 dirToCamera, Surface s float2 randomPoint = GetHammersleyPoint(i, sampleCount); float3 sampleDirection = SampleSphere(randomPoint); float3 samplePoint = light.m_position + sampleDirection * light.m_bulbRadius; - AddSampleContribution(surface, samplePoint, sampleDirection, dirToCamera, 0.0, diffuseAcc, specularAcc, translucentAcc); + AddSampleContribution(surface, lightingData, samplePoint, sampleDirection, 0.0, diffuseAcc, specularAcc, translucentAcc); } // Lighting value is in Candela, convert to Lumen for total light output of the light @@ -87,29 +87,29 @@ void ValidatePointLight(ViewSrg::PointLight light, float3 dirToCamera, Surface s // equal directions across the hemisphere, so we need to account for that float3 intensity = intensityLumens * INV_PI; - diffuseLighting += (diffuseAcc / float(sampleCount)) * intensity; - translucentBackLighting += (translucentAcc / float(sampleCount)) * intensity; - specularLighting += (specularAcc / float(sampleCount)) * intensity; + lightingData.diffuseLighting += (diffuseAcc / float(sampleCount)) * intensity; + lightingData.translucentBackLighting += (translucentAcc / float(sampleCount)) * intensity; + lightingData.specularLighting += (specularAcc / float(sampleCount)) * intensity; } -void ApplyPointLights(inout LightCullingTileIterator tileIterator, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyPointLights(Surface surface, inout LightingData lightingData) { - tileIterator.LoadAdvance(); - - while( !tileIterator.IsDone() ) + lightingData.tileIterator.LoadAdvance(); + + while( !lightingData.tileIterator.IsDone() ) { - uint currLightIndex = tileIterator.GetValue(); - tileIterator.LoadAdvance(); + uint currLightIndex = lightingData.tileIterator.GetValue(); + lightingData.tileIterator.LoadAdvance(); ViewSrg::PointLight light = ViewSrg::m_pointLights[currLightIndex]; if (o_area_light_validation) { - ValidatePointLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ValidatePointLight(light, surface, lightingData); } else { - ApplyPointLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ApplyPointLight(light, surface, lightingData); } } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli index 284a9d68fa..0f8c897dc2 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli @@ -17,7 +17,7 @@ #include // Polygon lights using Linearly Transformed Cosines -void ApplyPoylgonLight(ViewSrg::PolygonLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyPoylgonLight(ViewSrg::PolygonLight light, Surface surface, inout LightingData lightingData) { float3 posToLight = light.m_position - surface.position; float distanceToLight2 = dot(posToLight, posToLight); // light distance squared @@ -57,13 +57,13 @@ void ApplyPoylgonLight(ViewSrg::PolygonLight light, float3 dirToCamera, Surface // Diffuse static const float3x3 identityMatrix = float3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); - float diffuse = LtcPolygonEvaluate(surface.position, surface.normal, dirToCamera, identityMatrix, ViewSrg::m_polygonLightPoints, startIndex, endIndex); + float diffuse = LtcPolygonEvaluate(surface.position, surface.normal, lightingData.dirToCamera, identityMatrix, ViewSrg::m_polygonLightPoints, startIndex, endIndex); diffuse = doubleSided ? abs(diffuse) : max(0.0, diffuse); // Specular - float2 ltcCoords = LtcCoords(dot(surface.normal, dirToCamera), surface.roughnessLinear); + float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear); float3x3 ltcMat = LtcMatrix(SceneSrg::m_ltcMatrix, ltcCoords); - float3 specular = LtcPolygonEvaluate(surface.position, surface.normal, dirToCamera, ltcMat, ViewSrg::m_polygonLightPoints, startIndex, endIndex); + float3 specular = LtcPolygonEvaluate(surface.position, surface.normal, lightingData.dirToCamera, ltcMat, ViewSrg::m_polygonLightPoints, startIndex, endIndex); specular = doubleSided ? abs(specular) : max(0.0, specular); // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) @@ -73,16 +73,16 @@ void ApplyPoylgonLight(ViewSrg::PolygonLight light, float3 dirToCamera, Surface // Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity float3 intensity = 0.5 * INV_PI * radiusAttenuation * abs(light.m_rgbIntensityNits); - diffuseLighting += surface.albedo * diffuse * intensity; - specularLighting += surface.specularF0 * specular * intensity; + lightingData.diffuseLighting += surface.albedo * diffuse * intensity; + lightingData.specularLighting += surface.specularF0 * specular * intensity; } -void ApplyPolygonLights(float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyPolygonLights(Surface surface, inout LightingData lightingData) { for (uint currLightIndex = 0; currLightIndex < ViewSrg::m_polygonLightCount; ++currLightIndex) { ViewSrg::PolygonLight light = ViewSrg::m_polygonLights[currLightIndex]; - ApplyPoylgonLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ApplyPoylgonLight(light, surface, lightingData); } -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli index 7350743e27..cfc4a78147 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli @@ -79,7 +79,7 @@ float3 GetSpecularDominantDirection(float3 normal, float3 reflection, float roug } // Quad light approximation. Diffuse portion based on https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf Pages 49-50. -void ApplyQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyQuadLight(ViewSrg::QuadLight light, Surface surface, inout LightingData lightingData) { float3 lightDirection = cross(light.m_leftDir, light.m_upDir); // left and up are already normalized. @@ -118,12 +118,12 @@ void ApplyQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface surfac // Diffuse float3x3 identityMatrix = float3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); - float diffuse = LtcQuadEvaluate(surface.normal, dirToCamera, identityMatrix, p, doubleSided); + float diffuse = LtcQuadEvaluate(surface.normal, lightingData.dirToCamera, identityMatrix, p, doubleSided); // Specular - float2 ltcCoords = LtcCoords(dot(surface.normal, dirToCamera), surface.roughnessLinear); + float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear); float3x3 ltcMat = LtcMatrix(SceneSrg::m_ltcMatrix, ltcCoords); - float3 specular = LtcQuadEvaluate(surface.normal, dirToCamera, ltcMat, p, doubleSided); + float3 specular = LtcQuadEvaluate(surface.normal, lightingData.dirToCamera, ltcMat, p, doubleSided); // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) float2 schlick = SceneSrg::m_ltcAmplification.Sample(PassSrg::LinearSampler, ltcCoords).xy; @@ -132,8 +132,8 @@ void ApplyQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface surfac // Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity float3 intensity = 0.5 * INV_PI * radiusAttenuation * light.m_rgbIntensityNits; - diffuseLighting += surface.albedo * diffuse * intensity; - specularLighting += surface.specularF0 * specular * intensity; + lightingData.diffuseLighting += surface.albedo * diffuse * intensity; + lightingData.specularLighting += surface.specularF0 * specular * intensity; } else { @@ -152,29 +152,29 @@ void ApplyQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface surfac // Each position contributes 1/5 of the light (4 corners + center) float3 intensity = solidAngle * 0.2 * radiusAttenuation * light.m_rgbIntensityNits; - diffuseLighting += + lightingData.diffuseLighting += ( - GetDiffuseLighting(surface, intensity, dirToCamera, p0) + - GetDiffuseLighting(surface, intensity, dirToCamera, p1) + - GetDiffuseLighting(surface, intensity, dirToCamera, p2) + - GetDiffuseLighting(surface, intensity, dirToCamera, p3) + - GetDiffuseLighting(surface, intensity, dirToCamera, dirToLightCenter) + GetDiffuseLighting(surface, lightingData, intensity, p0) + + GetDiffuseLighting(surface, lightingData, intensity, p1) + + GetDiffuseLighting(surface, lightingData, intensity, p2) + + GetDiffuseLighting(surface, lightingData, intensity, p3) + + GetDiffuseLighting(surface, lightingData, intensity, dirToLightCenter) ); - translucentBackLighting += + lightingData.translucentBackLighting += ( - GetBackLighting(surface, intensity, dirToCamera, p0, 0.0) + - GetBackLighting(surface, intensity, dirToCamera, p1, 0.0) + - GetBackLighting(surface, intensity, dirToCamera, p2, 0.0) + - GetBackLighting(surface, intensity, dirToCamera, p3, 0.0) + - GetBackLighting(surface, intensity, dirToCamera, dirToLightCenter, 0.0) + GetBackLighting(surface, lightingData, intensity, p0, 0.0) + + GetBackLighting(surface, lightingData, intensity, p1, 0.0) + + GetBackLighting(surface, lightingData, intensity, p2, 0.0) + + GetBackLighting(surface, lightingData, intensity, p3, 0.0) + + GetBackLighting(surface, lightingData, intensity, dirToLightCenter, 0.0) ); // Calculate specular by choosing a single representative point on the light's surface based on the reflection ray // Then adjusting it's brightness based on different factors. // Calculate the reflection ray from the view direction and surface normal - float3 reflectionDir = reflect(-dirToCamera, surface.normal); + float3 reflectionDir = reflect(-lightingData.dirToCamera, surface.normal); // First find the reflection-plane intersection, then find the closest point on the rectangle to that intersection. float2 halfSize = float2(light.m_halfWidth, light.m_halfHeight); @@ -207,7 +207,7 @@ void ApplyQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface surfac float distanceAdjustment = 1.0 + sqrt(lightPositionDist2) * (1.0 - rough * rough * solidAngleCoverage); float3 specularintensity = light.m_rgbIntensityNits * roughnessAdjustment * distanceAdjustment; - specularLighting += GetSpecularLighting(surface, specularintensity, dirToCamera, dirToLight) * radiusAttenuation; + lightingData.specularLighting += GetSpecularLighting(surface, lightingData, specularintensity, dirToLight) * radiusAttenuation; } } } @@ -222,7 +222,7 @@ float3 SampleRectangle(float2 randomPoint, ViewSrg::QuadLight light) return outPoint; } -void ValidateQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ValidateQuadLight(ViewSrg::QuadLight light, Surface surface, inout LightingData lightingData) { float3 lightDirection = cross(light.m_leftDir, light.m_upDir); // left and up are already normalized. @@ -239,35 +239,35 @@ void ValidateQuadLight(ViewSrg::QuadLight light, float3 dirToCamera, Surface sur { float2 randomPoint = GetHammersleyPoint(i, sampleCount); float3 samplePoint = SampleRectangle(randomPoint, light); - AddSampleContribution(surface, samplePoint, lightDirection, dirToCamera, bothDirectionsFactor, diffuseAcc, specularAcc, translucentAcc); + AddSampleContribution(surface, lightingData, samplePoint, lightDirection, bothDirectionsFactor, diffuseAcc, specularAcc, translucentAcc); } float area = light.m_halfWidth * light.m_halfHeight * 4.0; float3 intensityCandelas = light.m_rgbIntensityNits * area; - diffuseLighting += (diffuseAcc / float(sampleCount)) * intensityCandelas; - translucentBackLighting += (translucentAcc / float(sampleCount)) * intensityCandelas; - specularLighting += (specularAcc / float(sampleCount)) * intensityCandelas; + lightingData.diffuseLighting += (diffuseAcc / float(sampleCount)) * intensityCandelas; + lightingData.translucentBackLighting += (translucentAcc / float(sampleCount)) * intensityCandelas; + lightingData.specularLighting += (specularAcc / float(sampleCount)) * intensityCandelas; } -void ApplyQuadLights(inout LightCullingTileIterator tileIterator, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplyQuadLights(Surface surface, inout LightingData lightingData) { - tileIterator.LoadAdvance(); + lightingData.tileIterator.LoadAdvance(); - while( !tileIterator.IsDone() ) + while( !lightingData.tileIterator.IsDone() ) { - uint currLightIndex = tileIterator.GetValue(); - tileIterator.LoadAdvance(); + uint currLightIndex = lightingData.tileIterator.GetValue(); + lightingData.tileIterator.LoadAdvance(); ViewSrg::QuadLight light = ViewSrg::m_quadLights[currLightIndex]; if (o_area_light_validation) { - ValidateQuadLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ValidateQuadLight(light, surface, lightingData); } else { - ApplyQuadLight(light, dirToCamera, surface, diffuseLighting, specularLighting, translucentBackLighting); + ApplyQuadLight(light, surface, lightingData); } } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/SpotLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/SpotLight.azsli index 7706403daf..c6ea016938 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/SpotLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/SpotLight.azsli @@ -15,7 +15,7 @@ #include #include -void ApplySpotLight(ViewSrg::SpotLight spotLight, float3 dirToCamera, Surface surface, uint lightIndex, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplySpotLight(ViewSrg::SpotLight spotLight, Surface surface, inout LightingData lightingData, uint lightIndex) { float3 posToLight = spotLight.m_position - surface.position; float distanceToLight2 = dot(posToLight, posToLight); // light distance squared @@ -98,11 +98,11 @@ void ApplySpotLight(ViewSrg::SpotLight spotLight, float3 dirToCamera, Surface su lightIntensity *= penumbraMask; } - diffuseLighting += GetDiffuseLighting(surface, lightIntensity, dirToCamera, dirToLight) * litRatio; - translucentBackLighting += GetBackLighting(surface, lightIntensity, dirToCamera, dirToLight, backShadowRatio); + lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, dirToLight) * litRatio; + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, dirToLight, backShadowRatio); // Calculate the reflection off the normal from the view lightDirection - float3 reflectionDir = reflect(-dirToCamera, surface.normal); + float3 reflectionDir = reflect(-lightingData.dirToCamera, surface.normal); float reflectionDotLight = dot(reflectionDir, -spotLight.m_direction); // Let 'Intersection' denote the point where the reflection ray intersects the diskLight plane @@ -133,20 +133,20 @@ void ApplySpotLight(ViewSrg::SpotLight spotLight, float3 dirToCamera, Surface su // Adjust the intensity of the light based on the bulb size to conserve energy float diskIntensityNormalization = GetIntensityAdjustedByRadiusAndRoughness(surface.roughnessA, spotLight.m_bulbRadius, distanceToLight2); - specularLighting += diskIntensityNormalization * GetSpecularLighting(surface, lightIntensity, dirToCamera, normalize(posToLight)) * litRatio; + lightingData.specularLighting += diskIntensityNormalization * GetSpecularLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; } } -void ApplySpotLights(inout LightCullingTileIterator tileIterator, float3 dirToCamera, Surface surface, inout float3 diffuseLighting, inout float3 specularLighting, inout float3 translucentBackLighting) +void ApplySpotLights(Surface surface, inout LightingData lightingData) { - tileIterator.LoadAdvance(); + lightingData.tileIterator.LoadAdvance(); - while( !tileIterator.IsDone() ) + while( !lightingData.tileIterator.IsDone() ) { - uint currLightIndex = tileIterator.GetValue(); - tileIterator.LoadAdvance(); + uint currLightIndex = lightingData.tileIterator.GetValue(); + lightingData.tileIterator.LoadAdvance(); ViewSrg::SpotLight light = ViewSrg::m_spotLights[currLightIndex]; - ApplySpotLight(light, dirToCamera, surface, currLightIndex, diffuseLighting, specularLighting, translucentBackLighting); + ApplySpotLight(light, surface, lightingData, currLightIndex); } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli index 1ba0a76ed7..fa60e9485d 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli @@ -23,8 +23,15 @@ #include "Ggx.azsli" #include "Fresnel.azsli" -option bool o_applySpecularAA; -option bool o_enableAnisotropy = false; + +// ------- Diffuse Lighting ------- + +//! Simple Lambertian BRDF. +float3 DiffuseLambertian(float3 albedo, float3 normal, float3 dirToLight) +{ + float NdotL = saturate(dot(normal, dirToLight)); + return albedo * NdotL * INV_PI; +} // Normalized Disney diffuse function taken from Frostbite's PBR course notes (page 10): // https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/course-notes-moving-frostbite-to-pbr-v32.pdf @@ -73,29 +80,11 @@ float3 DiffuseTitanfall(float roughnessA, float3 albedo, float3 normal, float3 d return albedo * (single + albedo * multi) * NdotL; } -//! Simple Lambertian BRDF. -float3 DiffuseLambertian(float3 albedo, float3 normal, float3 dirToLight) -{ - float NdotL = saturate(dot(normal, dirToLight)); - return albedo * NdotL * INV_PI; -} -// Specular Anti-Aliasing technique from this paper: -// http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf -float ApplySpecularAA(float roughnessA2, float3 normal) -{ - // Constants for formula below - const float screenVariance = 0.25f; - const float varianceThresh = 0.18f; - // Specular Anti-Aliasing - float3 dndu = ddx_fine( normal ); - float3 dndv = ddy_fine( normal ); - float variance = screenVariance * (dot( dndu , dndu ) + dot( dndv , dndv )); - float kernelRoughnessA2 = min(2.0 * variance , varianceThresh ); - float filteredRoughnessA2 = saturate ( roughnessA2 + kernelRoughnessA2 ); - return filteredRoughnessA2; -} + + +// ------- Specular Lighting ------- //! Computes specular response from surfaces with microgeometry. The common form for microfacet //! implementations is D * G * F / (4.0 * NdotL * NdotV), with D G F being swappable terms. @@ -103,53 +92,55 @@ float ApplySpecularAA(float roughnessA2, float3 normal) //! //! @param roughnessA2 alpha roughness ^ 2 (alpha roughness is the unpacked form of artist authored linear roughness and is what is used for lighting calculations) //! @param specularF0 the fresnel f0 spectral value of the surface -float3 SpecularGGX( Surface surface, float3 dirToCamera, float3 dirToLight) +float3 SpecularGGX( float3 dirToCamera, float3 dirToLight, float3 normal, float3 specularF0, float NdotV, float roughnessA2, float3 multiScatterCompensation ) { float3 halfVector = normalize(dirToLight + dirToCamera); - float NdotH = saturate(dot(surface.normal, halfVector)); - float NdotV = saturate(dot(surface.normal, dirToCamera)); - float NdotL = saturate(dot(surface.normal, dirToLight)); + float NdotH = saturate(dot(normal, halfVector)); + float NdotL = saturate(dot(normal, dirToLight)); float HdotV = saturate(dot(halfVector, dirToCamera)); // Note that HdotL = HdotV, so we don't need to calculate both - // Specular Anti-Aliasing correction - float roughnessA2 = surface.roughnessA * surface.roughnessA; - if(o_applySpecularAA) - { - roughnessA2 = ApplySpecularAA(roughnessA2, surface.normal); - } - // D, G and F from the lighting equation // Note: the division by (4.0 * NdotL * NdotV) is already factored out in the G function as an optimization - float D, G; - if (o_enableAnisotropy) - { - D = NormalDistibution_AnisotropicGGX( - NdotH, halfVector, surface.tangentAniso, surface.bitangentAniso, surface.anisotropyFactors ); - G = ShadowingMasking_AnisotropicSmithGGXCorrelated( - surface.tangentAniso, surface.bitangentAniso, dirToCamera, dirToLight, NdotV, NdotL, surface.anisotropyFactors ); - } - else - { - D = NormalDistributionGGX(NdotH, roughnessA2); - G = GeometricShadowingMaskingGGXCorrelated(NdotV, NdotL, roughnessA2); - } - float3 F = FresnelSchlick(HdotV, surface.specularF0); + float D = NormalDistributionGGX(NdotH, roughnessA2); + float G = GeometricShadowingMaskingGGXCorrelated(NdotV, NdotL, roughnessA2); + float3 F = FresnelSchlick(HdotV, specularF0); D = max(0.0, D); G = max(0.0, G); // Multiply with multiscattering compensation in order to take account for several specular light bounces. - return surface.multiScatterCompensation * (D * G * F * NdotL); + return multiScatterCompensation * (D * G * F * NdotL); +} + +float3 AnisotropicGGX( float3 dirToCamera, float3 dirToLight, float3 normal, float3 tangent, float3 bitangent, float2 anisotropyFactors, + float3 specularF0, float NdotV, float3 multiScatterCompensation ) +{ + float3 halfVector = normalize(dirToLight + dirToCamera); + float NdotH = saturate(dot(normal, halfVector)); + float NdotL = saturate(dot(normal, dirToLight)); + float HdotV = saturate(dot(halfVector, dirToCamera)); // Note that HdotL = HdotV, so we don't need to calculate both + + // D, G and F from the lighting equation + // Note: the division by (4.0 * NdotL * NdotV) is already factored out in the G function as an optimization + float D = NormalDistibution_AnisotropicGGX( NdotH, halfVector, tangent, bitangent, anisotropyFactors ); + float G = ShadowingMasking_AnisotropicSmithGGXCorrelated(tangent, bitangent, dirToCamera, dirToLight, NdotV, NdotL, anisotropyFactors); + float3 F = FresnelSchlick(HdotV, specularF0); + + D = max(0.0, D); + G = max(0.0, G); + + // Multiply with multiscattering compensation in order to take account for several specular light bounces. + return multiScatterCompensation * (D * G * F * NdotL); } float3 ClearCoatGGX(float NdotH, float HdotL, float NdotL, float3 normal, float roughnessA, float3 F) { // Specular Anti-Aliasing correction float roughnessA2 = roughnessA * roughnessA; - if(o_applySpecularAA) - { - roughnessA2 = ApplySpecularAA(roughnessA2, normal); - } + //if(o_applySpecularAA) + //{ + // roughnessA2 = ApplySpecularAA(roughnessA2, normal); + //} float D = NormalDistributionGGX(NdotH, roughnessA2); // Kelemen geometry term : Kelemen. C. and Szirmay-Kalos. L. 2001 diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Fresnel.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Fresnel.azsli index 5081b38504..6fc7db401a 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Fresnel.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Fresnel.azsli @@ -12,22 +12,23 @@ #pragma once +// ------- Fresnel Functions ------- + //! Calculate fresnel reflectance using the Schlick method. //! Reference Naty Hoffman, "Background: Physics and Math of Shading": https://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf Page 16, (6) //! //! @param H half vector (which coincides with the normal vector at microlevel) //! @param V view vector (or light vector; the dot product is the same for both) //! @param F0 the characteristic specular reflectance of the material. Also referred to it as specular color. -float3 FresnelSchlick(const float HdotV, const float3 F0) -{ - // At angles where (View = Normal) the dot product HdotV is 1.0 - return F0 + (float3(1.0, 1.0, 1.0) - F0) * pow(1.0 - HdotV, 5.0); -} - float3 FresnelSchlickF90(const float HdotV, const float3 F0, const float F90) { // At angles where (View = Normal) the dot product HdotV is 1.0 - return F0 + (F90 - F0) * pow(1.0 - HdotV, 5.0); + return F0 + (F90 - F0) * pow(1.0f - HdotV, 5.0f); +} + +float3 FresnelSchlick(const float HdotV, const float3 F0) +{ + return FresnelSchlickF90(HdotV, F0, 1.0f); } //! Calculate fresnel reflectance using the Schlick method, taking roughness into account. @@ -42,9 +43,9 @@ float3 FresnelSchlickF90(const float HdotV, const float3 F0, const float F90) //! @param roughness roughness value used to further attenuate the fresnel response. This is a "fudge factor" and may or may not be perceptually linear. float3 FresnelSchlickWithRoughness(const float NdotV, const float3 specularF0, const float roughness) { - float smoothness = 1.0 - roughness; + float smoothness = 1.0f - roughness; float3 F0 = specularF0; - return F0 + (max(smoothness, F0) - F0) * pow(1.0 - saturate(NdotV), 5.0); + return F0 + (max(smoothness, F0) - F0) * pow(1.0 - saturate(NdotV), 5.0f); } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Ggx.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Ggx.azsli index b7171ed910..cb0b15f4dd 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Ggx.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Ggx.azsli @@ -28,7 +28,44 @@ #include -//! Distribution function (D) for the anisotropic GGX +// ------- GGX ------- + +//! (D) Normal Distribution function for GGX +//! Provides statistical distribution of microfacet normals M around the macrosurface normal N. +//! +//! @param H potential microfacet normal, usually the half-vector between the light and the camera +//! @param N macrosurface normal +//! @param roughnessA2 alpha roughness ^ 2 (alpha roughness is the unpacked form of artist authored linear roughness and is what is used for lighting calculations) +//! @return factor for how much of the macrosurface has normals in the direction M. The value non-negative, but it's not normalized, so values are not restricted to [0, 1]. +float NormalDistributionGGX(const float NdotH, const float roughnessA2) +{ + // Walter equation 33, simplified given that the positive characteristic function is handled elsewhere + float b = (NdotH * roughnessA2 - NdotH) * NdotH + 1.0; + return roughnessA2 / (PI * b * b); +} + +//! (G) Geometric Shadowing and Masking Distribution function for GGX +//! Variant with height correlated Smith +//! +//! @param N macrosurface normal +//! @param V direction to the camera +//! @param L direction to the light +//! @param roughnessA2 alpha roughness ^ 2 (alpha roughness is the unpacked form of artist authored linear roughness and is what is used for lighting calculations) +//! @return probability that V and L are not masked. +float GeometricShadowingMaskingGGXCorrelated(const float NdotV, const float NdotL, const float roughnessA2) +{ + // See Frostbite PBR guide (page 12) + // https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/course-notes-moving-frostbite-to-pbr-v32.pdf + float ggxV = NdotL * sqrt((-NdotV * roughnessA2 + NdotV) * NdotV + roughnessA2); + float ggxL = NdotV * sqrt((-NdotL * roughnessA2 + NdotL) * NdotL + roughnessA2); + return 0.5f / max(ggxV + ggxL, GGX_EPSILON); +} + + +// ------- Anisotropic GGX ------- + +//! (D) Normal Distribution function for anisotropic GGX +//! //! @param h - half vector viewer to the light, used to approximate the reflection probability for a microfacet normal at this angle //! @param t - rotated surface tangent for calculating anisotropic response //! @param b - rotated surface bitangent for calculating anisotropic response @@ -46,7 +83,7 @@ float NormalDistibution_AnisotropicGGX( float NdotH, const float3 h, const float return a2 * w2 * w2 * (1.0 / PI); } -//! Geometric shadowing and masking distribution function (G) for the anisotropic GGX +//! (G) Geometric shadowing and masking distribution function for anisotropic GGX //! @param t - rotated surface tangent for calculating anisotropic response //! @param b - rotated surface bitangent for calculating anisotropic response //! @param anisotropyFactors - anisotropic tangent and bitangent factor @@ -66,35 +103,8 @@ float ShadowingMasking_AnisotropicSmithGGXCorrelated( return min(v, FLOAT_16_MAX); } -//! GGX normal distribution function. -//! Provides statistical distribution of microfacet normals M around the macrosurface normal N. -//! -//! @param H potential microfacet normal, usually the half-vector between the light and the camera -//! @param N macrosurface normal -//! @param roughnessA2 alpha roughness ^ 2 (alpha roughness is the unpacked form of artist authored linear roughness and is what is used for lighting calculations) -//! @return factor for how much of the macrosurface has normals in the direction M. The value non-negative, but it's not normalized, so values are not restricted to [0, 1]. -float NormalDistributionGGX(const float NdotH, const float roughnessA2) -{ - // Walter equation 33, simplified given that the positive characteristic function is handled elsewhere - float b = (NdotH * roughnessA2 - NdotH) * NdotH + 1.0; - return roughnessA2 / (PI * b * b); -} -//! GGX geometry shadowing/masking function, using the height correlated Smith -//! -//! @param N macrosurface normal -//! @param V direction to the camera -//! @param L direction to the light -//! @param roughnessA2 alpha roughness ^ 2 (alpha roughness is the unpacked form of artist authored linear roughness and is what is used for lighting calculations) -//! @return probability that V and L are not masked. -float GeometricShadowingMaskingGGXCorrelated(const float NdotV, const float NdotL, const float roughnessA2) -{ - // See Frostbite PBR guide (page 12) - // https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/course-notes-moving-frostbite-to-pbr-v32.pdf - float ggxV = NdotL * sqrt((-NdotV * roughnessA2 + NdotV) * NdotV + roughnessA2); - float ggxL = NdotV * sqrt((-NdotL * roughnessA2 + NdotL) * NdotL + roughnessA2); - return 0.5f / max(ggxV + ggxL, GGX_EPSILON); -} +// ------- Importance Sampling ------- //! Importance-sample a microgeometry normal using GGX distribution. //! diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surface.azsli index 05ac706a5e..104eaf140e 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surface.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surface.azsli @@ -12,57 +12,57 @@ #pragma once -//! The surface struct should contain all the info for a pixel that can be -//! passed onto the rendering logic for shading. -//! Note that metallic workflow can be supported by first converting to these physical properties first. -struct Surface -{ - float3 position; - float3 normal; - float3 tangentAniso; //! surface space tangent for anisotropic use - float3 bitangentAniso; //! surface space bitangent for anisotropic use - float2 anisotropyFactors; //! anisotory factors along the tangent and the bitangent directions - float3 albedo; - float3 specularF0; //!< actual fresnel f0 spectral value of the surface (as opposed to a "factor") - float3 multiScatterCompensation; //!< the constant scaling term to approximate multiscattering contribution in specular BRDF - float roughnessLinear; //!< perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use - float roughnessA; //!< actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations - float thickness; //!< pre baked local thickness, used for transmission - float4 transmissionParams; //!< parameters: thick mode->(attenuation coefficient, power, distortion, scale), thin mode: (float3 scatter distance, scale) - float clearCoatFactor; //!< clear coat strength factor - float clearCoatRoughness; //!< clear coat linear roughness (not base layer one) - float3 clearCoatNormal; //!< normal used for top layer clear coat -}; - -//! Calculate and fill the data required for fast directional anisotropty surface response. -//! Assumption: the normal and roughnessA surface properties were filled and are valid -//! Notice that since the newly created surface tangent and bitangent will be rotated -//! according to the anisotropy direction and should not be used for other purposes uness -//! rotated back. -void CalculateSurfaceDirectionalAnisotropicData( - inout Surface surface, float2 anisotropyAngleAndFactor, - float3 vtxTangent, float3 vtxBitangent ) -{ - const float anisotropyAngle = anisotropyAngleAndFactor.x; - const float anisotropyFactor = anisotropyAngleAndFactor.y; - - surface.anisotropyFactors = max( 0.01, - float2( surface.roughnessA * (1.0 + anisotropyFactor), - surface.roughnessA * (1.0 - anisotropyFactor) ) - ); - - if (anisotropyAngle > 0.01) - { - // Base rotation according to anisotropic main direction - float aniSin, aniCos; - sincos(anisotropyAngle, aniSin, aniCos); - - // Rotate the vertex tangent to get new aligned to surface normal tangent - vtxTangent = aniCos * vtxTangent - aniSin * vtxBitangent; - } - - // Now create the new surface base according to the surface normal - // If rotation was required it was already applied to the tangent, hence to the bitangent - surface.bitangentAniso = normalize(cross(surface.normal, vtxTangent)); - surface.tangentAniso = cross(surface.bitangentAniso, surface.normal); -} +// //! The surface struct should contain all the info for a pixel that can be +// //! passed onto the rendering logic for shading. +// //! Note that metallic workflow can be supported by first converting to these physical properties first. +// struct Surface +// { +// float3 position; +// float3 normal; +// float3 tangentAniso; //! surface space tangent for anisotropic use +// float3 bitangentAniso; //! surface space bitangent for anisotropic use +// float2 anisotropyFactors; //! anisotory factors along the tangent and the bitangent directions +// float3 albedo; +// float3 specularF0; //!< actual fresnel f0 spectral value of the surface (as opposed to a "factor") +// float3 multiScatterCompensation; //!< the constant scaling term to approximate multiscattering contribution in specular BRDF +// float roughnessLinear; //!< perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use +// float roughnessA; //!< actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations +// float thickness; //!< pre baked local thickness, used for transmission +// float4 transmissionParams; //!< parameters: thick mode->(attenuation coefficient, power, distortion, scale), thin mode: (float3 scatter distance, scale) +// float clearCoatFactor; //!< clear coat strength factor +// float clearCoatRoughness; //!< clear coat linear roughness (not base layer one) +// float3 clearCoatNormal; //!< normal used for top layer clear coat +// }; +// +// //! Calculate and fill the data required for fast directional anisotropty surface response. +// //! Assumption: the normal and roughnessA surface properties were filled and are valid +// //! Notice that since the newly created surface tangent and bitangent will be rotated +// //! according to the anisotropy direction and should not be used for other purposes uness +// //! rotated back. +// void CalculateSurfaceDirectionalAnisotropicData( +// inout Surface surface, float2 anisotropyAngleAndFactor, +// float3 vtxTangent, float3 vtxBitangent ) +// { +// const float anisotropyAngle = anisotropyAngleAndFactor.x; +// const float anisotropyFactor = anisotropyAngleAndFactor.y; +// +// surface.anisotropyFactors = max( 0.01, +// float2( surface.roughnessA * (1.0 + anisotropyFactor), +// surface.roughnessA * (1.0 - anisotropyFactor) ) +// ); +// +// if (anisotropyAngle > 0.01) +// { +// // Base rotation according to anisotropic main direction +// float aniSin, aniCos; +// sincos(anisotropyAngle, aniSin, aniCos); +// +// // Rotate the vertex tangent to get new aligned to surface normal tangent +// vtxTangent = aniCos * vtxTangent - aniSin * vtxBitangent; +// } +// +// // Now create the new surface base according to the surface normal +// // If rotation was required it was already applied to the tangent, hence to the bitangent +// surface.bitangentAniso = normalize(cross(surface.normal, vtxTangent)); +// surface.tangentAniso = cross(surface.bitangentAniso, surface.normal); +// } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/AnisotropicSurfaceData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/AnisotropicSurfaceData.azsli new file mode 100644 index 0000000000..6db36fda53 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/AnisotropicSurfaceData.azsli @@ -0,0 +1,53 @@ +/* +* 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 + +option bool o_enableAnisotropy = false; + +// ------- Surface Data ------- + +class AnisotropicSurfaceData +{ + float3 tangent; //!< surface space tangent for anisotropic use + float3 bitangent; //!< surface space bitangent for anisotropic use + float2 anisotropyFactors; //!< anisotory factors along the tangent and the bitangent directions + + void Init(float3 normal, float3 vtxTangent, float3 vtxBitangent, float anisotropyAngle, float anisotropyFactor, float roughnessA); +}; + +// ------- Functions ------- + +//! Notice that since the newly created surface tangent and bitangent will be rotated according +//! to the anisotropy direction and should not be used for other purposes unless rotated back. +void AnisotropicSurfaceData::Init(float3 normal, float3 vtxTangent, float3 vtxBitangent, float anisotropyAngle, float anisotropyFactor, float roughnessA) +{ + anisotropyFactors = max( 0.01, + float2( roughnessA * (1.0 + anisotropyFactor), + roughnessA * (1.0 - anisotropyFactor) ) + ); + + if (anisotropyAngle > 0.01) + { + // Base rotation according to anisotropic main direction + float aniSin, aniCos; + sincos(anisotropyAngle, aniSin, aniCos); + + // Rotate the vertex tangent to get new aligned to surface normal tangent + vtxTangent = aniCos * vtxTangent - aniSin * vtxBitangent; + } + + // Now create the new surface base according to the surface normal + // If rotation was required it was already applied to the tangent, hence to the bitangent + bitangent = normalize(cross(normal, vtxTangent)); + tangent = cross(bitangent, normal); +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/BasePbrSurfaceData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/BasePbrSurfaceData.azsli new file mode 100644 index 0000000000..da4c44e1d8 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/BasePbrSurfaceData.azsli @@ -0,0 +1,92 @@ +/* +* 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 + +option bool o_applySpecularAA; + +// ------- Constants ------- + +// For artists workflows, specular F0 for dialectric (non-metal) materials is exposed as a 0-1 scale +// However the specular F0 for dialectrics is much lower than metals, so we expose this scaling factor here +static const float3 MaxDielectricSpecularF0 = 0.08f; + +// Make sure roughnessA is above 0 to avoid precision and divide by zero issues. +// 0.0005f is sufficient for directional lights since they tend to be quite bright. +static const float MinRoughnessA = 0.0005f; + +// ------- Surface Data ------- + +class BasePbrSurfaceData +{ + float3 position; //!< Position in world-space + float3 normal; //!< Normal in world-space + float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value + float3 specularF0; //!< Fresnel f0 spectral value of the surface + float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use + float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations + float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance + + //! Applies specular anti-aliasing to roughnessA2 + void ApplySpecularAA(); + + //! Calculates roughnessA and roughnessA2 after roughness has been set + void CalculateRoughnessA(); + + //! Sets albedo and specularF0 using metallic workflow + void SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic); +}; + +// ------- Functions ------- + +// Specular Anti-Aliasing technique from this paper: +// http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf +void BasePbrSurfaceData::ApplySpecularAA() +{ + // Constants for formula below + const float screenVariance = 0.25f; + const float varianceThresh = 0.18f; + + // Specular Anti-Aliasing + float3 dndu = ddx_fine( normal ); + float3 dndv = ddy_fine( normal ); + float variance = screenVariance * (dot( dndu , dndu ) + dot( dndv , dndv )); + float kernelRoughnessA2 = min(2.0 * variance , varianceThresh ); + float filteredRoughnessA2 = saturate ( roughnessA2 + kernelRoughnessA2 ); + roughnessA2 = filteredRoughnessA2; +} + +void BasePbrSurfaceData::CalculateRoughnessA() +{ + // The roughness value in microfacet calculations (called "alpha" in the literature) does not give perceptually + // linear results. Disney found that squaring the roughness value before using it in microfacet equations causes + // the user-provided roughness parameter to be more perceptually linear. We keep both values available as some + // equations need roughnessLinear (i.e. IBL sampling) while others need roughnessA (i.e. GGX equations). + // See Burley's Disney PBR: https://pdfs.semanticscholar.org/eeee/3b125c09044d3e2f58ed0e4b1b66a677886d.pdf + + roughnessA = max(roughnessLinear * roughnessLinear, MinRoughnessA); + + roughnessA2 = roughnessA * roughnessA; + if(o_applySpecularAA) + { + ApplySpecularAA(); + } +} + +void BasePbrSurfaceData::SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic) +{ + float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * inSpecularF0; + + // Compute albedo and specularF0 based on metalness + albedo = lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic); + specularF0 = lerp(dielectricSpecularF0, baseColor, metallic); +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli new file mode 100644 index 0000000000..c0fc626075 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli @@ -0,0 +1,20 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +class ClearCoatSurfaceData +{ + float factor; //!< clear coat strength factor + float roughness; //!< clear coat linear roughness (not base layer one) + float3 normal; //!< normal used for top layer clear coat +}; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/DualSpecularSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/DualSpecularSurface.azsli new file mode 100644 index 0000000000..7c93f8e35b --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/DualSpecularSurface.azsli @@ -0,0 +1,26 @@ +/* +* 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 +#include +#include +#include + +class Surface +{ + BasePbrSurfaceData pbr; + //AnisotropicSurfaceData anisotropy; + TransmissionSurfaceData transmission; +}; + diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli new file mode 100644 index 0000000000..9d4163c474 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli @@ -0,0 +1,91 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#include +#include +#include +#include + +class Surface //: BasePbrSurfaceData +{ + //BasePbrSurfaceData pbr; + AnisotropicSurfaceData anisotropy; + ClearCoatSurfaceData clearCoat; + TransmissionSurfaceData transmission; + + // ------- BasePbrSurfaceData ------- + + float3 position; //!< Position in world-space + float3 normal; //!< Normal in world-space + float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value + float3 specularF0; //!< Fresnel f0 spectral value of the surface + float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use + float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations + float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance + + //! Applies specular anti-aliasing to roughnessA2 + void ApplySpecularAA(); + + //! Calculates roughnessA and roughnessA2 after roughness has been set + void CalculateRoughnessA(); + + //! Sets albedo and specularF0 using metallic workflow + void SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic); + +}; + + +// Specular Anti-Aliasing technique from this paper: +// http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf +void Surface::ApplySpecularAA() +{ + // Constants for formula below + const float screenVariance = 0.25f; + const float varianceThresh = 0.18f; + + // Specular Anti-Aliasing + float3 dndu = ddx_fine( normal ); + float3 dndv = ddy_fine( normal ); + float variance = screenVariance * (dot( dndu , dndu ) + dot( dndv , dndv )); + float kernelRoughnessA2 = min(2.0 * variance , varianceThresh ); + float filteredRoughnessA2 = saturate ( roughnessA2 + kernelRoughnessA2 ); + roughnessA2 = filteredRoughnessA2; +} + +void Surface::CalculateRoughnessA() +{ + // The roughness value in microfacet calculations (called "alpha" in the literature) does not give perceptually + // linear results. Disney found that squaring the roughness value before using it in microfacet equations causes + // the user-provided roughness parameter to be more perceptually linear. We keep both values available as some + // equations need roughnessLinear (i.e. IBL sampling) while others need roughnessA (i.e. GGX equations). + // See Burley's Disney PBR: https://pdfs.semanticscholar.org/eeee/3b125c09044d3e2f58ed0e4b1b66a677886d.pdf + + roughnessA = max(roughnessLinear * roughnessLinear, MinRoughnessA); + + roughnessA2 = roughnessA * roughnessA; + if(o_applySpecularAA) + { + ApplySpecularAA(); + } +} + +void Surface::SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic) +{ + float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * inSpecularF0; + + // Compute albedo and specularF0 based on metalness + albedo = lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic); + specularF0 = lerp(dielectricSpecularF0, baseColor, metallic); +} + diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli new file mode 100644 index 0000000000..987e4ea575 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli @@ -0,0 +1,20 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +class TransmissionSurfaceData +{ + float3 tint; + float thickness; //!< pre baked local thickness, used for transmission + float4 transmissionParams; //!< parameters: thick mode->(attenuation coefficient, power, distortion, scale), thin mode: (float3 scatter distance, scale) +}; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli index c0b6331fab..0e9ab3e300 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli @@ -152,4 +152,4 @@ float SampleShadowMapBicubic_16Tap(SampleShadowMapBicubicParameters param) shadow /= 2704; return shadow * shadow; -} \ No newline at end of file +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/SrgSemantics.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/SrgSemantics.azsli index 38ffe24c87..c134a9d293 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/SrgSemantics.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/SrgSemantics.azsli @@ -63,4 +63,4 @@ ShaderResourceGroupSemantic SRG_RayTracingGlobal ShaderResourceGroupSemantic SRG_RayTracingScene { FrequencyId = 1; -}; \ No newline at end of file +}; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Vertex/VertexHelper.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Vertex/VertexHelper.azsli new file mode 100644 index 0000000000..24cca8dc87 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Vertex/VertexHelper.azsli @@ -0,0 +1,57 @@ +/* +* 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 + +// ------------------------------------------------------------------------------ +// NOTE: VSInput, VSOutput, ObjectSrg must be defined before including this file. +// --------------------------------------------------------------------------------- + +// Options +#include + +// Shader Resource Groups +#include +#include +#include +#include +#include + +// Math +#include +#include + +// Shadow Coords +#include + + +//! @param skipShadowCoords can be useful for example when PixelDepthOffset is enable, because the pixel shader will have to run before the final world position is known +void VertexHelper(in VSInput IN, inout VSOutput OUT, float3 worldPosition, bool skipShadowCoords = false) +{ + OUT.m_worldPosition = worldPosition; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(OUT.m_worldPosition, 1.0)); + + float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); + float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose(); + + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + + // directional light shadow + const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; + if (o_enableShadows && !skipShadowCoords && shadowIndex < SceneSrg::m_directionalLightCount) + { + DirectionalLightShadow::GetShadowCoords( + shadowIndex, + worldPosition, + OUT.m_shadowCoords); + } +} diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/AcesOutputTransformLut.shader b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/AcesOutputTransformLut.shader index 981d0e9603..69ffb44394 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/AcesOutputTransformLut.shader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/AcesOutputTransformLut.shader @@ -5,8 +5,6 @@ "Depth" : { "Enable" : false } }, - "CompilerVersion" : "1.0", - "ProgramSettings": { "EntryPoints": diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ApplyShaperLookupTable.shader b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ApplyShaperLookupTable.shader index 18a94d8f9f..ec18e33e7d 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ApplyShaperLookupTable.shader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ApplyShaperLookupTable.shader @@ -5,8 +5,6 @@ "Depth" : { "Enable" : false } }, - "CompilerVersion" : "1.0", - "ProgramSettings": { "EntryPoints": diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen.azsl index 136e205d49..6e41e5123c 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen.azsl @@ -102,7 +102,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) float NdotV = saturate(dot(normal, dirToCamera)); NdotV = max(NdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles. float2 brdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(roughness, NdotV)).rg; - float3 multiScatterCompensation = GetMultiScatterCompensation(NdotV, specularF0, brdf, multiScatterCompensationEnabled); + float3 multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, multiScatterCompensationEnabled); float3 specular = blendWeight * globalSpecular * multiScatterCompensation * (specularF0 * brdf.x + brdf.y); float4 encodedClearCoatNormal = PassSrg::m_clearCoatNormal.Load(IN.m_position.xy, sampleIndex); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.azsl index eb1899e21f..f90048b7ab 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.azsl @@ -123,7 +123,7 @@ PSOutput MainPS(VSOutput IN) float NdotV = saturate(dot(normal, dirToCamera)); NdotV = max(NdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles. float2 brdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(roughness, NdotV)).rg; - float3 multiScatterCompensation = GetMultiScatterCompensation(NdotV, specularF0, brdf, multiScatterCompensationEnabled); + float3 multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, multiScatterCompensationEnabled); float3 specular = blendWeight * globalSpecular * multiScatterCompensation * (specularF0 * brdf.x + brdf.y); float4 encodedClearCoatNormal = PassSrg::m_clearCoatNormal.Load(int3(IN.m_position.xy, 0)); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli index 8b4d391a62..d81477fdd9 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli @@ -58,7 +58,7 @@ bool ComputeProbeSpecular(float2 screenCoords, float3 positionWS, float3 aabbMin float3 probeSpecular = ObjectSrg::m_reflectionCubeMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(localReflectDir), GetRoughnessMip(roughness)).rgb; // compute final specular amount - float3 multiScatterCompensation = GetMultiScatterCompensation(NdotV, specularF0, brdf, multiScatterCompensationEnabled); + float3 multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, multiScatterCompensationEnabled); specular = probeSpecular * multiScatterCompensation * (specularF0.xyz * brdf.x + brdf.y); // compute clear coat specular amount diff --git a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake index 44b0b590b2..91bb1999c2 100644 --- a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake +++ b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake @@ -23,6 +23,11 @@ set(FILES Materials/Types/EnhancedPBR_ForwardPass_EDS.shader Materials/Types/EnhancedPBR_Shadowmap_WithPS.azsl Materials/Types/EnhancedPBR_Shadowmap_WithPS.shader + Materials/Types/Skin.azsl + Materials/Types/Skin.materialtype + Materials/Types/Skin.shader + Materials/Types/Skin_Common.azsli + Materials/Types/Skin_WrinkleMaps.lua Materials/Types/StandardMultilayerPBR.materialtype Materials/Types/StandardMultilayerPBR_ClearCoatEnableFeature.lua Materials/Types/StandardMultilayerPBR_Common.azsli @@ -57,6 +62,7 @@ set(FILES Materials/Types/MaterialInputs/AlphaInput.azsli Materials/Types/MaterialInputs/BaseColorInput.azsli Materials/Types/MaterialInputs/ClearCoatInput.azsli + Materials/Types/MaterialInputs/DetailMapsCommonFunctor.lua Materials/Types/MaterialInputs/DetailMapsInput.azsli Materials/Types/MaterialInputs/EmissiveInput.azsli Materials/Types/MaterialInputs/MetallicInput.azsli @@ -106,6 +112,7 @@ set(FILES Passes/DepthUpsample.pass Passes/DiffuseComposite.pass Passes/DiffuseGlobalFullscreen.pass + Passes/DiffuseGlobalFullscreen_nomsaa.pass Passes/DiffuseGlobalIllumination.pass Passes/DiffuseProbeGridBlendDistance.pass Passes/DiffuseProbeGridBlendIrradiance.pass @@ -162,6 +169,7 @@ set(FILES Passes/ReflectionComposite.pass Passes/ReflectionCopyFrameBuffer.pass Passes/ReflectionGlobalFullscreen.pass + Passes/ReflectionGlobalFullscreen_nomsaa.pass Passes/ReflectionProbeBlendWeight.pass Passes/ReflectionProbeRenderInner.pass Passes/ReflectionProbeRenderOuter.pass @@ -173,6 +181,7 @@ set(FILES Passes/ReflectionScreenSpaceBlurVertical.pass Passes/ReflectionScreenSpaceComposite.pass Passes/ReflectionScreenSpaceTrace.pass + Passes/Reflections_nomsaa.pass Passes/ShadowParent.pass Passes/Skinning.pass Passes/SkyBox.pass @@ -191,6 +200,8 @@ set(FILES Passes/TransparentParent.pass Passes/UI.pass Passes/UIParent.pass + Scripts/material_property_overrides_demo.lua + ShaderLib/Atom/Features/BlendUtility.azsli ShaderLib/Atom/Features/IndirectRendering.azsli ShaderLib/Atom/Features/MatrixUtility.azsli ShaderLib/Atom/Features/ParallaxMapping.azsli @@ -212,6 +223,7 @@ set(FILES ShaderLib/Atom/Features/Math/Filter.azsli ShaderLib/Atom/Features/Math/FilterPassSrg.azsli ShaderLib/Atom/Features/Math/IntersectionTests.azsli + ShaderLib/Atom/Features/MorphTargets/MorphTargetCompression.azsli ShaderLib/Atom/Features/PBR/AlphaUtils.azsli ShaderLib/Atom/Features/PBR/BackLighting.azsli ShaderLib/Atom/Features/PBR/Decals.azsli @@ -220,21 +232,33 @@ set(FILES ShaderLib/Atom/Features/PBR/ForwardPassSrg.azsli ShaderLib/Atom/Features/PBR/Hammersley.azsli ShaderLib/Atom/Features/PBR/LightingModel.azsli + ShaderLib/Atom/Features/PBR/LightingOptions.azsli ShaderLib/Atom/Features/PBR/LightingUtils.azsli ShaderLib/Atom/Features/PBR/Surface.azsli ShaderLib/Atom/Features/PBR/TransparentPassSrg.azsli + ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli + ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli + ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli + ShaderLib/Atom/Features/PBR/Lights/Lights.azsli ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli + ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli ShaderLib/Atom/Features/PBR/Lights/SpotLight.azsli ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli ShaderLib/Atom/Features/PBR/Microfacet/Fresnel.azsli ShaderLib/Atom/Features/PBR/Microfacet/Ggx.azsli + ShaderLib/Atom/Features/PBR/Surfaces/AnisotropicSurfaceData.azsli + ShaderLib/Atom/Features/PBR/Surfaces/BasePbrSurfaceData.azsli + ShaderLib/Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli + ShaderLib/Atom/Features/PBR/Surfaces/DualSpecularSurface.azsli + ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli + ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli ShaderLib/Atom/Features/PostProcessing/Aces.azsli ShaderLib/Atom/Features/PostProcessing/AcesColorSpaceConversion.azsli ShaderLib/Atom/Features/PostProcessing/FullscreenPixelInfo.azsli @@ -245,6 +269,7 @@ set(FILES ShaderLib/Atom/Features/PostProcessing/GlyphRender.azsli ShaderLib/Atom/Features/PostProcessing/PostProcessUtil.azsli ShaderLib/Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli + ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli ShaderLib/Atom/Features/Shadow/JitterTablePcf.azsli ShaderLib/Atom/Features/Shadow/Shadow.azsli @@ -279,10 +304,16 @@ set(FILES Shaders/Depth/DepthPassTransparentMin.shader Shaders/DiffuseGlobalIllumination/DiffuseComposite.azsl Shaders/DiffuseGlobalIllumination/DiffuseComposite.shader + Shaders/DiffuseGlobalIllumination/DiffuseComposite_nomsaa.azsl + Shaders/DiffuseGlobalIllumination/DiffuseComposite_nomsaa.shader Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen.azsl Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen.shader + Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen_nomsaa.azsl + Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen_nomsaa.shader Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample.azsl Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample.shader + Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample_nomsaa.azsl + Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample_nomsaa.shader Shaders/ImGui/ImGui.azsl Shaders/ImGui/ImGui.shader Shaders/LightCulling/LightCulling.azsl @@ -398,8 +429,12 @@ set(FILES Shaders/Reflections/ReflectionCommon.azsli Shaders/Reflections/ReflectionComposite.azsl Shaders/Reflections/ReflectionComposite.shader + Shaders/Reflections/ReflectionComposite_nomsaa.azsl + Shaders/Reflections/ReflectionComposite_nomsaa.shader Shaders/Reflections/ReflectionGlobalFullscreen.azsl Shaders/Reflections/ReflectionGlobalFullscreen.shader + Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.azsl + Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.shader Shaders/Reflections/ReflectionProbeBlendWeight.azsl Shaders/Reflections/ReflectionProbeBlendWeight.shader Shaders/Reflections/ReflectionProbeRenderCommon.azsli diff --git a/Gems/Atom/RPI/Assets/Materials/DefaultMaterial.azsl b/Gems/Atom/RPI/Assets/Materials/DefaultMaterial.azsl index d74dd3959c..fd3558c276 100644 --- a/Gems/Atom/RPI/Assets/Materials/DefaultMaterial.azsl +++ b/Gems/Atom/RPI/Assets/Materials/DefaultMaterial.azsl @@ -106,7 +106,7 @@ PixelOutput MainPS(VertexOutput input) if (o_useNormalMap) { float4 sampledValue = MaterialSrg::m_normalMap.Sample(MaterialSrg::m_sampler, input.m_uv); - normal = GetWorldSpaceNormal(sampledValue, input.m_normal, input.m_tangent, input.m_bitangent); + normal = GetWorldSpaceNormal(sampledValue.xy, input.m_normal, input.m_tangent, input.m_bitangent); } else { diff --git a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli index 077a2676d2..2381febed0 100644 --- a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli +++ b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli @@ -224,4 +224,4 @@ float NextRandomFloatUniform(inout uint seed) { seed = Xorshift(seed); return (float)seed / 4294967295.0f; -} \ No newline at end of file +} diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp index 29adc2176d..6a1897815f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp @@ -138,31 +138,14 @@ namespace AZ AZStd::array_view ModelKdTree::GetPositionsBuffer(const ModelLodAsset::Mesh& mesh) { - const BufferAssetView* positionBufferAssetView = mesh.GetSemanticBufferAssetView(AZ::Name{"POSITION"}); - if (positionBufferAssetView) - { - const AZStd::array_view positionRawBuffer = positionBufferAssetView->GetBufferAsset()->GetBuffer(); - const auto size = positionBufferAssetView->GetBufferViewDescriptor().m_elementSize; - return { - reinterpret_cast(positionRawBuffer.data() + positionBufferAssetView->GetBufferViewDescriptor().m_elementOffset * size), - positionBufferAssetView->GetBufferViewDescriptor().m_elementCount * size / sizeof(float) - }; - } - - AZ_Warning("ModelKdTree", false, "Could not find position buffers in a mesh"); - return {}; + AZStd::array_view positionBuffer = mesh.GetSemanticBufferTyped(AZ::Name{"POSITION"}); + AZ_Warning("ModelKdTree", !positionBuffer.empty(), "Could not find position buffers in a mesh"); + return positionBuffer; } AZStd::array_view ModelKdTree::GetIndexBuffer(const ModelLodAsset::Mesh& mesh) { - const BufferAssetView& indexBufferAssetView = mesh.GetIndexBufferAssetView(); - const AZStd::array_view indexRawBuffer = indexBufferAssetView.GetBufferAsset()->GetBuffer(); - const auto size = indexBufferAssetView.GetBufferViewDescriptor().m_elementSize; - static_assert(sizeof(TriangleIndices) == 3 * sizeof(uint32_t)); - return { - reinterpret_cast(indexRawBuffer.data() + indexBufferAssetView.GetBufferViewDescriptor().m_elementOffset * size), - indexBufferAssetView.GetBufferViewDescriptor().m_elementCount * size / sizeof(TriangleIndices) - }; + return mesh.GetIndexBufferTyped(); } void ModelKdTree::BuildRecursively(ModelKdTreeNode* pNode, const AZ::Aabb& boundbox, AZStd::vector& indices) diff --git a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl index 6607228673..f484006fe1 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl @@ -39,6 +39,7 @@ struct VSOutput }; #include +#include VSOutput AutoBrick_ForwardPassVS(VSInput IN) { @@ -48,7 +49,7 @@ VSOutput AutoBrick_ForwardPassVS(VSInput IN) OUT.m_uv = IN.m_uv; - PbrVsHelper(IN, OUT, worldPosition); + VertexHelper(IN, OUT, worldPosition); return OUT; } diff --git a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl index 8f23239437..64903eb1db 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl @@ -43,6 +43,7 @@ struct VSOutput }; #include +#include VSOutput MinimalPBR_MainPassVS(VSInput IN) { @@ -50,7 +51,7 @@ VSOutput MinimalPBR_MainPassVS(VSInput IN) float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz; - PbrVsHelper(IN, OUT, worldPosition); + VertexHelper(IN, OUT, worldPosition); return OUT; } diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index 344e9564ea..93f94475e4 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -44,6 +44,7 @@ namespace AtomToolsFramework //! Requires the Atom RPI to be initialized in order //! to internally construct an RPI::ViewportContext. explicit RenderViewportWidget(AzFramework::ViewportId id = AzFramework::InvalidViewportId, QWidget* parent = nullptr); + ~RenderViewportWidget(); //! Gets the name associated with this viewport's ViewportContext. //! This context name can be used to adjust the current Camera @@ -93,8 +94,8 @@ namespace AtomToolsFramework // AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Handler ... void BeginCursorCapture() override; void EndCursorCapture() override; - QPoint ViewportCursorScreenPosition() override; - AZStd::optional PreviousViewportCursorScreenPosition() override; + AzFramework::ScreenPoint ViewportCursorScreenPosition() override; + AZStd::optional PreviousViewportCursorScreenPosition() override; // AzFramework::WindowRequestBus::Handler ... void SetWindowTitle(const AZStd::string& title) override; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 132ef3a0a4..142de886e2 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -54,12 +55,22 @@ namespace AtomToolsFramework AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Handler::BusConnect(GetId()); AzFramework::InputChannelEventListener::Connect(); AZ::TickBus::Handler::BusConnect(); + AzFramework::WindowRequestBus::Handler::BusConnect(params.windowHandle); setUpdatesEnabled(false); setFocusPolicy(Qt::FocusPolicy::WheelFocus); setMouseTracking(true); } + RenderViewportWidget::~RenderViewportWidget() + { + AzFramework::WindowRequestBus::Handler::BusDisconnect(); + AZ::TickBus::Handler::BusDisconnect(); + AzFramework::InputChannelEventListener::Disconnect(); + AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Handler::BusDisconnect(); + AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler::BusDisconnect(); + } + void RenderViewportWidget::LockRenderTargetSize(uint32_t width, uint32_t height) { setFixedSize(aznumeric_cast(width), aznumeric_cast(height)); @@ -183,7 +194,8 @@ namespace AtomToolsFramework return false; } - return m_controllerList->HandleInputChannelEvent({GetId(), inputChannel}); + AzFramework::NativeWindowHandle windowId = reinterpret_cast(winId()); + return m_controllerList->HandleInputChannelEvent({GetId(), windowId, inputChannel}); } void RenderViewportWidget::OnTick([[maybe_unused]]float deltaTime, AZ::ScriptTimePoint time) @@ -234,14 +246,16 @@ namespace AtomToolsFramework // Now that we've looked a viewport local mouse position, // we can go ahead and broadcast the system cursor input event to the controllers. - // This allows any controllers not listening to pure mosue deltas to consistently + // This allows any controllers not listening to pure mouse deltas to consistently // look up the mouse position in viewport screen coordinates. const AzFramework::InputDevice* mouseInputDevice = nullptr; - if (AzFramework::InputDeviceRequestBus::EventResult(mouseInputDevice, AzFramework::InputDeviceMouse::Id, &AzFramework::InputDeviceRequests::GetInputDevice); + if (AzFramework::InputDeviceRequestBus::EventResult( + mouseInputDevice, AzFramework::InputDeviceMouse::Id, &AzFramework::InputDeviceRequests::GetInputDevice); mouseInputDevice != nullptr) { + const AzFramework::NativeWindowHandle windowId = reinterpret_cast(winId()); AzFramework::InputChannel syntheticInput(AzFramework::InputDeviceMouse::SystemCursorPosition, *mouseInputDevice); - m_controllerList->HandleInputChannelEvent({GetId(), syntheticInput}); + m_controllerList->HandleInputChannelEvent({GetId(), windowId, syntheticInput}); } if (m_capturingCursor && m_lastCursorPosition.has_value()) @@ -262,7 +276,7 @@ namespace AtomToolsFramework const qreal deficePixelRatio = devicePixelRatioF(); const QSize windowSize = uiWindowSize * deficePixelRatio; - AzFramework::NativeWindowHandle windowId = reinterpret_cast(winId()); + const AzFramework::NativeWindowHandle windowId = reinterpret_cast(winId()); AzFramework::WindowNotificationBus::Event(windowId, &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height()); m_windowResizedEvent = false; } @@ -391,7 +405,8 @@ namespace AtomToolsFramework return projectedPosition.GetAsVector3() / projectedPosition.GetW(); } - AZStd::optional RenderViewportWidget::ViewportScreenToWorldRay(const QPoint& screenPosition) + AZStd::optional RenderViewportWidget::ViewportScreenToWorldRay( + const QPoint& screenPosition) { auto pos0 = ViewportScreenToWorld(screenPosition, 0.f); auto pos1 = ViewportScreenToWorld(screenPosition, 1.f); @@ -407,14 +422,16 @@ namespace AtomToolsFramework return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{rayOrigin, rayDirection}; } - QPoint RenderViewportWidget::ViewportCursorScreenPosition() + AzFramework::ScreenPoint RenderViewportWidget::ViewportCursorScreenPosition() { - return m_mousePosition.toPoint(); + return AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(m_mousePosition.toPoint()); } - AZStd::optional RenderViewportWidget::PreviousViewportCursorScreenPosition() + AZStd::optional RenderViewportWidget::PreviousViewportCursorScreenPosition() { - return m_lastCursorPosition.has_value() ? mapFromGlobal(m_lastCursorPosition.value()) : m_lastCursorPosition; + using AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint; + return m_lastCursorPosition.has_value() ? ScreenPointFromQPoint(mapFromGlobal(m_lastCursorPosition.value())) + : AZStd::optional{}; } void RenderViewportWidget::BeginCursorCapture() diff --git a/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt index 143bd04c51..1066cc33e8 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt @@ -23,7 +23,7 @@ ly_add_target( Source BUILD_DEPENDENCIES PRIVATE - 3rdParty::FreeType2 + 3rdParty::freetype AZ::AzCore AZ::AtomCore Legacy::CryCommon diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index 9da227c26b..88b0e812d2 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -290,7 +290,7 @@ namespace AZ void MeshComponentController::UnregisterModel() { - if (m_meshFeatureProcessor) + if (m_meshFeatureProcessor && m_meshHandle.IsValid()) { MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelPreDestroy); m_meshFeatureProcessor->ReleaseMesh(m_meshHandle); diff --git a/Gems/EMotionFX/Code/Tests/MotionExtractionTests.cpp b/Gems/EMotionFX/Code/Tests/MotionExtractionTests.cpp index c36c26efbb..cdfb0c9519 100644 --- a/Gems/EMotionFX/Code/Tests/MotionExtractionTests.cpp +++ b/Gems/EMotionFX/Code/Tests/MotionExtractionTests.cpp @@ -307,9 +307,9 @@ namespace EMotionFX const float updatedPositionY = m_actorInstance->GetWorldSpaceTransform().mPosition.GetY(); const float actualDeltaX = AZ::GetAbs(updatedPositionX - originalPositionX); const float actualDeltaY = AZ::GetAbs(updatedPositionY - originalPositionY); - EXPECT_TRUE(AZ::GetAbs(actualDeltaX - expectedDeltaX) < 0.001f) + EXPECT_NEAR(actualDeltaX, expectedDeltaX, 0.001f) << "Diagonal Rotation: The absolute difference between actual delta and expected delta of X-axis should be less than 0.001f."; - EXPECT_TRUE(AZ::GetAbs(actualDeltaY - expectedDeltaY) < 0.001f) + EXPECT_NEAR(actualDeltaY, expectedDeltaY, 0.001f) << "Diagonal Rotation: The absolute difference between actual delta and expected delta of Y-axis should be less than 0.001f."; } } diff --git a/Gems/ImageProcessing/Code/CMakeLists.txt b/Gems/ImageProcessing/Code/CMakeLists.txt index 356ec3d8a1..a5cb6f6cb9 100644 --- a/Gems/ImageProcessing/Code/CMakeLists.txt +++ b/Gems/ImageProcessing/Code/CMakeLists.txt @@ -64,6 +64,7 @@ ly_add_target( 3rdParty::etc2comp 3rdParty::PVRTexTool 3rdParty::squish-ccr + 3rdParty::zlib 3rdParty::tiff Legacy::CryCommon AZ::AzCore diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h index cbd34abaf2..2d5c8eb1e3 100644 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h +++ b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h @@ -105,7 +105,7 @@ namespace ImageProcessing { } - explicit ColorRGBA16(uint64 a_u) + explicit ColorRGBA16(AZ::u64 a_u) : u(a_u) { } @@ -152,7 +152,7 @@ namespace ImageProcessing uint16 b; uint16 a; }; - uint64 u; + AZ::u64 u; }; }; diff --git a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp b/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp index 90691407d1..64fee3b747 100644 --- a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp +++ b/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp @@ -219,7 +219,7 @@ namespace ImageProcessing srcImage->GetImagePointer(mip, srcMem, srcPitch); const pvrtexture::CPVRTextureHeader srcHeader( - srcPixelType.PixelTypeID, // uint64 u64PixelFormat, + srcPixelType.PixelTypeID, // AZ::u64 u64PixelFormat, width, // uint32 u32Height=1, height, // uint32 u32Width=1, 1, // uint32 u32Depth=1, @@ -310,7 +310,7 @@ namespace ImageProcessing // Preparing source compressed data const pvrtexture::CPVRTextureHeader compressedHeader( - FindPvrPixelFormat(fmtSrc), // uint64 u64PixelFormat, + FindPvrPixelFormat(fmtSrc), // AZ::u64 u64PixelFormat, width, // uint32 u32Height=1, height, // uint32 u32Width=1, 1, // uint32 u32Depth=1, diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h b/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h index 7556fa638c..962cd81668 100644 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h +++ b/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h @@ -25,9 +25,5 @@ typedef AZ::s32 int32; typedef AZ::s32 sint32; typedef AZ::u32 uint32; -typedef AZ::s64 int64; -typedef AZ::s64 sint64; -typedef AZ::u64 uint64; - typedef float f32; typedef double f64; diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp index 4134719bcc..6c2881423d 100644 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp +++ b/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp @@ -22,7 +22,7 @@ #include -#include // TIFF library +#include // TIFF library namespace ImageProcessing { diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index 6f76144046..9c46a61236 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -87,6 +87,8 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) Legacy::CryCommon Gem::LmbrCentral Gem::TextureAtlas + Gem::AtomToolsFramework.Static + Gem::AtomToolsFramework.Editor ${additional_dependencies} PUBLIC Gem::Atom_RPI.Public diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.cpp b/Gems/LyShine/Code/Editor/ViewportWidget.cpp index eae2b05633..c805d45bef 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.cpp +++ b/Gems/LyShine/Code/Editor/ViewportWidget.cpp @@ -22,6 +22,8 @@ #include +#include "LyShine.h" +#include "UiRenderer.h" #include "ViewportNudge.h" #include "ViewportPivot.h" #include "ViewportSnap.h" @@ -34,6 +36,9 @@ #include +#include +#include + #define UICANVASEDITOR_SETTINGS_VIEWPORTWIDGET_DRAW_ELEMENT_BORDERS_KEY "ViewportWidget::m_drawElementBordersFlags" #define UICANVASEDITOR_SETTINGS_VIEWPORTWIDGET_DRAW_ELEMENT_BORDERS_DEFAULT ( ViewportWidget::DrawElementBorders_Unselected ) @@ -198,7 +203,7 @@ namespace } // anonymous namespace. ViewportWidget::ViewportWidget(EditorWindow* parent) - : QViewport(parent) + : AtomToolsFramework::RenderViewportWidget(AzFramework::InvalidViewportId, parent) , m_editorWindow(parent) , m_viewportInteraction(new ViewportInteraction(m_editorWindow)) , m_viewportAnchor(new ViewportAnchor()) @@ -213,30 +218,12 @@ ViewportWidget::ViewportWidget(EditorWindow* parent) , m_rulersVisible(GetPersistentRulerVisibility()) , m_guidesVisible(GetPersistentGuideVisibility()) { - QObject::connect(this, - SIGNAL(SignalRender(const SRenderContext&)), - SLOT(HandleSignalRender(const SRenderContext&))); - - // Turn off all fancy visuals in the viewport. - { - SViewportSettings tweakedSettings = GetSettings(); - - tweakedSettings.grid.showGrid = false; - tweakedSettings.grid.origin = false; - tweakedSettings.rendering.fps = false; - tweakedSettings.rendering.wireframe = false; - tweakedSettings.lighting.m_brightness = 0.0f; - tweakedSettings.camera.showViewportOrientation = false; - - SetSettings(tweakedSettings); - } - setAcceptDrops(true); - SetUseArrowsForNavigation(false); - UpdateViewportBackground(); + InitUiRenderer(); + SetupShortcuts(); // Setup a timer for the maximum refresh rate we want. @@ -264,12 +251,32 @@ ViewportWidget::ViewportWidget(EditorWindow* parent) }); FontNotificationBus::Handler::BusConnect(); + AZ::TickBus::Handler::BusConnect(); } ViewportWidget::~ViewportWidget() { AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect(); FontNotificationBus::Handler::BusDisconnect(); + AZ::TickBus::Handler::BusDisconnect(); + + m_uiRenderer.reset(); + + // Notify LyShine that this is no longer a valid UiRenderer. + // Only one viewport/renderer is currently supported in the UI Editor + CLyShine* lyShine = static_cast(gEnv->pLyShine); + lyShine->SetUiRendererForEditor(nullptr); +} + +void ViewportWidget::InitUiRenderer() +{ + m_uiRenderer = AZStd::make_shared(GetViewportContext()); + + // Notify LyShine that this is the UiRenderer to be used for rendering + // UI canvases that are loaded in the UI Editor. + // Only one viewport/renderer is currently supported in the UI Editor + CLyShine* lyShine = static_cast(gEnv->pLyShine); + lyShine->SetUiRendererForEditor(m_uiRenderer); } ViewportInteraction* ViewportWidget::GetViewportInteraction() @@ -292,17 +299,15 @@ void ViewportWidget::ToggleDrawElementBorders(uint32 flags) void ViewportWidget::UpdateViewportBackground() { - SViewportSettings tweakedSettings = GetSettings(); - ColorB backgroundColor(ViewportHelpers::backgroundColorDark.GetR8(), + const QColor backgroundColor(ViewportHelpers::backgroundColorDark.GetR8(), ViewportHelpers::backgroundColorDark.GetG8(), ViewportHelpers::backgroundColorDark.GetB8(), ViewportHelpers::backgroundColorDark.GetA8()); - tweakedSettings.background.useGradient = false; - tweakedSettings.background.topColor = backgroundColor; - tweakedSettings.background.bottomColor = backgroundColor; - tweakedSettings.lighting.m_ambientColor = backgroundColor; - SetSettings(tweakedSettings); + QPalette pal(palette()); + pal.setColor(QPalette::Window, backgroundColor); + setPalette(pal); + setAutoFillBackground(true); } void ViewportWidget::ActiveCanvasChanged() @@ -344,8 +349,10 @@ void ViewportWidget::ClearUntilSafeToRedraw() // set flag so that Update will just clear the screen rather than rendering canvas m_canvasRenderIsEnabled = false; +#ifdef LYSHINE_ATOM_TODO // check if still needed // Force an update Update(); +#endif // Schedule a timer to set the m_canvasRenderIsEnabled flag // using a time of zero just waits until there is nothing on the event queue @@ -454,9 +461,10 @@ void ViewportWidget::contextMenuEvent(QContextMenuEvent* e) } } - QViewport::contextMenuEvent(e); + RenderViewportWidget::contextMenuEvent(e); } +#ifdef LYSHINE_ATOM_TODO // check if still needed void ViewportWidget::HandleSignalRender([[maybe_unused]] const SRenderContext& context) { // Called from QViewport when redrawing the viewport. @@ -477,6 +485,7 @@ void ViewportWidget::HandleSignalRender([[maybe_unused]] const SRenderContext& c } } } +#endif void ViewportWidget::UserSelectionChanged(HierarchyItemRawPtrList* items) { @@ -497,8 +506,34 @@ void ViewportWidget::EnableCanvasRender() RefreshTick(); } +void ViewportWidget::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) +{ + if (!m_uiRenderer->IsReady() || !m_canvasRenderIsEnabled) + { + return; + } + +#ifdef LYSHINE_ATOM_TODO + gEnv->pRenderer->SetSrgbWrite(true); +#endif + + // Set up to render a frame to this viewport's window + GetViewportContext()->RenderTick(); + + UiEditorMode editorMode = m_editorWindow->GetEditorMode(); + if (editorMode == UiEditorMode::Edit) + { + RenderEditMode(deltaTime); + } + else // if (editorMode == UiEditorMode::Preview) + { + RenderPreviewMode(deltaTime); + } +} + void ViewportWidget::RefreshTick() { +#ifdef LYSHINE_EDITOR_TODO // still need this? if (m_refreshRequested) { if (m_canvasRenderIsEnabled) @@ -511,6 +546,7 @@ void ViewportWidget::RefreshTick() // in case we were called manually, reset the timer m_updateTimer.start(); } +#endif } void ViewportWidget::mousePressEvent(QMouseEvent* ev) @@ -636,7 +672,7 @@ void ViewportWidget::wheelEvent(QWheelEvent* ev) m_viewportInteraction->MouseWheelEvent(&scaledEvent); } - QViewport::wheelEvent(ev); + RenderViewportWidget::wheelEvent(ev); Refresh(); } @@ -698,7 +734,7 @@ void ViewportWidget::keyPressEvent(QKeyEvent* event) bool handled = m_viewportInteraction->KeyPressEvent(event); if (!handled) { - QViewport::keyPressEvent(event); + RenderViewportWidget::keyPressEvent(event); } } else // if (editorMode == UiEditorMode::Preview) @@ -739,7 +775,7 @@ void ViewportWidget::keyReleaseEvent(QKeyEvent* event) bool handled = m_viewportInteraction->KeyReleaseEvent(event); if (!handled) { - QViewport::keyReleaseEvent(event); + RenderViewportWidget::keyReleaseEvent(event); } } else if (editorMode == UiEditorMode::Preview) @@ -790,7 +826,7 @@ void ViewportWidget::resizeEvent(QResizeEvent* ev) } } - QViewport::resizeEvent(ev); + RenderViewportWidget::resizeEvent(ev); } bool ViewportWidget::AcceptsMimeData(const QMimeData* mimeData) @@ -863,7 +899,7 @@ QPointF ViewportWidget::WidgetToViewport(const QPointF & point) const return point * WidgetToViewportFactor(); } -void ViewportWidget::RenderEditMode() +void ViewportWidget::RenderEditMode(float deltaTime) { if (m_fontTextureHasChanged) { @@ -893,16 +929,18 @@ void ViewportWidget::RenderEditMode() AZ::Vector2 viewportSize(aznumeric_cast(size().width()), aznumeric_cast(size().height())); viewportSize *= QHighDpiScaling::factor(windowHandle()->screen()); +#ifdef LYSHINE_ATOM_TODO // clear the stencil buffer before rendering each canvas - required for masking // NOTE: the FRT_CLEAR_IMMEDIATE is required since we will not be setting the render target ColorF viewportBackgroundColor(0, 0, 0, 0); // if clearing color we want to set alpha to zero also gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR_STENCIL, viewportBackgroundColor); +#endif // Set the target size of the canvas EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, false, canvasSize); // Update this canvas (must be done after SetTargetCanvasSize) - EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, GetLastFrameTime(), false); + EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, false); // Render this canvas EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, RenderCanvasInEditorViewport, false, viewportSize); @@ -999,7 +1037,7 @@ void ViewportWidget::RenderEditMode() } } -void ViewportWidget::RenderPreviewMode() +void ViewportWidget::RenderPreviewMode(float deltaTime) { AZ::EntityId canvasEntityId = m_editorWindow->GetPreviewModeCanvas(); @@ -1059,7 +1097,7 @@ void ViewportWidget::RenderPreviewMode() EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, true, canvasSize); // Update this canvas (must be done after SetTargetCanvasSize) - EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, GetLastFrameTime(), true); + EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, true); // Execute events that have been queued during the canvas update gEnv->pLyShine->ExecuteQueuedEvents(); @@ -1090,12 +1128,15 @@ void ViewportWidget::RenderPreviewMode() canvasToViewportMatrix.SetTranslation(translation); EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetCanvasToViewportMatrix, canvasToViewportMatrix); +#ifdef LYSHINE_ATOM_TODO // clear the stencil buffer before rendering each canvas - required for masking // NOTE: the FRT_CLEAR_IMMEDIATE is required since we will not be setting the render target // We also clear the color to a mid grey so that we can see the bounds of the canvas ColorF viewportBackgroundColor(0.5f, 0.5f, 0.5f, 0); // if clearing color we want to set alpha to zero also gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR, viewportBackgroundColor); +#endif +#ifdef LYSHINE_ATOM_TODO // Render a black rectangle covering the canvas area. This allows the canvas bounds to be visible when the canvas size is // not exactly the same as the viewport size AZ::Vector2 topLeftInViewportSpace = CanvasHelpers::GetViewportPoint(canvasEntityId, AZ::Vector2(0.0f, 0.0f)); @@ -1104,6 +1145,7 @@ void ViewportWidget::RenderPreviewMode() Draw2dHelper draw2d; int texId = gEnv->pRenderer->GetBlackTextureId(); draw2d.DrawImage(texId, topLeftInViewportSpace, sizeInViewportSpace); +#endif // Render this canvas // NOTE: the displayBounds param is always false. If we wanted a debug option to display the bounds diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.h b/Gems/LyShine/Code/Editor/ViewportWidget.h index 4281d05670..e506a26d88 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.h +++ b/Gems/LyShine/Code/Editor/ViewportWidget.h @@ -15,18 +15,19 @@ #include "EditorCommon.h" #include +#include #include -#include #include #endif class RulerWidget; class QMimeData; +class UiRenderer; class ViewportWidget - : public QViewport + : public AtomToolsFramework::RenderViewportWidget , private AzToolsFramework::EditorPickModeNotificationBus::Handler , private FontNotificationBus::Handler { @@ -84,13 +85,14 @@ public: // member functions void ShowGuides(bool show); bool AreGuidesShown() { return m_guidesVisible; } + void InitUiRenderer(); + protected: void contextMenuEvent(QContextMenuEvent* e) override; private slots: - void HandleSignalRender(const SRenderContext& context); void UserSelectionChanged(HierarchyItemRawPtrList* items); void EnableCanvasRender(); @@ -141,11 +143,15 @@ private: // member functions void OnFontTextureUpdated(IFFont* font) override; // ~FontNotifications + // AZ::TickBus::Handler + void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + // ~AZ::TickBus::Handler + //! Render the viewport when in edit mode - void RenderEditMode(); + void RenderEditMode(float deltaTime); //! Render the viewport when in preview mode - void RenderPreviewMode(); + void RenderPreviewMode(float deltaTime); //! Create shortcuts for manipulating the viewport void SetupShortcuts(); @@ -193,4 +199,6 @@ private: // data bool m_rulersVisible; bool m_guidesVisible; bool m_fontTextureHasChanged = false; + + AZStd::shared_ptr m_uiRenderer; }; diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index c9b201dc5b..cfea0cbdf7 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -288,6 +288,18 @@ UiRenderer* CLyShine::GetUiRenderer() return m_uiRenderer.get(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +UiRenderer* CLyShine::GetUiRendererForEditor() +{ + return m_uiRendererForEditor.get(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CLyShine::SetUiRendererForEditor(AZStd::shared_ptr uiRenderer) +{ + m_uiRendererForEditor = uiRenderer; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::EntityId CLyShine::CreateCanvas() { @@ -414,7 +426,7 @@ void CLyShine::Render() { FRAME_PROFILER(__FUNCTION__, gEnv->pSystem, PROFILE_UI); - // LYSHINE_ATOM_TODO - verify that this is no longer needed and remove + // LYSHINE_ATOM_TODO - convert to use Atom interface to check for null renderer if (!gEnv || !gEnv->pRenderer || gEnv->pRenderer->GetRenderType() == ERenderType::eRT_Null) { // if the renderer is not initialized or it is the null renderer (e.g. running as a server) diff --git a/Gems/LyShine/Code/Source/LyShine.h b/Gems/LyShine/Code/Source/LyShine.h index 7e59cb37c8..943f5fa537 100644 --- a/Gems/LyShine/Code/Source/LyShine.h +++ b/Gems/LyShine/Code/Source/LyShine.h @@ -111,9 +111,13 @@ public: int GetTickOrder() override; // ~TickEvents - // Get the UIRenderer (which is owned by CLyShine). This is not exposed outside the gem. + // Get the UIRenderer for the game (which is owned by CLyShine). This is not exposed outside the gem. UiRenderer* GetUiRenderer(); + // Get/set the UIRenderer for the Editor (which is owned by CLyShine). This is not exposed outside the gem. + UiRenderer* GetUiRendererForEditor(); + void SetUiRendererForEditor(AZStd::shared_ptr uiRenderer); + public: // static member functions #if defined(LYSHINE_INTERNAL_UNIT_TEST) @@ -138,6 +142,7 @@ private: // data std::unique_ptr m_draw2d; // using a pointer rather than an instance to avoid including Draw2d.h std::unique_ptr m_uiRenderer; // using a pointer rather than an instance to avoid including UiRenderer.h + AZStd::shared_ptr m_uiRendererForEditor; std::unique_ptr m_uiCanvasManager; diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp index a980822211..f386d5756b 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp @@ -253,12 +253,18 @@ namespace }, context); } - UiRenderer* GetUiRenderer() + UiRenderer* GetUiRendererForGame() { CLyShine* lyShine = static_cast(gEnv->pLyShine); return lyShine->GetUiRenderer(); } + UiRenderer* GetUiRendererForEditor() + { + CLyShine* lyShine = static_cast(gEnv->pLyShine); + return lyShine->GetUiRendererForEditor(); + } + bool IsValidInteractable(const AZ::EntityId& entityId) { if (!entityId.IsValid()) @@ -1974,9 +1980,12 @@ void UiCanvasComponent::UpdateCanvasInEditorViewport(float deltaTime, bool isInG //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasComponent::RenderCanvasInEditorViewport(bool isInGame, AZ::Vector2 viewportSize) { - GetUiRenderer()->BeginUiFrameRender(); - RenderCanvas(isInGame, viewportSize); - GetUiRenderer()->EndUiFrameRender(); + // When isInGame is true we're rendering the canvas in UI Editor's Preview Mode + UiRenderer* uiRenderer = GetUiRendererForEditor(); + AZ_Assert(uiRenderer, "Trying to render a canvas in the UI Editor before its UIRenderer has been initialized"); + uiRenderer->BeginUiFrameRender(); + RenderCanvas(isInGame, viewportSize, uiRenderer); + uiRenderer->EndUiFrameRender(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2019,7 +2028,7 @@ void UiCanvasComponent::UpdateCanvas(float deltaTime, bool isInGame) } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UiCanvasComponent::RenderCanvas(bool isInGame, AZ::Vector2 viewportSize) +void UiCanvasComponent::RenderCanvas(bool isInGame, AZ::Vector2 viewportSize, UiRenderer* uiRenderer) { // Ignore render ops if we're not enabled if (!m_enabled) @@ -2027,6 +2036,11 @@ void UiCanvasComponent::RenderCanvas(bool isInGame, AZ::Vector2 viewportSize) return; } + if (!uiRenderer) + { + uiRenderer = GetUiRendererForGame(); + } + // It is possible, due to the LoadScreenComponent, for this canvas to have Render called while it is rendering. // This is rare but can happen because rendering of text can call FontCreateTexture which results in CreateTextureObject // being called, which has a load scren update in it. Rendering the canvas to the render graph while already in the @@ -2051,9 +2065,9 @@ void UiCanvasComponent::RenderCanvas(bool isInGame, AZ::Vector2 viewportSize) if (!m_renderGraph.IsEmpty()) { - GetUiRenderer()->BeginCanvasRender(); - m_renderGraph.Render(GetUiRenderer(), viewportSize); - GetUiRenderer()->EndCanvasRender(); + uiRenderer->BeginCanvasRender(); + m_renderGraph.Render(uiRenderer, viewportSize); + uiRenderer->EndCanvasRender(); } m_isRendering = false; @@ -3724,6 +3738,7 @@ void UiCanvasComponent::DestroyRenderTarget() //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasComponent::RenderCanvasToTexture() { +#ifdef LYSHINE_ATOM_TODO if (m_renderTargetHandle <= 0) { return; @@ -3752,6 +3767,7 @@ void UiCanvasComponent::RenderCanvasToTexture() GetUiRenderer()->EndUiFrameRender(); } +#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.h b/Gems/LyShine/Code/Source/UiCanvasComponent.h index be6ffb2fed..6e59a0899f 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.h +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.h @@ -241,7 +241,7 @@ public: // member functions // ~UiCanvasComponentImplementationInterface void UpdateCanvas(float deltaTime, bool isInGame); - void RenderCanvas(bool isInGame, AZ::Vector2 viewportSize); + void RenderCanvas(bool isInGame, AZ::Vector2 viewportSize, UiRenderer* uiRenderer = nullptr); AZ::Entity* GetRootElement() const; diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index 36d236b481..2a2c950e82 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include // LYSHINE_ATOM_TODO - remove when GS_DEPTHFUNC_LEQUAL reference is removed with LyShine render target Atom conversion #include @@ -30,10 +31,13 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// -UiRenderer::UiRenderer() +UiRenderer::UiRenderer(AZ::RPI::ViewportContextPtr viewportContext) : m_baseState(GS_DEPTHFUNC_LEQUAL) , m_stencilRef(0) + , m_viewportContext(viewportContext) { + // Use bootstrap scene event to indicate when the RPI has fully + // initialized with all assets loaded and is ready to be used AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect(); } @@ -42,24 +46,78 @@ UiRenderer::~UiRenderer() { AZ::Render::Bootstrap::NotificationBus::Handler::BusDisconnect(); + if (m_viewportContext) + { + AZ::RPI::RPISystemInterface::Get()->UnregisterScene(m_viewportContext->GetRenderScene()); + } m_dynamicDraw = nullptr; } bool UiRenderer::IsReady() { - return m_isReady; + return m_isRPIReady; } void UiRenderer::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapScene) { - // Create a dynamic draw context for UI Canvas drawing - AZ::RPI::Scene* scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene().get(); - m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(scene); + // At this point the RPI is ready for use // Load the UI shader const char* uiShaderFilepath = "Shaders/LyShineUI.azshader"; AZ::Data::Instance uiShader = AZ::RPI::LoadShader(uiShaderFilepath); + // Create scene to be used by the dynamic draw context + AZ::RPI::ScenePtr scene; + if (m_viewportContext) + { + // Create a new scene based on the user specified viewport context + scene = CreateScene(m_viewportContext); + } + else + { + // No viewport context specified, use default scene + scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene(); + } + + // Create a dynamic draw context for UI Canvas drawing for the scene + CreateDynamicDrawContext(scene, uiShader); + + // Cache shader data such as input indices for later use + CacheShaderData(m_dynamicDraw); + + m_isRPIReady = true; +} + +AZ::RPI::ScenePtr UiRenderer::CreateScene(AZStd::shared_ptr viewportContext) +{ + // Create a scene with the necessary feature processors + AZ::RPI::SceneDescriptor sceneDesc; + AZ::RPI::ScenePtr atomScene = AZ::RPI::Scene::CreateScene(sceneDesc); + atomScene->EnableAllFeatureProcessors(); // LYSHINE_ATOM_TODO - have a UI pipeline and enable only needed fps + + // Assign the new scene to the specified viewport context + viewportContext->SetRenderScene(atomScene); + + // Create a render pipeline and add it to the scene + AZStd::string pipelineAssetPath = "passes/MainRenderPipeline.azasset"; // LYSHINE_ATOM_TODO - make and use a UI pipeline + AZ::Data::Asset pipelineAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath(pipelineAssetPath.c_str(), AZ::RPI::AssetUtils::TraceLevel::Error); + AZStd::shared_ptr windowContext = viewportContext->GetWindowContext(); + auto renderPipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineAsset, *windowContext.get()); + pipelineAsset.Release(); + atomScene->AddRenderPipeline(renderPipeline); + + atomScene->Activate(); + + // Register the scene + AZ::RPI::RPISystemInterface::Get()->RegisterScene(atomScene); + + return atomScene; +} + +void UiRenderer::CreateDynamicDrawContext(AZ::RPI::ScenePtr scene, AZ::Data::Instance uiShader) +{ + m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(scene.get()); + // Initialize the dynamic draw context m_dynamicDraw->InitShader(uiShader); m_dynamicDraw->InitVertexFormat( @@ -68,22 +126,30 @@ void UiRenderer::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstra { "TEXCOORD", AZ::RHI::Format::R32G32_FLOAT }, { "BLENDINDICES", AZ::RHI::Format::R16G16_UINT } } ); - m_dynamicDraw->EndInit(); - - // Cache shader data such as input indices for later use - CacheShaderData(uiShader); - - m_isReady = true; } -void UiRenderer::CacheShaderData(const AZ::Data::Instance shader) +AZStd::shared_ptr UiRenderer::GetViewportContext() +{ + if (!m_viewportContext) + { + // Return the default viewport context + auto viewContextManager = AZ::Interface::Get(); + auto defaultViewportContext = viewContextManager->GetViewportContextByName(viewContextManager->GetDefaultViewportContextName()); + return defaultViewportContext; + } + + // Return the user specified viewport context + return m_viewportContext; +} + +void UiRenderer::CacheShaderData(const AZ::RHI::Ptr& dynamicDraw) { // Cache draw srg input indices static const char textureIndexName[] = "m_texture"; static const char worldToProjIndexName[] = "m_worldToProj"; static const char isClampIndexName[] = "m_isClamp"; - AZ::Data::Instance drawSrg = m_dynamicDraw->NewDrawSrg(); + AZ::Data::Instance drawSrg = dynamicDraw->NewDrawSrg(); const AZ::RHI::ShaderResourceGroupLayout* layout = drawSrg->GetAsset()->GetLayout(); m_uiShaderData.m_imageInputIndex = layout->FindShaderInputImageIndex(AZ::Name(textureIndexName)); AZ_Error(LogName, m_uiShaderData.m_imageInputIndex.IsValid(), "Failed to find shader input constant %s.", @@ -102,7 +168,7 @@ void UiRenderer::CacheShaderData(const AZ::Data::Instance shade shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("false"))); shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("true"))); shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); - m_uiShaderData.m_shaderVariantDefault = m_dynamicDraw->UseShaderVariant(shaderOptionsDefault); + m_uiShaderData.m_shaderVariantDefault = dynamicDraw->UseShaderVariant(shaderOptionsDefault); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -169,8 +235,7 @@ const UiRenderer::UiShaderData& UiRenderer::GetUiShaderData() AZ::Matrix4x4 UiRenderer::GetModelViewProjectionMatrix() { - auto viewContextManager = AZ::Interface::Get(); - auto viewportContext = viewContextManager->GetViewportContextByName(viewContextManager->GetDefaultViewportContextName()); + auto viewportContext = GetViewportContext(); auto windowContext = viewportContext->GetWindowContext(); const AZ::RHI::Viewport& viewport = windowContext->GetViewport(); @@ -189,8 +254,7 @@ AZ::Matrix4x4 UiRenderer::GetModelViewProjectionMatrix() AZ::Vector2 UiRenderer::GetViewportSize() { - auto viewContextManager = AZ::Interface::Get(); - auto viewportContext = viewContextManager->GetViewportContextByName(viewContextManager->GetDefaultViewportContextName()); + auto viewportContext = GetViewportContext(); auto windowContext = viewportContext->GetWindowContext(); const AZ::RHI::Viewport& viewport = windowContext->GetViewport(); diff --git a/Gems/LyShine/Code/Source/UiRenderer.h b/Gems/LyShine/Code/Source/UiRenderer.h index 6a0205af4e..260bd8278c 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.h +++ b/Gems/LyShine/Code/Source/UiRenderer.h @@ -32,20 +32,16 @@ public: // types struct UiShaderData { AZ::RHI::ShaderInputImageIndex m_imageInputIndex; - AZ::RHI::ShaderInputSamplerIndex m_samplerInputIndex; AZ::RHI::ShaderInputConstantIndex m_viewProjInputIndex; AZ::RHI::ShaderInputConstantIndex m_isClampInputIndex; AZ::RPI::ShaderVariantId m_shaderVariantDefault; - - AZ::RPI::ShaderVariantKey m_shaderVariantKeyFallback; - AZ::RPI::ShaderVariantStableId m_defaultVariantStableId; }; public: // member functions //! Constructor, constructed by the LyShine class - UiRenderer(); + UiRenderer(AZ::RPI::ViewportContextPtr viewportContext = nullptr); ~UiRenderer(); //! Returns whether RPI has loaded all its assets and is ready to render @@ -63,7 +59,7 @@ public: // member functions //! End the rendering of a UI canvas void EndCanvasRender(); - //! Return the dynamic draw context used for LyShine + //! Return the dynamic draw context associated with this UI renderer AZ::RHI::Ptr GetDynamicDrawContext(); //! Return the shader data for the ui shader @@ -109,12 +105,21 @@ private: // member functions void OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) override; // ~AZ::Render::Bootstrap::Notification + //! Create a scene for the user defined viewportContext + AZ::RPI::ScenePtr CreateScene(AZStd::shared_ptr viewportContext); + + //! Create a dynamic draw context for this renderer + void CreateDynamicDrawContext(AZ::RPI::ScenePtr scene, AZ::Data::Instance); + + //! Return the viewport context set by the user, or the default if not set + AZStd::shared_ptr GetViewportContext(); + //! Bind the global white texture for all the texture units we use void BindNullTexture(); //! Store shader data for later use - void CacheShaderData(const AZ::Data::Instance shader); - + void CacheShaderData(const AZ::RHI::Ptr& dynamicDraw); + protected: // attributes static constexpr char LogName[] = "UiRenderer"; @@ -124,8 +129,10 @@ protected: // attributes UiShaderData m_uiShaderData; AZ::RHI::Ptr m_dynamicDraw; + bool m_isRPIReady = false; - bool m_isReady = false; + // Set by user when viewport context is not the main/default viewport + AZStd::shared_ptr m_viewportContext; #ifndef _RELEASE int m_debugTextureDataRecordLevel = 0; diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/Cloth_Blinds_Broken.fbx b/Gems/NvCloth/Assets/Objects/cloth/Environment/Cloth_Blinds_Broken.fbx index 563088c3c6..d55de60928 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/Cloth_Blinds_Broken.fbx +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/Cloth_Blinds_Broken.fbx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf6b5ef7a24ff72a6e078cf8d9e8e95d7152bd1b20bb02bf24f779c0976eca07 -size 20608 +oid sha256:8999cfa2a5602c188eef9e451a39c1ab7c312fc1899436248236c06c373c35a4 +size 15804 diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.fbx.assetinfo b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.fbx.assetinfo index d4f5b59650..88fef4a2cd 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.fbx.assetinfo +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.fbx.assetinfo @@ -1,113 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "values": [ + { + "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup", + "name": "cloth_blinds", + "nodeSelectionList": { + "selectedNodes": [ + "RootNode", + "RootNode.pPlane1", + "RootNode.pPlane1.colorSet1", + "RootNode.pPlane1.map1", + "RootNode.pPlane1.lambert1" + ] + }, + "rules": { + "rules": [ + { + "$type": "StaticMeshAdvancedRule", + "vertexColorStreamName": "Disabled" + }, + { + "$type": "MaterialRule" + }, + { + "$type": "ClothRule", + "meshNodeName": "RootNode.pPlane1", + "inverseMassesStreamName": "colorSet1", + "motionConstraintsStreamName": "Default: 1.0", + "backstopStreamName": "None" + } + ] + }, + "id": "{9D0F5F7F-FB90-5C00-97A7-C55F9180CE4E}" + } + ] +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material new file mode 100644 index 0000000000..9bc75c7189 --- /dev/null +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material @@ -0,0 +1,22 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.8207980394363403, + 1.0, + 0.0, + 1.0 + ] + }, + "opacity": { + "alphaSource": "None", + "doubleSided": true, + "factor": 1.0, + "mode": "Cutout" + } + } +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.mtl b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.mtl deleted file mode 100644 index f6bcffc0f2..0000000000 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.mtl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.fbx.assetinfo b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.fbx.assetinfo index 877e1370e8..9a21c3adc7 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.fbx.assetinfo +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.fbx.assetinfo @@ -1,113 +1,37 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "values": [ + { + "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup", + "name": "cloth_blinds_broken", + "nodeSelectionList": { + "selectedNodes": [ + "RootNode", + "RootNode.pPlane1", + "RootNode.pPlane1.transform", + "RootNode.pPlane1.colorSet1", + "RootNode.pPlane1.map1", + "RootNode.pPlane1.lambert1" + ] + }, + "rules": { + "rules": [ + { + "$type": "StaticMeshAdvancedRule", + "vertexColorStreamName": "Disabled" + }, + { + "$type": "MaterialRule" + }, + { + "$type": "ClothRule", + "meshNodeName": "RootNode.pPlane1", + "inverseMassesStreamName": "colorSet1", + "motionConstraintsStreamName": "Default: 1.0", + "backstopStreamName": "None" + } + ] + }, + "id": "{3A467F2C-C2AB-581F-94E3-946575011973}" + } + ] +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material new file mode 100644 index 0000000000..0efbc2fd14 --- /dev/null +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material @@ -0,0 +1,22 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 1.0, + 0.0, + 0.8207980394363403, + 1.0 + ] + }, + "opacity": { + "alphaSource": "None", + "doubleSided": true, + "factor": 1.0, + "mode": "Cutout" + } + } +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.mtl b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.mtl deleted file mode 100644 index a0517b5bf8..0000000000 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.mtl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.fbx.assetinfo b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.fbx.assetinfo index 3e1d53441d..6256b0d521 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.fbx.assetinfo +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.fbx.assetinfo @@ -1,113 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "values": [ + { + "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup", + "name": "cloth_locked_corners_four", + "nodeSelectionList": { + "selectedNodes": [ + "RootNode", + "RootNode.pPlane1", + "RootNode.pPlane1.colorSet1", + "RootNode.pPlane1.map1", + "RootNode.pPlane1.lambert1" + ] + }, + "rules": { + "rules": [ + { + "$type": "StaticMeshAdvancedRule", + "vertexColorStreamName": "Disabled" + }, + { + "$type": "MaterialRule" + }, + { + "$type": "ClothRule", + "meshNodeName": "RootNode.pPlane1", + "inverseMassesStreamName": "colorSet1", + "motionConstraintsStreamName": "Default: 1.0", + "backstopStreamName": "None" + } + ] + }, + "id": "{105338D3-5947-5F72-A077-36C193C8AE7C}" + } + ] +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material new file mode 100644 index 0000000000..904c57fa24 --- /dev/null +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material @@ -0,0 +1,22 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.0, + 0.7548332810401917, + 1.0, + 1.0 + ] + }, + "opacity": { + "alphaSource": "None", + "doubleSided": true, + "factor": 1.0, + "mode": "Cutout" + } + } +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.mtl b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.mtl deleted file mode 100644 index 50242bec5f..0000000000 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.mtl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.fbx.assetinfo b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.fbx.assetinfo index 93836e9fac..ef5ffa8618 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.fbx.assetinfo +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.fbx.assetinfo @@ -1,113 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "values": [ + { + "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup", + "name": "cloth_locked_corners_two", + "nodeSelectionList": { + "selectedNodes": [ + "RootNode", + "RootNode.pPlane1", + "RootNode.pPlane1.colorSet1", + "RootNode.pPlane1.map1", + "RootNode.pPlane1.lambert1" + ] + }, + "rules": { + "rules": [ + { + "$type": "StaticMeshAdvancedRule", + "vertexColorStreamName": "Disabled" + }, + { + "$type": "MaterialRule" + }, + { + "$type": "ClothRule", + "meshNodeName": "RootNode.pPlane1", + "inverseMassesStreamName": "colorSet1", + "motionConstraintsStreamName": "Default: 1.0", + "backstopStreamName": "None" + } + ] + }, + "id": "{45EFD81A-7FBC-59E3-B495-280376B40AC5}" + } + ] +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material new file mode 100644 index 0000000000..771995ffe6 --- /dev/null +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material @@ -0,0 +1,22 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 1.0, + 0.07655451446771622, + 0.0, + 1.0 + ] + }, + "opacity": { + "alphaSource": "None", + "doubleSided": true, + "factor": 1.0, + "mode": "Cutout" + } + } +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.mtl b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.mtl deleted file mode 100644 index 1d4c47d254..0000000000 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.mtl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.fbx.assetinfo b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.fbx.assetinfo index c8e523e76d..90e369f88e 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.fbx.assetinfo +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.fbx.assetinfo @@ -1,113 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "values": [ + { + "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup", + "name": "cloth_locked_edge", + "nodeSelectionList": { + "selectedNodes": [ + "RootNode", + "RootNode.pPlane1", + "RootNode.pPlane1.colorSet1", + "RootNode.pPlane1.map1", + "RootNode.pPlane1.lambert1" + ] + }, + "rules": { + "rules": [ + { + "$type": "StaticMeshAdvancedRule", + "vertexColorStreamName": "Disabled" + }, + { + "$type": "MaterialRule" + }, + { + "$type": "ClothRule", + "meshNodeName": "RootNode.pPlane1", + "inverseMassesStreamName": "colorSet1", + "motionConstraintsStreamName": "Default: 1.0", + "backstopStreamName": "None" + } + ] + }, + "id": "{40E4554D-B904-50DF-90C6-98395C9DDE8C}" + } + ] +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material new file mode 100644 index 0000000000..7e577bf98e --- /dev/null +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material @@ -0,0 +1,22 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.0, + 1.0, + 0.0, + 1.0 + ] + }, + "opacity": { + "alphaSource": "None", + "doubleSided": true, + "factor": 1.0, + "mode": "Cutout" + } + } +} \ No newline at end of file diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.mtl b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.mtl deleted file mode 100644 index c097d8f75b..0000000000 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.mtl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds.slice b/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds.slice index 2c34ae6562..214e6ce3b0 100644 --- a/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds.slice +++ b/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds.slice @@ -39,7 +39,7 @@ - + @@ -61,13 +61,17 @@ - + - + + + + + @@ -126,59 +130,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + @@ -186,6 +164,7 @@ + @@ -208,6 +187,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,13 +297,13 @@ - + - + - + diff --git a/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds_broken.slice b/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds_broken.slice index ff01b86e7b..979616f8f3 100644 --- a/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds_broken.slice +++ b/Gems/NvCloth/Assets/slices/Cloth/cloth_blinds_broken.slice @@ -39,7 +39,7 @@ - + @@ -61,13 +61,17 @@ - + - + + + + + @@ -126,59 +130,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + @@ -186,6 +164,7 @@ + @@ -208,6 +187,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,13 +297,13 @@ - + - + - + diff --git a/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_four.slice b/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_four.slice index c41df9b7db..b2bcb265fe 100644 --- a/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_four.slice +++ b/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_four.slice @@ -39,7 +39,7 @@ - + @@ -61,13 +61,17 @@ - + - + + + + + @@ -126,59 +130,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + @@ -186,6 +164,7 @@ + @@ -208,6 +187,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,13 +297,13 @@ - + - + - + diff --git a/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_two.slice b/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_two.slice index c566a2f5ba..f93956890c 100644 --- a/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_two.slice +++ b/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_corners_two.slice @@ -39,7 +39,7 @@ - + @@ -61,13 +61,17 @@ - + - + + + + + @@ -126,59 +130,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + @@ -186,6 +164,7 @@ + @@ -208,6 +187,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,13 +297,13 @@ - + - + - + diff --git a/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_edge.slice b/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_edge.slice index 298a9b5b88..0d6a7d7f30 100644 --- a/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_edge.slice +++ b/Gems/NvCloth/Assets/slices/Cloth/cloth_locked_edge.slice @@ -39,7 +39,7 @@ - + @@ -61,13 +61,17 @@ - + - + + + + + @@ -126,59 +130,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + @@ -186,6 +164,7 @@ + @@ -208,6 +187,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,13 +297,13 @@ - + - + - + diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp index 278296b9bf..ddd2d6fa36 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp @@ -70,9 +70,6 @@ namespace NvCloth const AZ::Data::Asset& asset, [[maybe_unused]] const AZ::Data::Instance& model) { - // [TODO LYN-1886] Remove this call once OnModelDestroyed is part of MeshComponentNotificationBus - OnModelDestroyed(); - if (!asset.IsReady()) { return; @@ -81,7 +78,7 @@ namespace NvCloth m_clothComponentMesh = AZStd::make_unique(GetEntityId(), m_config); } - void ClothComponent::OnModelDestroyed() + void ClothComponent::OnModelPreDestroy() { m_clothComponentMesh.reset(); } diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponent.h b/Gems/NvCloth/Code/Source/Components/ClothComponent.h index 28708c50c8..9b8458d276 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponent.h +++ b/Gems/NvCloth/Code/Source/Components/ClothComponent.h @@ -48,7 +48,7 @@ namespace NvCloth // AZ::Render::MeshComponentNotificationBus::Handler overrides ... void OnModelReady(const AZ::Data::Asset& modelAsset, const AZ::Data::Instance& model) override; - void OnModelDestroyed(); // [TODO LYN-1886] Add override once it's part of MeshComponentNotificationBus + void OnModelPreDestroy() override; private: ClothConfiguration m_config; diff --git a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp index 00144e1f71..18f86f558b 100644 --- a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp @@ -443,16 +443,13 @@ namespace NvCloth AzToolsFramework::Components::EditorComponentBase::Deactivate(); - m_clothComponentMesh.reset(); + OnModelPreDestroy(); } void EditorClothComponent::OnModelReady( const AZ::Data::Asset& asset, [[maybe_unused]] const AZ::Data::Instance& model) { - // [TODO LYN-1886] Remove this call once OnModelDestroyed is part of MeshComponentNotificationBus - OnModelDestroyed(); - if (!asset.IsReady()) { return; @@ -518,7 +515,7 @@ namespace NvCloth AzToolsFramework::Refresh_EntireTree); } - void EditorClothComponent::OnModelDestroyed() + void EditorClothComponent::OnModelPreDestroy() { m_previousMeshNode = m_config.m_meshNode; diff --git a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h index b262edb9ea..1339fe1c6d 100644 --- a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h +++ b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h @@ -52,7 +52,7 @@ namespace NvCloth // AZ::Render::MeshComponentNotificationBus::Handler overrides ... void OnModelReady(const AZ::Data::Asset& modelAsset, const AZ::Data::Instance& model) override; - void OnModelDestroyed(); // [TODO LYN-1886] Add override once it's part of MeshComponentNotificationBus + void OnModelPreDestroy() override; private: bool IsSimulatedInEditor() const; diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp index e27ec3aaf4..f64c96a863 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp @@ -100,7 +100,7 @@ namespace ScriptCanvasBuilder // or the fingerprint of the individual job is different. size_t fingerprint = ScriptCanvas::BehaviorContextUtils::GenerateFingerprintForBehaviorContext(); builderDescriptor.m_analysisFingerprint = AZStd::string(m_scriptCanvasBuilder.GetFingerprintString()) - .append(AZStd::string::format("|%zu", fingerprint)); + .append("|").append(AZStd::to_string(static_cast(fingerprint))); builderDescriptor.AddFlags(AssetBuilderSDK::AssetBuilderDesc::BF_DeleteLastKnownGoodProductOnFailure, s_scriptCanvasProcessJobKey); builderDescriptor.m_productsToKeepOnFailure[s_scriptCanvasProcessJobKey] = { AZ_CRC("SubgraphInterface", 0xdfe6dc72) }; m_scriptCanvasBuilder.BusConnect(builderDescriptor.m_busId); diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index 947bb7d511..eab22ba14f 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -514,8 +514,23 @@ namespace ScriptCanvasEditor bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, AZStd::unordered_map>& outSlotIdMap) { + auto findReplacementMatch = [](const ScriptCanvas::Slot* oldSlot, const AZStd::vector& newSlots)->ScriptCanvas::SlotId + { + for (auto& newSlot : newSlots) + { + if (newSlot->GetName() == oldSlot->GetName() + && newSlot->GetType() == oldSlot->GetType() + && (newSlot->IsExecution() || newSlot->GetDataType() == oldSlot->GetDataType())) + { + return newSlot->GetId(); + } + } + + return {}; + }; + oldNode->CustomizeReplacementNode(newNode, outSlotIdMap); - // Double check to make sure no stupid thing has been done + if (!newNode) { AZ_Warning("ScriptCanvas", false, "Replacement node can not be null."); @@ -523,7 +538,13 @@ namespace ScriptCanvasEditor } AZStd::unordered_map> slotNameMap = oldNode->GetReplacementSlotsMap(); - for (auto oldSlot : oldNode->GetAllSlots()) + + const auto newSlots = newNode->GetAllSlots(); + const auto oldSlots = oldNode->GetAllSlots(); + bool usingDefaults = true; + size_t defaultMatchesFound = 0; + + for (auto oldSlot : oldSlots) { const ScriptCanvas::SlotId oldSlotId = oldSlot->GetId(); const AZStd::string oldSlotName = oldSlot->GetName(); @@ -575,12 +596,30 @@ namespace ScriptCanvasEditor } outSlotIdMap.emplace(oldSlot->GetId(), newSlotIds); } + else if (slotNameMap.empty()) + { + usingDefaults = true; + auto newSlotId = findReplacementMatch(oldSlot, newSlots); + + if (newSlotId.IsValid()) + { + ++defaultMatchesFound; + AZStd::vector slotIds{ newSlotId }; + outSlotIdMap.emplace(oldSlot->GetId(), slotIds); + } + } else { AZ_Warning("ScriptCanvas", false, "Failed to remap deprecated Node(%s) Slot(%s).", oldNode->GetNodeName().c_str(), oldSlot->GetName().c_str()); return false; } } + + if (usingDefaults && defaultMatchesFound != oldSlots.size()) + { + AZ_Warning("ScriptCanvas", false, "Failed to remap deprecated Node(%s) not all old slots were present in the new node.", oldNode->GetNodeName().c_str()); + } + return true; } diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp index 8408f8e594..c6ecac00f1 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp @@ -10,6 +10,8 @@ * */ +#include + #include #include #include @@ -414,16 +416,7 @@ namespace ScriptCanvasEditor::Nodes GraphCanvas::NodeTitleRequestBus::EventResult(title, graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::GetTitle); if (!title.empty()) { - if (title.ends_with("::Getter")) - { - AZ::StringFunc::Replace(title, "::Getter", ""); - } - - if (displayName.ends_with("::Setter")) - { - AZ::StringFunc::Replace(title, "::Setter", ""); - } - + AZ::RemovePropertyNameArtifacts(title); GraphCanvas::NodeTitleRequestBus::Event(graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::SetTitle, title); } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp index 56c18dc803..bce247aee7 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp @@ -586,7 +586,7 @@ namespace auto attributeData = azdynamic_cast*>(AZ::FindAttribute(AZ::Script::Attributes::ExcludeFrom, methodIter.second->m_attributes)); if (ShouldExcludeFromNodeList(attributeData , {})) { - return; + continue; } RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, methodIter.first, *methodIter.second, behaviorClass->IsMethodOverloaded(methodIter.first)); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja index 1f87cf2cfe..b7394ef212 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja @@ -78,7 +78,7 @@ public: \ {% if deprecationUuid is defined %} NodeConfiguration GetReplacementNodeConfiguration() const override; \ {% endif %} using Node::FindDatum; \ -{% if Class.attrib['GraphEntryPoint'] is defined %} bool IsEntryPoint() const override { return {%if Class.attrib['GraphEntryPoint'] == True %}true{%else%}false{%endif%}; } \ +{% if Class.attrib['GraphEntryPoint'] is defined %} bool IsEntryPoint() const override { return {%if Class.attrib['GraphEntryPoint'] == "True" %}true{%else%}false{%endif%}; } \ {% endif %} public: \ friend struct ::{{ className | replace(' ','') }}Property; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja index e0d2ca79ab..4e0f424980 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja @@ -171,7 +171,7 @@ bool {{ Class.attrib['QualifiedName'] }}::RequiresDynamicSlotOrdering() const bool {{ Class.attrib['QualifiedName'] }}::IsDeprecated() const { - return {% if Class.attrib['Deprecated'] is defined %}true{% else %}false{% endif %}; + return {% if Class.attrib['Deprecated'] is defined or Class.attrib['DeprecationUUID'] is defined %}true{% else %}false{% endif %}; } {% set deprecationUuid = Class.attrib['DeprecationUUID'] %} @@ -183,6 +183,9 @@ ScriptCanvas::NodeConfiguration {{ Class.attrib['QualifiedName'] }}::GetReplacem {% if Class.attrib['ReplacementMethodName'] is defined %} nodeConfig.m_methodName = "{{Class.attrib['ReplacementMethodName']}}"; {% endif %} + {% if Class.attrib['ReplacementClassName'] is defined %} + nodeConfig.m_className = "{{Class.attrib['ReplacementClassName']}}"; + {% endif %} return nodeConfig; } {% endif %} @@ -225,7 +228,7 @@ void {{ Class.attrib['QualifiedName'] }}::Reflect(AZ::ReflectContext* context) {% if Class.attrib['Icon'] is defined %} ->Attribute(AZ::Edit::Attributes::Icon, "{{ Class.attrib['Icon'] }}") {% endif %} -{% if Class.attrib['Deprecated'] is defined %} +{% if Class.attrib['Deprecated'] is defined or Class.attrib['DeprecationUUID'] is defined %} ->Attribute(ScriptCanvas::Attributes::Node::TitlePaletteOverride, "DeprecatedNodeTitlePalette") ->Attribute(AZ::Script::Attributes::Deprecated, true) {% else %} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja index 0db611ffcb..7b873e1362 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja @@ -224,6 +224,7 @@ void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) { behaviorContext->Class<{{ attribute_Name }}>("{{ attribute_Name }}") ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List) + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) {% for inputMethod in Class.iter('Input') %} {% set methodName = inputMethod.attrib['Name'] %} // {{ inputMethod.attrib['Name'] }} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp index 153242d78a..ab467127c1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp @@ -121,6 +121,58 @@ namespace ParsingUtilitiesCpp AZStd::string m_result; ExecutionTreeConstPtr m_marker; }; + + bool IsBehaviorContextProperty(const Node* node, const Slot* slot, bool checkRead, bool checkWrite) + { + auto methodNode = azrtti_cast(node); + if (!methodNode) + { + return false; + } + + auto behaviorContext = AZ::GetDefaultBehaviorContext(); + if (!behaviorContext) + { + return false; + } + + auto nameOutcome = methodNode->GetFunctionCallName(slot); + if (!nameOutcome.IsSuccess()) + { + return false; + } + + AZStd::string sanitized(nameOutcome.GetValue()); + AZ::RemovePropertyNameArtifacts(sanitized); + + auto iter = behaviorContext->m_properties.find(sanitized); + if (iter == behaviorContext->m_properties.end()) + { + return false; + } + + if (checkRead && !iter->second->m_getter) + { + return false; + } + + if (checkWrite && !iter->second->m_setter) + { + return false; + } + + return true; + } + + bool IsBehaviorContextPropertyRead(const Node* node, const Slot* slot) + { + return IsBehaviorContextProperty(node, slot, true, false); + } + + bool IsBehaviorContextPropertyWrite(const Node* node, const Slot* slot) + { + return IsBehaviorContextProperty(node, slot, false, true); + } } namespace ScriptCanvas @@ -608,6 +660,20 @@ namespace ScriptCanvas && execution->GetInput(0).m_value->m_requiresNullCheck; } + bool IsGlobalPropertyRead(ExecutionTreeConstPtr execution) + { + return execution->GetSymbol() == Symbol::FunctionCall + && execution->GetInputCount() == 0 + && ParsingUtilitiesCpp::IsBehaviorContextPropertyRead(execution->GetId().m_node, execution->GetId().m_slot); + } + + bool IsGlobalPropertyWrite(ExecutionTreeConstPtr execution) + { + return execution->GetSymbol() == Symbol::FunctionCall + && execution->GetInputCount() == 0 + && ParsingUtilitiesCpp::IsBehaviorContextPropertyWrite(execution->GetId().m_node, execution->GetId().m_slot); + } + bool IsIfCondition(const ExecutionTreeConstPtr& execution) { return execution->GetId().m_node->IsIfBranch() diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h index 62c8cafa7e..7bdfa39c7c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h @@ -105,6 +105,10 @@ namespace ScriptCanvas bool IsFunctionCallNullCheckRequired(const ExecutionTreeConstPtr& execution); + bool IsGlobalPropertyRead(ExecutionTreeConstPtr execution); + + bool IsGlobalPropertyWrite(ExecutionTreeConstPtr execution); + bool IsIfCondition(const ExecutionTreeConstPtr& execution); bool IsInfiniteSelfEntityActivationLoop(const AbstractCodeModel& model, ExecutionTreeConstPtr execution); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml index 6ec1960d35..6b9feb9303 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ GeneratePropertyFriend="True" Description="adds a failure directly to the unit testing framework" DeprecationUUID="{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Add Failure" > diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml index 0bec5f9c20..19226be6d6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml @@ -10,7 +10,7 @@ Version="0" GeneratePropertyFriend="True" DeprecationUUID="{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Add Success" Description="adds a success directly to the unit testing framework"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml index 609ee43ca2..1149993f3a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml @@ -10,7 +10,7 @@ Version="0" GeneratePropertyFriend="True" DeprecationUUID="{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Checkpoint" Description="Add a progress checkpoint for test debugging"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml index bbd49dd958..b2efdb7e6f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectComparisonVersioner" GeneratePropertyFriend="True" DeprecationUUID="{C1E3C9D0-42E3-4D00-AE73-2A881E7E76A8}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect Equal" Description="Expects lhs equal to rhs"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml index e7336a306e..ed5f8ae779 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectBooleanVersioner" GeneratePropertyFriend="True" DeprecationUUID="{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect False" Description="Expects a value to be false"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml index 12cc5bf8fc..d074d0eba3 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectComparisonVersioner" GeneratePropertyFriend="True" DeprecationUUID="{C1E3C9D0-42E3-4D00-AE73-2A881E7E76A8}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect Greater Than" Description="Expects lhs to be greater than rhs"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml index 728d64ab64..58358466bf 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectComparisonVersioner" GeneratePropertyFriend="True" DeprecationUUID="{C1E3C9D0-42E3-4D00-AE73-2A881E7E76A8}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect Greater Than Equal" Description="Expects lhs to be greater than rhs"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml index 6790bcfe3c..69d52f570a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectComparisonVersioner" GeneratePropertyFriend="True" DeprecationUUID="{C1E3C9D0-42E3-4D00-AE73-2A881E7E76A8}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect Less Than" Description="Expects lhs to be less than rhs"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml index bbac6ffd09..9fdff37155 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectComparisonVersioner" GeneratePropertyFriend="True" DeprecationUUID="{C1E3C9D0-42E3-4D00-AE73-2A881E7E76A8}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect Less Than Equal" Description="Expects lhs to be greater than rhs"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml index c783c1dadd..615e5688e2 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectComparisonVersioner" GeneratePropertyFriend="True" DeprecationUUID="{C1E3C9D0-42E3-4D00-AE73-2A881E7E76A8}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect Not Equal" Description="Expects lhs not equal to rhs"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml index dd6e688de5..153706ba7b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml @@ -11,7 +11,7 @@ VersionConverter="ScriptCanvas::UnitTesting::ExpectBooleanVersioner" GeneratePropertyFriend="True" DeprecationUUID="{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Expect True" Description="Expects a value to be true"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml index 465cfaeff5..6111ade264 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml @@ -10,7 +10,7 @@ Version="0" GeneratePropertyFriend="True" DeprecationUUID="{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}" - ReplacementClassname="Unit Testing" + ReplacementClassName="Unit Testing" ReplacementMethodName="Mark Complete" Description="reports that the graph completed to the unit testing framework"> diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.cpp index c48c79e8ec..e6ab482ef4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.cpp @@ -388,7 +388,10 @@ namespace ScriptCanvas { AZ::ScriptCanvasAttributes::HiddenIndices uniqueIdIndex = { 0 }; - auto builder = behaviorContext->Class("Unit Testing"); + auto builder = behaviorContext->Class("Unit Testing") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ; + builder->Method("Add Failure", &EventSender::AddFailure, { { {"", "", behaviorContext->MakeDefaultValue(UniqueId)}, {"Report", "additional notes for the test report"} } }) ->Attribute(AZ::ScriptCanvasAttributes::HiddenParameterIndex, uniqueIdIndex) ->Method("Add Success", &EventSender::AddSuccess, { { {"", "", behaviorContext->MakeDefaultValue(UniqueId)}, {"Report", "additional notes for the test report"} } }) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index 843844a64e..bd583cb43d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -237,6 +237,13 @@ namespace ScriptCanvas writer.Indent(); } + AZStd::string GraphToLua::SanitizeFunctionCallName(AZStd::string_view name) + { + AZStd::string sanitized(name); + AZ::RemovePropertyNameArtifacts(sanitized); + return Grammar::ToIdentifier(sanitized); + } + AZ::Outcome GraphToLua::Translate(const Grammar::AbstractCodeModel& model) { GraphToLua translation(model); @@ -626,6 +633,10 @@ namespace ScriptCanvas { WriteEventDisconnectCall(execution, PostDisconnectAction::SetToNil); } + else if (Grammar::IsGlobalPropertyRead(execution)) + { + WriteGlobalPropertyRead(execution); + } else { const bool isNullCheckRequired = Grammar::IsFunctionCallNullCheckRequired(execution); @@ -1765,7 +1776,12 @@ namespace ScriptCanvas return 0; } - + + void GraphToLua::WriteGlobalPropertyRead(Grammar::ExecutionTreeConstPtr execution) + { + m_dotLua.WriteLine(SanitizeFunctionCallName(execution->GetName())); + } + void GraphToLua::WriteHeader() { // no one will ever the see header or the do not modify, so these will not be necessary diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h index b10856c67a..ab80627944 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h @@ -60,7 +60,8 @@ namespace ScriptCanvas enum class IsNamed { No, Yes }; static IsNamed IsInputNamed(Grammar::VariableConstPtr input, Grammar::ExecutionTreeConstPtr execution); - + static AZStd::string SanitizeFunctionCallName(AZStd::string_view name); + RuntimeInputs m_runtimeInputs; BuildConfiguration m_executionConfig = BuildConfiguration::Release; FunctionBlockConfig m_functionBlockConfig = FunctionBlockConfig::Ignored; @@ -143,6 +144,7 @@ namespace ScriptCanvas void WriteFunctionCallNullCheckPost(Grammar::ExecutionTreeConstPtr execution); void WriteFunctionCallNullCheckPre(Grammar::ExecutionTreeConstPtr execution); void WriteFunctionCallOfNode(Grammar::ExecutionTreeConstPtr, AZStd::string nameOverride = "", size_t inputOverride = AZStd::numeric_limits::max()); + void WriteGlobalPropertyRead(Grammar::ExecutionTreeConstPtr); void WriteHeader(); void WriteInfiniteLoopCheckPost(Grammar::ExecutionTreeConstPtr execution); void WriteInfiniteLoopCheckPre(Grammar::ExecutionTreeConstPtr execution); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp index 0cb9d7f749..ff38b74d47 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp @@ -13,6 +13,7 @@ #include "BehaviorContextUtils.h" #include +#include #include #include @@ -245,23 +246,13 @@ namespace ScriptCanvas } else { - // The method is not in the behaviorContext Global Methods, so check the Global Properties - for (auto [propertyName, behaviorProperty] : behaviorContext->m_properties) + AZStd::string propertyName(methodName); + AZ::RemovePropertyNameArtifacts(propertyName); + + auto iter = behaviorContext->m_properties.find(propertyName); + if (iter != behaviorContext->m_properties.end()) { - AZStd::string getterName = AZStd::string::format("%s::Getter", methodName.data()); - AZStd::string setterName = AZStd::string::format("%s::Setter", methodName.data()); - - if (behaviorProperty->m_getter && (behaviorProperty->m_getter->m_name == methodName || behaviorProperty->m_getter->m_name == getterName)) - { - method = behaviorProperty->m_getter; - break; - } - if (behaviorProperty->m_setter && (behaviorProperty->m_setter->m_name == methodName || behaviorProperty->m_setter->m_name == setterName)) - { - method = behaviorProperty->m_setter; - break; - } - + method = iter->second->m_getter ? iter->second->m_getter : iter->second->m_setter; } if (!method) diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ReadEnumConstant.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ReadEnumConstant.scriptcanvas new file mode 100644 index 0000000000..99563638c7 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ReadEnumConstant.scriptcanvas @@ -0,0 +1,2547 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h index cc7be9397d..cb3c9cdccb 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h @@ -108,13 +108,9 @@ namespace ScriptCanvasTests auto m_serializeContext = s_application->GetSerializeContext(); auto m_behaviorContext = s_application->GetBehaviorContext(); - ScriptCanvasTesting::GlobalBusTraits::Reflect(m_serializeContext); - ScriptCanvasTesting::GlobalBusTraits::Reflect(m_behaviorContext); - ScriptCanvasTesting::LocalBusTraits::Reflect(m_serializeContext); - ScriptCanvasTesting::LocalBusTraits::Reflect(m_behaviorContext); - ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(m_serializeContext); - ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(m_behaviorContext); - ScriptCanvasTesting::TestTupleMethods::Reflect(m_behaviorContext); + + ScriptCanvasTesting::Reflect(m_serializeContext); + ScriptCanvasTesting::Reflect(m_behaviorContext); ::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_serializeContext); ::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_behaviorContext); diff --git a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp index f8664e0fe0..34df10fdea 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp @@ -20,6 +20,21 @@ namespace ScriptCanvasTesting { + void Reflect(AZ::ReflectContext* context) + { + ScriptCanvasTesting::GlobalBusTraits::Reflect(context); + ScriptCanvasTesting::LocalBusTraits::Reflect(context); + ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(context); + ScriptCanvasTesting::TestTupleMethods::Reflect(context); + + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->EnumProperty<(AZ::u32)TestEnum::Alpha>("ALPHA"); + behaviorContext->EnumProperty<(AZ::u32)TestEnum::Bravo>("BRAVO"); + behaviorContext->EnumProperty<(AZ::u32)TestEnum::Charlie>("CHARLIE"); + } + } + class GlobalEBusHandler : public GlobalEBus::Handler , public AZ::BehaviorEBusHandler @@ -99,6 +114,7 @@ namespace ScriptCanvasTesting modVoidDesc.m_eventName = "OnEvent-ZeroParam"; behaviorContext->EBus("GlobalEBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Handler() ->Event("AppendSweet", &GlobalEBus::Events::AppendSweet) ->Event("Increment", &GlobalEBus::Events::Increment) @@ -154,6 +170,7 @@ namespace ScriptCanvasTesting if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->EBus("LocalEBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Handler() ->Event("AppendSweet", &LocalEBus::Events::AppendSweet) ->Event("Increment", &LocalEBus::Events::Increment) @@ -167,6 +184,7 @@ namespace ScriptCanvasTesting if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->EBus("NativeHandlingOnlyEBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Event("AppendSweet", &NativeHandlingOnlyEBus::Events::AppendSweet) ->Event("Increment", &NativeHandlingOnlyEBus::Events::Increment) ->Event("Not", &NativeHandlingOnlyEBus::Events::Not) diff --git a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h index fbc03a8ab8..c31627f9fb 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h +++ b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h @@ -25,6 +25,8 @@ namespace AZ namespace ScriptCanvasTesting { + void Reflect(AZ::ReflectContext* context); + class GlobalBusTraits : public AZ::EBusTraits { public: @@ -104,4 +106,11 @@ namespace ScriptCanvasTesting } }; + + enum class TestEnum : AZ::u32 + { + Alpha = 7, + Bravo = 15, + Charlie = 31, + }; } diff --git a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp index 7c9fa8e1ed..e6bd4f53cf 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp @@ -43,10 +43,7 @@ namespace ScriptCanvasTesting NodeableTestingLibrary::Reflect(context); ScriptCanvasTestingNodes::BehaviorContextObjectTest::Reflect(context); - ScriptCanvasTesting::GlobalBusTraits::Reflect(context); - ScriptCanvasTesting::LocalBusTraits::Reflect(context); - ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(context); - ScriptCanvasTesting::TestTupleMethods::Reflect(context); + ScriptCanvasTesting::Reflect(context); } void ScriptCanvasTestingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index c48e4f4f1a..9e6f7aa051 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -95,6 +95,11 @@ TEST_F(ScriptCanvasTestFixture, InterpretedHelloWorld) RunUnitTestGraph("LY_SC_UnitTest_HelloWorld"); } +TEST_F(ScriptCanvasTestFixture, InterpretedReadEnumConstant) +{ + RunUnitTestGraph("LY_SC_UnitTest_ReadEnumConstant"); +} + TEST_F(ScriptCanvasTestFixture, InterpretedEventHandlerNoDisconnect) { GlobalHandler handler; diff --git a/cmake/3rdParty/FindFreeType2.cmake b/cmake/3rdParty/FindFreeType2.cmake deleted file mode 100644 index 9dda2bbc41..0000000000 --- a/cmake/3rdParty/FindFreeType2.cmake +++ /dev/null @@ -1,16 +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. -# - -ly_add_external_target( - NAME FreeType2 - VERSION 2.5.0.1-pkg.3 - INCLUDE_DIRECTORIES dist/include -) diff --git a/cmake/3rdParty/Findtiff.cmake b/cmake/3rdParty/Findtiff.cmake deleted file mode 100644 index f0890234b8..0000000000 --- a/cmake/3rdParty/Findtiff.cmake +++ /dev/null @@ -1,16 +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. -# - -ly_add_external_target( - NAME tiff - VERSION 3.9.5-az.3 - INCLUDE_DIRECTORIES include -) diff --git a/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake b/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake index fcc72625dd..6c16909c6e 100644 --- a/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake +++ b/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake @@ -22,9 +22,11 @@ ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zst ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform TARGETS glad PACKAGE_HASH ff97ee9664e97d0854b52a3734c2289329d9f2b4cd69478df6d0ca1f1c9392ee) ly_associate_package(PACKAGE_NAME lux_core-2.2-rev5-multiplatform TARGETS lux_core PACKAGE_HASH c8c13cf7bc351643e1abd294d0841b24dee60e51647dff13db7aec396ad1e0b5) # platform-specific: +ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-android TARGETS freetype PACKAGE_HASH 74dd75382688323c3a2a5090f473840b5d7e9d2aed1a4fcdff05ed2a09a664f2) +ly_associate_package(PACKAGE_NAME tiff-4.2.0.14-android TARGETS tiff PACKAGE_HASH a9b30a1980946390c2fad0ed94562476a1d7ba8c1f36934ae140a89c54a8efd0) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev2-android TARGETS AWSNativeSDK PACKAGE_HASH 7a99556055c021cb94a2c4956c040ca36fa6cdb044a5faff0e05cc728e216e8e) ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-android TARGETS PhysX PACKAGE_HASH 9c494576c2d4ff04dee5a9e092fcd9d5af4b2845f15ffdfcaabb0dbc5b88a7a9) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-android TARGETS mikkelsen PACKAGE_HASH 075e8e4940884971063b5a9963014e2e517246fa269c07c7dc55b8cf2cd99705) ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-android TARGETS googletest PACKAGE_HASH 95671be75287a61c9533452835c3647e9c1b30f81b34b43bcb0ec1997cc23894) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-android TARGETS GoogleBenchmark PACKAGE_HASH 20b46e572211a69d7d94ddad1c89ec37bb958711d6ad4025368ac89ea83078fb) -ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev1-android TARGETS libsamplerate PACKAGE_HASH cf94df05c1a18ea17b1f576a86c33a1d45652e688b5797ecf3a83192391c929f) +ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-android TARGETS libsamplerate PACKAGE_HASH bf13662afe65d02bcfa16258a4caa9b875534978227d6f9f36c9cfa92b3fb12b) diff --git a/cmake/3rdParty/Platform/Android/FreeType2_android.cmake b/cmake/3rdParty/Platform/Android/FreeType2_android.cmake deleted file mode 100644 index 6e85744060..0000000000 --- a/cmake/3rdParty/Platform/Android/FreeType2_android.cmake +++ /dev/null @@ -1,12 +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. -# - -set(FREETYPE2_LIBS ${BASE_PATH}/build/win_x64/android_ndk_r12/android-21/arm64-v8a/clang-3.8/$,debug,release>/libfreetype2.a) diff --git a/cmake/3rdParty/Platform/Android/cmake_android_files.cmake b/cmake/3rdParty/Platform/Android/cmake_android_files.cmake index aea8054ab1..07e453f862 100644 --- a/cmake/3rdParty/Platform/Android/cmake_android_files.cmake +++ b/cmake/3rdParty/Platform/Android/cmake_android_files.cmake @@ -12,7 +12,6 @@ set(FILES BuiltInPackages_android.cmake civetweb_android.cmake - FreeType2_android.cmake VkValidation_android.cmake Wwise_android.cmake ) diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake index 80cbc0174e..482d4ed4ca 100644 --- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake +++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake @@ -33,6 +33,8 @@ ly_associate_package(PACKAGE_NAME xxhash-0.7.4-rev1-multiplatform TARG ly_associate_package(PACKAGE_NAME PVRTexTool-4.24.0-rev4-multiplatform TARGETS PVRTexTool PACKAGE_HASH d0d6da61c7557de0d2c71fc35ba56c3be49555b703f0e853d4c58225537acf1e) # platform-specific: +ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-linux TARGETS freetype PACKAGE_HASH 9ad246873067717962c6b780d28a5ce3cef3321b73c9aea746a039c798f52e93) +ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-linux TARGETS tiff PACKAGE_HASH ae92b4d3b189c42ef644abc5cac865d1fb2eb7cb5622ec17e35642b00d1a0a76) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev2-linux TARGETS AWSNativeSDK PACKAGE_HASH 6203e1b00907b3977a6999bbdaa0aa7d5ce24f09effaffee2725b200d200eeb7) ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-linux TARGETS PhysX PACKAGE_HASH e3ca36106a8dbf1524709f8bb82d520920ebd3ff3a92672d382efff406c75ee3) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-linux TARGETS mikkelsen PACKAGE_HASH 5973b1e71a64633588eecdb5b5c06ca0081f7be97230f6ef64365cbda315b9c8) @@ -40,4 +42,4 @@ ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-linux TARGETS goog ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-linux TARGETS GoogleBenchmark PACKAGE_HASH 4038878f337fc7e0274f0230f71851b385b2e0327c495fc3dd3d1c18a807928d) ly_associate_package(PACKAGE_NAME unwind-1.2.1-linux TARGETS unwind PACKAGE_HASH 3453265fb056e25432f611a61546a25f60388e315515ad39007b5925dd054a77) ly_associate_package(PACKAGE_NAME qt-5.15.2-linux TARGETS Qt PACKAGE_HASH 3857fbb2fc5581cdb71d80a7f9298c83ef06073d4e1ccd86a32b4f88782b6f14) -ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev1-linux TARGETS libsamplerate PACKAGE_HASH 9fbf284c5952607c679a7c3ddac18fa608a1b316b8ff735d5225c0618e06c562) +ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-linux TARGETS libsamplerate PACKAGE_HASH 41643c31bc6b7d037f895f89d8d8d6369e906b92eff42b0fe05ee6a100f06261) diff --git a/cmake/3rdParty/Platform/Linux/FreeType2_linux.cmake b/cmake/3rdParty/Platform/Linux/FreeType2_linux.cmake deleted file mode 100644 index 293cdc5947..0000000000 --- a/cmake/3rdParty/Platform/Linux/FreeType2_linux.cmake +++ /dev/null @@ -1,12 +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. -# - -set(FREETYPE2_LIBS ${BASE_PATH}/build/linux/clang-3.4/$,debug,release>/libfreetype2.a) diff --git a/cmake/3rdParty/Platform/Linux/cmake_linux_files.cmake b/cmake/3rdParty/Platform/Linux/cmake_linux_files.cmake index b991f1a008..5303b2b1e8 100644 --- a/cmake/3rdParty/Platform/Linux/cmake_linux_files.cmake +++ b/cmake/3rdParty/Platform/Linux/cmake_linux_files.cmake @@ -17,8 +17,6 @@ set(FILES dyad_linux.cmake etc2comp_linux.cmake FbxSdk_linux.cmake - FreeType2_linux.cmake OpenSSL_linux.cmake - tiff_linux.cmake Wwise_linux.cmake ) diff --git a/cmake/3rdParty/Platform/Linux/tiff_linux.cmake b/cmake/3rdParty/Platform/Linux/tiff_linux.cmake deleted file mode 100644 index a5666b02d6..0000000000 --- a/cmake/3rdParty/Platform/Linux/tiff_linux.cmake +++ /dev/null @@ -1,31 +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. -# - -# In some compilers, the build dependency has to be added after in linking. Because we represent 3rdParty with -# interface libraries, dependencies are transitive and do not represent dependencies between the 3rdParties themselves. -# Refer to the comment here: https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmComputeLinkDepends.cxx#L29 -# To workaround this problem, we wrap the static lib in an imported lib and mark the dependency there. That makes -# the DAG algorithm to sort them in the order we need. - -add_library(3rdParty::tiff::imported STATIC IMPORTED) -set_target_properties(3rdParty::tiff::imported - PROPERTIES - IMPORTED_LOCATION ${BASE_PATH}/libtiff/linux_gcc/libtiff.a -) -target_link_libraries(3rdParty::tiff::imported - INTERFACE - 3rdParty::zlib -) -set(TIFF_BUILD_DEPENDENCIES - 3rdParty::tiff::imported - jpeg - jbig -) \ No newline at end of file diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index 0f25b6cbbb..11c56ad5da 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -38,10 +38,12 @@ ly_associate_package(PACKAGE_NAME xxhash-0.7.4-rev1-multiplatform ly_associate_package(PACKAGE_NAME PVRTexTool-4.24.0-rev4-multiplatform TARGETS PVRTexTool PACKAGE_HASH d0d6da61c7557de0d2c71fc35ba56c3be49555b703f0e853d4c58225537acf1e) # platform-specific: +ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-mac-ios TARGETS freetype PACKAGE_HASH 67b4f57aed92082d3fd7c16aa244a7d908d90122c296b0a63f73e0a0b8761977) +ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-mac-ios TARGETS tiff PACKAGE_HASH a23ae1f8991a29f8e5df09d6d5b00d7768a740f90752cef465558c1768343709) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev2-mac TARGETS AWSNativeSDK PACKAGE_HASH 63768a6eb762c1941988dab0cb6fa4b5442989dff8f0b9391efeb83c1ba3786c) ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-mac TARGETS PhysX PACKAGE_HASH 149f5e9b44bd27291b1c4772f5e89a1e0efa88eef73c7e0b188935ed4d0c4a70) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-mac TARGETS mikkelsen PACKAGE_HASH 83af99ca8bee123684ad254263add556f0cf49486c0b3e32e6d303535714e505) ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-mac TARGETS googletest PACKAGE_HASH cbf020d5ef976c5db8b6e894c6c63151ade85ed98e7c502729dd20172acae5a8) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-mac TARGETS GoogleBenchmark PACKAGE_HASH ad25de0146769c91e179953d845de2bec8ed4a691f973f47e3eb37639381f665) ly_associate_package(PACKAGE_NAME qt-5.15.2-mac TARGETS Qt PACKAGE_HASH ac248833d65838e4bcef50f30c9ff02ba9464ff64b9ada52de2ad6045d38baec) -ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev1-mac TARGETS libsamplerate PACKAGE_HASH a72fd871915760c3b94df30186c9df906440c38ed38e58717f70a24c677c7b4b) +ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-mac TARGETS libsamplerate PACKAGE_HASH b912af40c0ac197af9c43d85004395ba92a6a859a24b7eacd920fed5854a97fe) diff --git a/cmake/3rdParty/Platform/Mac/FreeType2_mac.cmake b/cmake/3rdParty/Platform/Mac/FreeType2_mac.cmake deleted file mode 100644 index b7054a2527..0000000000 --- a/cmake/3rdParty/Platform/Mac/FreeType2_mac.cmake +++ /dev/null @@ -1,12 +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. -# - -set(FREETYPE2_LIBS ${BASE_PATH}/build/osx/darwin-clang-703.0.31/$,debug,release>/libfreetype2.a) diff --git a/cmake/3rdParty/Platform/Mac/cmake_mac_files.cmake b/cmake/3rdParty/Platform/Mac/cmake_mac_files.cmake index 5c7065a053..c569886384 100644 --- a/cmake/3rdParty/Platform/Mac/cmake_mac_files.cmake +++ b/cmake/3rdParty/Platform/Mac/cmake_mac_files.cmake @@ -16,7 +16,6 @@ set(FILES DirectXShaderCompiler_mac.cmake etc2comp_mac.cmake FbxSdk_mac.cmake - FreeType2_mac.cmake OpenSSL_mac.cmake Wwise_mac.cmake ) \ No newline at end of file diff --git a/cmake/3rdParty/Platform/Mac/tiff_mac.cmake b/cmake/3rdParty/Platform/Mac/tiff_mac.cmake deleted file mode 100644 index f29d99689d..0000000000 --- a/cmake/3rdParty/Platform/Mac/tiff_mac.cmake +++ /dev/null @@ -1,12 +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. -# - -set(TIFF_LIBS ${BASE_PATH}/libtiff/macosx_clang/libtiff.a) diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake index 1f05ee554e..3641d06dd9 100644 --- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake @@ -39,6 +39,8 @@ ly_associate_package(PACKAGE_NAME Blast-1.1.7-rev1-multiplatform ly_associate_package(PACKAGE_NAME PVRTexTool-4.24.0-rev4-multiplatform TARGETS PVRTexTool PACKAGE_HASH d0d6da61c7557de0d2c71fc35ba56c3be49555b703f0e853d4c58225537acf1e) # platform-specific: +ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-windows TARGETS freetype PACKAGE_HASH 88dedc86ccb8c92f14c2c033e51ee7d828fa08eafd6475c6aa963938a99f4bf3) +ly_associate_package(PACKAGE_NAME tiff-4.2.0.14-windows TARGETS tiff PACKAGE_HASH ab60d1398e4e1e375ec0f1a00cdb1d812a07c0096d827db575ce52dd6d714207) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev2-windows TARGETS AWSNativeSDK PACKAGE_HASH d762163d7db093bc9c25ab60bdafcc6f7a109a0010183a928e89b88ab7b20806) ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-windows TARGETS PhysX PACKAGE_HASH 198bed89d1aae7caaf5dadba24cee56235fe41725d004b64040d4e50d0f3aa1a) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-windows TARGETS mikkelsen PACKAGE_HASH 872c4d245a1c86139aa929f2b465b63ea4ea55b04ced50309135dd4597457a4e) @@ -48,4 +50,4 @@ ly_associate_package(PACKAGE_NAME d3dx12-headers-rev1-windows TARGETS d3d ly_associate_package(PACKAGE_NAME pyside2-qt-5.15.1-rev2-windows TARGETS pyside2 PACKAGE_HASH c90f3efcc7c10e79b22a33467855ad861f9dbd2e909df27a5cba9db9fa3edd0f) ly_associate_package(PACKAGE_NAME openimageio-2.1.16.0-rev1-windows TARGETS OpenImageIO PACKAGE_HASH b9f6d6df180ad240b9f17a68c1862c7d8f38234de0e692e83116254b0ee467e5) ly_associate_package(PACKAGE_NAME qt-5.15.2-windows TARGETS Qt PACKAGE_HASH edaf954c647c99727bfd313dab2959803d2df0873914bb96368c3d8286eed6d9) -ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev1-windows TARGETS libsamplerate PACKAGE_HASH 3dcf883d22dc9c99866eeed7bed3ede7ab1fbcbce16c45fdb1174c1c6ab7e358) +ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-windows TARGETS libsamplerate PACKAGE_HASH dcf3c11a96f212a52e2c9241abde5c364ee90b0f32fe6eeb6dcdca01d491829f) diff --git a/cmake/3rdParty/Platform/Windows/FreeType2_windows.cmake b/cmake/3rdParty/Platform/Windows/FreeType2_windows.cmake deleted file mode 100644 index 96958e4f3c..0000000000 --- a/cmake/3rdParty/Platform/Windows/FreeType2_windows.cmake +++ /dev/null @@ -1,12 +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. -# - -set(FREETYPE2_LIBS ${BASE_PATH}/build/win_x64/vc140/$,debug,release>/freetype2.lib) diff --git a/cmake/3rdParty/Platform/Windows/cmake_windows_files.cmake b/cmake/3rdParty/Platform/Windows/cmake_windows_files.cmake index 5a16784824..ff65abe10c 100644 --- a/cmake/3rdParty/Platform/Windows/cmake_windows_files.cmake +++ b/cmake/3rdParty/Platform/Windows/cmake_windows_files.cmake @@ -18,9 +18,7 @@ set(FILES dyad_windows.cmake etc2comp_windows.cmake FbxSdk_windows.cmake - FreeType2_windows.cmake libav_windows.cmake OpenSSL_windows.cmake - tiff_windows.cmake Wwise_windows.cmake ) diff --git a/cmake/3rdParty/Platform/Windows/tiff_windows.cmake b/cmake/3rdParty/Platform/Windows/tiff_windows.cmake deleted file mode 100644 index 1697f57430..0000000000 --- a/cmake/3rdParty/Platform/Windows/tiff_windows.cmake +++ /dev/null @@ -1,13 +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. -# - -set(TIFF_LIBS ${BASE_PATH}/libtiff/libtiff64rtdll$,d,>_vc140.lib) -set(TIFF_LINK_OPTIONS $<$:-Wl,>/ignore:4099) diff --git a/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake b/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake index a64b35ca05..3a644d2c6f 100644 --- a/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake +++ b/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake @@ -23,9 +23,11 @@ ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform TARGETS gla ly_associate_package(PACKAGE_NAME lux_core-2.2-rev5-multiplatform TARGETS lux_core PACKAGE_HASH c8c13cf7bc351643e1abd294d0841b24dee60e51647dff13db7aec396ad1e0b5) # platform-specific: +ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-mac-ios TARGETS freetype PACKAGE_HASH 67b4f57aed92082d3fd7c16aa244a7d908d90122c296b0a63f73e0a0b8761977) +ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-mac-ios TARGETS tiff PACKAGE_HASH a23ae1f8991a29f8e5df09d6d5b00d7768a740f90752cef465558c1768343709) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev2-ios TARGETS AWSNativeSDK PACKAGE_HASH ffd8a1a967bd67c996c64b64986706868bba5393e6d5c234cab578d66b2f8334) ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-ios TARGETS PhysX PACKAGE_HASH a2a48a09128337c72b9c2c1b8f43187c6c914e8509c9c6cd91810108748d7e09) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-ios TARGETS mikkelsen PACKAGE_HASH 976aaa3ccd8582346132a10af253822ccc5d5bcc9ea5ba44d27848f65ee88a8a) ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-ios TARGETS googletest PACKAGE_HASH 2f121ad9784c0ab73dfaa58e1fee05440a82a07cc556bec162eeb407688111a7) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-ios TARGETS GoogleBenchmark PACKAGE_HASH c2ffaed2b658892b1bcf81dee4b44cd1cb09fc78d55584ef5cb8ab87f2d8d1ae) -ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev1-ios TARGETS libsamplerate PACKAGE_HASH 126ab8335f3aa12322665c51d6cb144195b9b9e4c9f5a5d3fc1b560025cc772d) +ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-ios TARGETS libsamplerate PACKAGE_HASH 7656b961697f490d4f9c35d2e61559f6fc38c32102e542a33c212cd618fc2119) diff --git a/cmake/3rdParty/Platform/iOS/FreeType2_ios.cmake b/cmake/3rdParty/Platform/iOS/FreeType2_ios.cmake deleted file mode 100644 index f6310f5289..0000000000 --- a/cmake/3rdParty/Platform/iOS/FreeType2_ios.cmake +++ /dev/null @@ -1,12 +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. -# - -set(FREETYPE2_LIBS ${BASE_PATH}/build/osx/ios-clang-703.0.31/$,debug,release>/libfreetype2.a) diff --git a/cmake/3rdParty/Platform/iOS/cmake_ios_files.cmake b/cmake/3rdParty/Platform/iOS/cmake_ios_files.cmake index 78d8219424..e32a9f75bb 100644 --- a/cmake/3rdParty/Platform/iOS/cmake_ios_files.cmake +++ b/cmake/3rdParty/Platform/iOS/cmake_ios_files.cmake @@ -11,7 +11,6 @@ set(FILES BuiltInPackages_ios.cmake - FreeType2_ios.cmake OpenSSL_ios.cmake RadTelemetry_ios.cmake Wwise_ios.cmake diff --git a/cmake/3rdParty/cmake_files.cmake b/cmake/3rdParty/cmake_files.cmake index 95ce60e48a..98f8311d3b 100644 --- a/cmake/3rdParty/cmake_files.cmake +++ b/cmake/3rdParty/cmake_files.cmake @@ -18,11 +18,9 @@ set(FILES Finddyad.cmake Findetc2comp.cmake FindFbxSdk.cmake - FindFreeType2.cmake Findlibav.cmake FindOpenSSL.cmake FindRadTelemetry.cmake - Findtiff.cmake FindVkValidation.cmake FindWwise.cmake )