diff --git a/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass b/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass index 38a4524aa2..849094dd69 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass @@ -322,7 +322,14 @@ "Pass": "AuxGeomPass", "Attachment": "ColorInputOutput" } - } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + } ] }, { diff --git a/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass b/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass index b2e0cf088e..314d999e4d 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass @@ -427,6 +427,13 @@ "Pass": "DebugOverlayPass", "Attachment": "InputOutput" } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } } ] }, diff --git a/Gems/Atom/Feature/Common/Assets/Passes/UI.pass b/Gems/Atom/Feature/Common/Assets/Passes/UI.pass index 569fe1d722..ac43f17c11 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/UI.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/UI.pass @@ -7,6 +7,23 @@ "Name": "UIPassTemplate", "PassClass": "RasterPass", "Slots": [ + { + "Name": "DepthInputOutput", + "SlotType": "InputOutput", + "ScopeAttachmentUsage": "DepthStencil", + "LoadStoreAction": { + "ClearValue": { + "Type": "DepthStencil", + "Value": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + "LoadActionStencil": "Clear" + } + }, { "Name": "InputOutput", "SlotType": "InputOutput", diff --git a/Gems/Atom/Feature/Common/Assets/Passes/UIParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/UIParent.pass index 0069e89401..4ae67b9b09 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/UIParent.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/UIParent.pass @@ -10,6 +10,11 @@ { "Name": "InputOutput", "SlotType": "InputOutput" + }, + { + "Name": "DepthInputOutput", + "SlotType": "InputOutput", + "ScopeAttachmentUsage": "DepthStencil" } ], "PassRequests": [ @@ -24,6 +29,13 @@ "Pass": "Parent", "Attachment": "InputOutput" } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "DepthInputOutput" + } } ], "PassData": { diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h index 81b23068a1..94fd20f828 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h @@ -138,6 +138,12 @@ namespace AZ //! Without per draw viewport, the viewport setup in pass is usually used. void UnsetViewport(); + //! Set stencil reference for following draws which are added to this DynamicDrawContext + void SetStencilReference(uint8_t stencilRef); + + //! Get the current stencil reference. + uint8_t GetStencilReference() const; + //! Draw Indexed primitives with vertex and index data and per draw srg //! The per draw srg need to be provided if it's required by shader. void DrawIndexed(void* vertexData, uint32_t vertexCount, void* indexData, uint32_t indexCount, RHI::IndexFormat indexFormat, Data::Instance < ShaderResourceGroup> drawSrg = nullptr); @@ -204,10 +210,13 @@ namespace AZ bool m_useScissor = false; RHI::Scissor m_scissor; - // current scissor + // current viewport bool m_useViewport = false; RHI::Viewport m_viewport; + // Current stencil reference value + uint8_t m_stencilRef = 0; + // Cached RHI pipeline states for different combination of render states AZStd::unordered_map m_cachedRhiPipelineStates; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp index 00c2122825..09e3499820 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp @@ -382,6 +382,16 @@ namespace AZ m_useViewport = false; } + void DynamicDrawContext::SetStencilReference(uint8_t stencilRef) + { + m_stencilRef = stencilRef; + } + + uint8_t DynamicDrawContext::GetStencilReference() const + { + return m_stencilRef; + } + void DynamicDrawContext::SetShaderVariant(ShaderVariantId shaderVariantId) { AZ_Assert( m_initialized && m_supportShaderVariants, "DynamicDrawContext is not initialized or unable to support shader variants. " @@ -475,6 +485,9 @@ namespace AZ drawItem.m_viewports = &m_viewport; } + // Set stencil reference. Used when stencil is enabled. + drawItem.m_stencilRef = m_stencilRef; + drawItemInfo.m_sortKey = m_sortKey++; m_cachedDrawItems.emplace_back(drawItemInfo); } diff --git a/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist b/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist index 79bb726c9f..c7eddb10f2 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist +++ b/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist @@ -4,7 +4,7 @@ { "StableId": 1, "Options": { - "o_preMultiplyAlpha": "true", + "o_preMultiplyAlpha": "false", "o_alphaTest": "false", "o_srgbWrite": "true", "o_modulate": "Modulate::None" @@ -14,7 +14,7 @@ "StableId": 2, "Options": { "o_preMultiplyAlpha": "false", - "o_alphaTest": "false", + "o_alphaTest": "true", "o_srgbWrite": "true", "o_modulate": "Modulate::None" } diff --git a/Gems/LyShine/Code/Source/RenderGraph.cpp b/Gems/LyShine/Code/Source/RenderGraph.cpp index d5a1df7b15..ad2c46f8e6 100644 --- a/Gems/LyShine/Code/Source/RenderGraph.cpp +++ b/Gems/LyShine/Code/Source/RenderGraph.cpp @@ -137,7 +137,11 @@ namespace LyShine AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); const UiRenderer::UiShaderData& uiShaderData = uiRenderer->GetUiShaderData(); - dynamicDraw->SetShaderVariant(uiShaderData.m_shaderVariantDefault); + // Set render state + dynamicDraw->SetStencilState(uiRenderer->GetBaseState().m_stencilState); + dynamicDraw->SetTarget0BlendState(uiRenderer->GetBaseState().m_blendState); + + dynamicDraw->SetShaderVariant(uiRenderer->GetCurrentShaderVariant()); // Set up per draw SRG AZ::Data::Instance drawSrg = dynamicDraw->NewDrawSrg(); @@ -307,7 +311,7 @@ namespace LyShine //////////////////////////////////////////////////////////////////////////////////////////////////// void MaskRenderNode::Render(UiRenderer* uiRenderer) { - int priorBaseState = uiRenderer->GetBaseState(); + UiRenderer::BaseState priorBaseState = uiRenderer->GetBaseState(); if (m_isMaskingEnabled || m_drawBehind) { @@ -369,68 +373,61 @@ namespace LyShine #endif //////////////////////////////////////////////////////////////////////////////////////////////////// - void MaskRenderNode::SetupBeforeRenderingMask(UiRenderer* uiRenderer, bool firstPass, int priorBaseState) + void MaskRenderNode::SetupBeforeRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState) { + UiRenderer::BaseState curBaseState = priorBaseState; + // If using alpha test for drawing the renderable components on this element then we turn on // alpha test as a pre-render step - int alphaTest = 0; - if (m_useAlphaTest) - { - alphaTest = GS_ALPHATEST_GREATER; - } + curBaseState.m_useAlphaTest = m_useAlphaTest; // if either of the draw flags are checked then we may want to draw the renderable component(s) // on this element, otherwise use the color mask to stop them rendering - int colorMask = GS_COLMASK_NONE; + curBaseState.m_blendState.m_enable = false; + curBaseState.m_blendState.m_writeMask = 0x0; if ((m_drawBehind && firstPass) || (m_drawInFront && !firstPass)) { - colorMask = 0; // mask everything, don't write color or alpha, we just write to stencil buffer + curBaseState.m_blendState.m_enable = true; + curBaseState.m_blendState.m_writeMask = 0xF; } - if (m_isMaskingEnabled) + if (m_isMaskingEnabled) { + AZ::RHI::StencilOpState stencilOpState; + stencilOpState.m_func = AZ::RHI::ComparisonFunc::Equal; + // masking is enabled so we want to setup to increment (first pass) or decrement (second pass) // the stencil buff when rendering the renderable component(s) on this element - int passOp = 0; if (firstPass) { - passOp = STENCOP_PASS(FSS_STENCOP_INCR); - gEnv->pRenderer->PushProfileMarker(s_maskIncrProfileMarker); + stencilOpState.m_passOp = AZ::RHI::StencilOp::Increment; } else { - passOp = STENCOP_PASS(FSS_STENCOP_DECR); - gEnv->pRenderer->PushProfileMarker(s_maskDecrProfileMarker); + stencilOpState.m_passOp = AZ::RHI::StencilOp::Decrement; } + curBaseState.m_stencilState.m_frontFace = stencilOpState; + curBaseState.m_stencilState.m_backFace = stencilOpState; + // set up for stencil write - const uint32 stencilRef = uiRenderer->GetStencilRef(); - const uint32 stencilMask = 0xFF; - const uint32 stencilWriteMask = 0xFF; - const int32 stencilState = STENC_FUNC(FSS_STENCFUNC_EQUAL) - | STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | passOp; - gEnv->pRenderer->SetStencilState(stencilState, stencilRef, stencilMask, stencilWriteMask); - - // Set the base state that should be used when rendering the renderable component(s) on this - // element - uiRenderer->SetBaseState(priorBaseState | GS_STENCIL | alphaTest | colorMask); + AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); + dynamicDraw->SetStencilReference(uiRenderer->GetStencilRef()); + curBaseState.m_stencilState.m_enable = true; + curBaseState.m_stencilState.m_writeMask = 0xFF; } else { // masking is not enabled - - // Even if not masking we still use alpha test (if checked). This is primarily to help the user to - // visualize what their alpha tested mask looks like. - if (colorMask || alphaTest) - { - uiRenderer->SetBaseState(priorBaseState | colorMask | alphaTest); - } + curBaseState.m_stencilState.m_enable = false; } + + uiRenderer->SetBaseState(curBaseState); } //////////////////////////////////////////////////////////////////////////////////////////////////// - void MaskRenderNode::SetupAfterRenderingMask(UiRenderer* uiRenderer, bool firstPass, int priorBaseState) + void MaskRenderNode::SetupAfterRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState) { if (m_isMaskingEnabled) { @@ -442,26 +439,29 @@ namespace LyShine if (firstPass) { uiRenderer->IncrementStencilRef(); - gEnv->pRenderer->PopProfileMarker(s_maskIncrProfileMarker); } else { uiRenderer->DecrementStencilRef(); - gEnv->pRenderer->PopProfileMarker(s_maskDecrProfileMarker); } - // turn off stencil write and turn on stencil test - const uint32 stencilRef = uiRenderer->GetStencilRef(); - const uint32 stencilMask = 0xFF; - const uint32 stencilWriteMask = 0x00; - const int32 stencilState = STENC_FUNC(FSS_STENCFUNC_EQUAL) - | STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | STENCOP_PASS(FSS_STENCOP_KEEP); - gEnv->pRenderer->SetStencilState(stencilState, stencilRef, stencilMask, stencilWriteMask); + AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); + dynamicDraw->SetStencilReference(uiRenderer->GetStencilRef()); if (firstPass) { - // first pass, turn on stencil test for drawing children - uiRenderer->SetBaseState(priorBaseState | GS_STENCIL); + UiRenderer::BaseState curBaseState = priorBaseState; + + // turn off stencil write and turn on stencil test + curBaseState.m_stencilState.m_enable = true; + curBaseState.m_stencilState.m_writeMask = 0x00; + + AZ::RHI::StencilOpState stencilOpState; + stencilOpState.m_func = AZ::RHI::ComparisonFunc::Equal; + curBaseState.m_stencilState.m_frontFace = stencilOpState; + curBaseState.m_stencilState.m_backFace = stencilOpState; + + uiRenderer->SetBaseState(curBaseState); } else { @@ -475,7 +475,6 @@ namespace LyShine // remove any color mask or alpha test that we set in pre-render uiRenderer->SetBaseState(priorBaseState); } - } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -637,35 +636,24 @@ namespace LyShine //////////////////////////////////////////////////////////////////////////////////////////////////// void RenderGraph::BeginMask(bool isMaskingEnabled, bool useAlphaTest, bool drawBehind, bool drawInFront) { -#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (masks and render targets) - // this uses pool allocator MaskRenderNode* maskRenderNode = new MaskRenderNode(m_currentMask, isMaskingEnabled, useAlphaTest, drawBehind, drawInFront); m_currentMask = maskRenderNode; m_renderNodeListStack.push(&maskRenderNode->GetMaskRenderNodeList()); -#else - AZ_UNUSED(drawInFront); - AZ_UNUSED(drawBehind); - AZ_UNUSED(useAlphaTest); - AZ_UNUSED(isMaskingEnabled); -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// void RenderGraph::StartChildrenForMask() { -#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (masks and render targets) AZ_Assert(m_currentMask, "Calling StartChildrenForMask while not defining a mask"); m_renderNodeListStack.pop(); m_renderNodeListStack.push(&m_currentMask->GetContentRenderNodeList()); -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// void RenderGraph::EndMask() { -#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (masks and render targets) AZ_Assert(m_currentMask, "Calling EndMask while not defining a mask"); if (m_currentMask) { @@ -686,7 +674,6 @@ namespace LyShine m_renderNodeListStack.top()->push_back(newMaskRenderNode); } } -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -996,6 +983,12 @@ namespace LyShine // LYSHINE_ATOM_TODO - will probably need to support this when converting UI Editor to use Atom AZ_UNUSED(viewportSize); + AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); + + // Disable stencil and enable blend/color write + dynamicDraw->SetStencilState(uiRenderer->GetBaseState().m_stencilState); + dynamicDraw->SetTarget0BlendState(uiRenderer->GetBaseState().m_blendState); + // First render the render targets, they are sorted so that more deeply nested ones are rendered first. #ifdef LYSHINE_ATOM_TODO // keeping this code for reference for future phase (render targets) diff --git a/Gems/LyShine/Code/Source/RenderGraph.h b/Gems/LyShine/Code/Source/RenderGraph.h index 2f1586e857..355616a29a 100644 --- a/Gems/LyShine/Code/Source/RenderGraph.h +++ b/Gems/LyShine/Code/Source/RenderGraph.h @@ -22,12 +22,11 @@ #include #include +#include "UiRenderer.h" #ifndef _RELEASE #include "LyShineDebug.h" #endif -class UiRenderer; - namespace LyShine { enum RenderNodeType @@ -157,8 +156,8 @@ namespace LyShine #endif private: // functions - void SetupBeforeRenderingMask(UiRenderer* uiRenderer, bool firstPass, int priorBaseState); - void SetupAfterRenderingMask(UiRenderer* uiRenderer, bool firstPass, int priorBaseState); + void SetupBeforeRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState); + void SetupAfterRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState); private: // data AZStd::vector m_maskRenderNodes; //!< The render nodes used to render the mask shape diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index 57acbed5d5..e3ded694b5 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -20,7 +20,6 @@ #include #include #include -#include // LYSHINE_ATOM_TODO - remove when GS_DEPTHFUNC_LEQUAL reference is removed with LyShine render target Atom conversion #include #include @@ -33,9 +32,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// UiRenderer::UiRenderer(AZ::RPI::ViewportContextPtr viewportContext) - : m_baseState(GS_DEPTHFUNC_LEQUAL) - , m_stencilRef(0) - , m_viewportContext(viewportContext) + : 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 @@ -127,6 +124,8 @@ void UiRenderer::CreateDynamicDrawContext(AZ::RPI::ScenePtr scene, AZ::Data::Ins { "TEXCOORD", AZ::RHI::Format::R32G32_FLOAT }, { "BLENDINDICES", AZ::RHI::Format::R16G16_UINT } } ); + m_dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::StencilState + | AZ::RPI::DynamicDrawContext::DrawStateOptions::BlendMode); m_dynamicDraw->EndInit(); } @@ -170,25 +169,24 @@ void UiRenderer::CacheShaderData(const AZ::RHI::Ptr 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 = dynamicDraw->UseShaderVariant(shaderOptionsDefault); + AZ::RPI::ShaderOptionList shaderOptionsAlphaTest; + shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_preMultiplyAlpha"), AZ::Name("false"))); + shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("true"))); + shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("true"))); + shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); + m_uiShaderData.m_shaderVariantAlphaTest = dynamicDraw->UseShaderVariant(shaderOptionsAlphaTest); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiRenderer::BeginUiFrameRender() { -#ifdef LYSHINE_ATOM_TODO - m_renderer = gEnv->pRenderer; - - // we are rendering at the end of the frame, after tone mapping, so we should be writing sRGB values - m_renderer->SetSrgbWrite(true); - #ifndef _RELEASE if (m_debugTextureDataRecordLevel > 0) { m_texturesUsedInFrame.clear(); } #endif -#endif - + // Various platform drivers expect all texture slots used in the shader to be bound BindNullTexture(); } @@ -204,18 +202,10 @@ void UiRenderer::EndUiFrameRender() //////////////////////////////////////////////////////////////////////////////////////////////////// void UiRenderer::BeginCanvasRender() { -#ifdef LYSHINE_ATOM_TODO - m_baseState = GS_NODEPTHTEST; - m_stencilRef = 0; - // Set default starting state - IRenderer* renderer = gEnv->pRenderer; - - renderer->SetCullMode(R_CULL_DISABLE); - renderer->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); - renderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST); -#endif + // Set base state + m_baseState.ResetToDefault(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -229,11 +219,13 @@ AZ::RHI::Ptr UiRenderer::GetDynamicDrawContext() return m_dynamicDraw; } +//////////////////////////////////////////////////////////////////////////////////////////////////// const UiRenderer::UiShaderData& UiRenderer::GetUiShaderData() { return m_uiShaderData; } +//////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Matrix4x4 UiRenderer::GetModelViewProjectionMatrix() { auto viewportContext = GetViewportContext(); @@ -253,6 +245,7 @@ AZ::Matrix4x4 UiRenderer::GetModelViewProjectionMatrix() return modelViewProjMat; } +//////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Vector2 UiRenderer::GetViewportSize() { auto viewportContext = GetViewportContext(); @@ -267,17 +260,30 @@ AZ::Vector2 UiRenderer::GetViewportSize() } //////////////////////////////////////////////////////////////////////////////////////////////////// -int UiRenderer::GetBaseState() +UiRenderer::BaseState UiRenderer::GetBaseState() { return m_baseState; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UiRenderer::SetBaseState(int state) +void UiRenderer::SetBaseState(BaseState state) { m_baseState = state; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +AZ::RPI::ShaderVariantId UiRenderer::GetCurrentShaderVariant() +{ + AZ::RPI::ShaderVariantId variantId = m_uiShaderData.m_shaderVariantDefault; + + if (m_baseState.m_useAlphaTest) + { + variantId = m_uiShaderData.m_shaderVariantAlphaTest; + } + + return variantId; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// uint32 UiRenderer::GetStencilRef() { @@ -354,6 +360,7 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption) { if (recordingOption > 0) { +#ifdef LYSHINE_ATOM_TODO // Convert debug to use Atom images // compute the total area of all the textures, also create a vector that we can sort by area AZStd::vector textures; int totalArea = 0; @@ -431,6 +438,7 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption) texture->GetWidth(), texture->GetHeight(), texture->GetDataSize(), texture->GetFormatName(), texture->GetName()); WriteLine(buffer, white); } +#endif } } diff --git a/Gems/LyShine/Code/Source/UiRenderer.h b/Gems/LyShine/Code/Source/UiRenderer.h index 888c88586a..413e8c45cf 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.h +++ b/Gems/LyShine/Code/Source/UiRenderer.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifndef _RELEASE @@ -38,6 +39,36 @@ public: // types AZ::RHI::ShaderInputConstantIndex m_isClampInputIndex; AZ::RPI::ShaderVariantId m_shaderVariantDefault; + AZ::RPI::ShaderVariantId m_shaderVariantAlphaTest; + }; + + // Base state + struct BaseState + { + BaseState() + { + ResetToDefault(); + } + + void ResetToDefault() + { + // Enable blend/color write + m_blendState.m_enable = true; + m_blendState.m_writeMask = 0xF; + m_blendState.m_blendSource = AZ::RHI::BlendFactor::AlphaSource; + m_blendState.m_blendDest = AZ::RHI::BlendFactor::AlphaSourceInverse; + m_blendState.m_blendOp = AZ::RHI::BlendOp::Add; + + // Disable stencil + m_stencilState = AZ::RHI::StencilState(); + m_stencilState.m_enable = 0; + + m_useAlphaTest = false; + } + + AZ::RHI::TargetBlendState m_blendState; + AZ::RHI::StencilState m_stencilState; + bool m_useAlphaTest = false; }; public: // member functions @@ -74,10 +105,13 @@ public: // member functions AZ::Vector2 GetViewportSize(); //! Get the current base state - int GetBaseState(); + BaseState GetBaseState(); //! Set the base state - void SetBaseState(int state); + void SetBaseState(BaseState state); + + //! Get the shader variant based on current render properties + AZ::RPI::ShaderVariantId GetCurrentShaderVariant(); //! Get the current stencil test reference value uint32 GetStencilRef(); @@ -126,8 +160,8 @@ protected: // attributes static constexpr char LogName[] = "UiRenderer"; - int m_baseState; - uint32 m_stencilRef; + BaseState m_baseState; + uint32 m_stencilRef = 0; UiShaderData m_uiShaderData; AZ::RHI::Ptr m_dynamicDraw; diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleMask.tif b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleMask.tif new file mode 100644 index 0000000000..fd29516609 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleMask.tif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8474b897fe02f70ed8d0e5c47cae8c816c832a7a5739b8c32317737fd275774f +size 1069752