Forráskód Böngészése

Merge pull request #10259 from aws-lumberyard-dev/Atom/antonmic/FullscreenShadowTdrFix

Fix for TDR caused by fullscreen shadow shader
antonmic 3 éve
szülő
commit
ed49a06488

+ 12 - 0
Gems/Atom/Feature/Common/Assets/Passes/FullscreenShadow.pass

@@ -50,6 +50,9 @@
                         "LoadAction": "DontCare",
                         "StoreAction": "Store"
                     }
+                    // Todo: test Compute Shader version with async compute and LDS optimizations
+                    //"ScopeAttachmentUsage": "Shader",
+                    //"ShaderInputName": "m_fullscreenShadowOutput"
                 }
             ],
             "ImageAttachments": [
@@ -97,6 +100,15 @@
                 },
                 "PipelineViewTag": "MainCamera"
             }
+            // Todo: test Compute Shader version with async compute and LDS optimizations
+            // "PassData": {
+            //     "$type": "ComputePassData",
+            //     "ShaderAsset": {
+            //         "FilePath": "Shaders/Shadow/FullscreenShadow.shader"
+            //     },
+            //     "Make Fullscreen Pass": true,
+            //     "PipelineViewTag": "MainCamera"
+            // }
         }
     }
 }

+ 89 - 85
Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/DirectionalLightShadowCalculator.azsli

@@ -6,6 +6,10 @@
  *
  */
  
+#ifndef USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+#define USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT 0
+#endif
+
 enum class ShadowFilterMethod {None, Pcf, Esm, EsmPcf};
 
 // avoiding artifact between cascade levels.
@@ -22,11 +26,11 @@ class DirectionalShadowCalculator
     {
         m_blendBetweenCascadesEnable = enable;
     }
-    
+
     void SetShadowmaps(Texture2DArray<float> dirShadowMap, Texture2DArray<float> expShadowmap)
     {
-        m_directionalLightShadowmap = dirShadowMap;   
-        m_directionalLightExponentialShadowmap = expShadowmap;        
+        m_directionalLightShadowmap = dirShadowMap;
+        m_directionalLightExponentialShadowmap = expShadowmap;
     }
 
     void SetReceiverShadowPlaneBiasEnable(const bool enable)
@@ -38,17 +42,17 @@ class DirectionalShadowCalculator
     {
         m_worldNormal = worldNormal;
     }
-    
+
     void SetWorldPos(const float3 worldPos)
     {
         m_worldPos = worldPos;
     }
-    
+
     void SetLightIndex(const int lightIndex)
     {
-        m_lightIndex = lightIndex;    
+        m_lightIndex = lightIndex;
     }
-    
+
     void SetFilterMode(const ShadowFilterMethod filterMode)
     {
         m_filterMode = filterMode;
@@ -57,18 +61,18 @@ class DirectionalShadowCalculator
     
     bool IsShadowCoordInCascade(float3 shadowCoord, uint shadowMapSize);
 
-    float GetVisibility();    
+    float GetVisibility();
     float GetThickness();
-    
-    float GetVisibilityFromLightNoFilter();  
-    float SamplePcfBicubic(const float3 shadowCoord, const uint indexOfCascade);     
-    float GetVisibilityFromLightPcf();            
-    float GetVisibilityFromLightEsm();    
+
+    float GetVisibilityFromLightNoFilter();
+    float SamplePcfBicubic(const float3 shadowCoord, const int indexOfCascade);
+    float GetVisibilityFromLightPcf();
+    float GetVisibilityFromLightEsm();
     float GetVisibilityFromLightEsmPcf();
     float CalculateCascadeBlendAmount(const float3 texCoord);
-    bool2 IsShadowed(const float3 shadowCoord, const uint indexOfCascade); 
+    bool2 IsShadowed(const float3 shadowCoord, const int indexOfCascade);
     void ComputeShadowCoords();
-    
+
     float3 m_shadowCoords[ViewSrg::MaxCascadeCount];
     float m_slopeBias[ViewSrg::MaxCascadeCount];
     float3 m_shadowPosDX[ViewSrg::MaxCascadeCount];
@@ -81,6 +85,7 @@ class DirectionalShadowCalculator
 
     int m_lightIndex;
     int m_cascadeIndex;
+    int m_cascadeCount;
     ShadowFilterMethod m_filterMode;
 
     Texture2DArray<float> m_directionalLightShadowmap;   
@@ -106,16 +111,16 @@ float DirectionalShadowCalculator::GetThickness()
     Texture2DArray<float> shadowmap = m_directionalLightShadowmap;
     
     if(m_cascadeIndex >= 0)
-    {  
+    {
         float3 shadowCoord = m_shadowCoords[m_cascadeIndex];
         if (IsShadowCoordInCascade(shadowCoord, size))
         {
-            const float depthBufferValue = shadowmap.Sample(PassSrg::LinearSampler, float3(shadowCoord.xy, m_cascadeIndex)).r;
-            
+            const float depthBufferValue = shadowmap.SampleLevel(PassSrg::LinearSampler, float3(shadowCoord.xy, m_cascadeIndex), 0).r;
+
             // Normalized thickness (avoid negative values given by precision errors or shrinking offsets)
             const float deltaDepth = max(shadowCoord.z - depthBufferValue,0.0);
 
-            const float viewSpaceThickness = ViewSrg::m_directionalLightShadows[m_lightIndex].m_far_minus_near * deltaDepth;            
+            const float viewSpaceThickness = ViewSrg::m_directionalLightShadows[m_lightIndex].m_far_minus_near * deltaDepth;
             return viewSpaceThickness;
         }
     }
@@ -131,16 +136,17 @@ void DirectionalShadowCalculator::ComputeShadowCoords()
     const float4x4 worldToLightViewMatrices[ViewSrg::MaxCascadeCount] = ViewSrg::m_directionalLightShadows[m_lightIndex].m_worldToLightViewMatrices;
 
     const uint size = ViewSrg::m_directionalLightShadows[m_lightIndex].m_shadowmapSize;
-    const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
     const float3 shadowOffset = ComputeNormalShadowOffset(ViewSrg::m_directionalLightShadows[m_lightIndex].m_normalShadowBias, m_worldNormal, ViewSrg::m_directionalLightShadows[m_lightIndex].m_shadowmapSize);
 
+    m_cascadeCount = min(ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount, ViewSrg::MaxCascadeCount);
     m_cascadeIndex = -1;
-    for (uint index = 0; index < cascadeCount; ++index)
-    {        
+
+    for (int index = 0; index < m_cascadeCount; ++index)
+    {
         float4 lightSpacePos = mul(worldToLightViewMatrices[index], float4(m_worldPos + shadowOffset, 1.));
         lightSpacePos.z += shadowBias;
-        
-        const float4 clipSpacePos = mul(lightViewToShadowmapMatrices[index], lightSpacePos);                
+
+        const float4 clipSpacePos = mul(lightViewToShadowmapMatrices[index], lightSpacePos);
         m_shadowCoords[index] = clipSpacePos.xyz / clipSpacePos.w;
 
         // Cache Cascade index
@@ -149,19 +155,21 @@ void DirectionalShadowCalculator::ComputeShadowCoords()
             m_cascadeIndex = index;
         }
     }
-            
+
+// Todo: No ddx in compute, find a way to leverage world space normal for this
+#if !USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
     if (m_receiverShadowPlaneBiasEnable)
     {
-        [unroll]
-        for(int i = 0 ; i < ViewSrg::MaxCascadeCount ; ++i)
+        for(int i = 0 ; i < m_cascadeCount; ++i)
         {
             m_shadowPosDX[i] = ddx_fine(m_shadowCoords[i]);
-            m_shadowPosDY[i] = ddy_fine(m_shadowCoords[i]);        
-        }    
-    }        
+            m_shadowPosDY[i] = ddy_fine(m_shadowCoords[i]);
+        }
+    }
+#endif
 }
 
-bool2 DirectionalShadowCalculator::IsShadowed(const float3 shadowCoord, const uint indexOfCascade)
+bool2 DirectionalShadowCalculator::IsShadowed(const float3 shadowCoord, const int indexOfCascade)
 {
     // size is the shadowap's width and height.
     const uint size = ViewSrg::m_directionalLightShadows[m_lightIndex].m_shadowmapSize;
@@ -170,7 +178,7 @@ bool2 DirectionalShadowCalculator::IsShadowed(const float3 shadowCoord, const ui
     if (IsShadowCoordInCascade(shadowCoord, size))
     {
         const float3 coord = float3(shadowCoord.xy, indexOfCascade);
-        const float depthInShadowmap = m_directionalLightShadowmap.Sample(PassSrg::LinearSampler, coord).r;
+        const float depthInShadowmap = m_directionalLightShadowmap.SampleLevel(PassSrg::LinearSampler, coord, 0).r;
         const float depthDiff = shadowCoord.z - depthInShadowmap;
         return bool2(true, (depthDiff > m_slopeBias[indexOfCascade]));
     }
@@ -178,7 +186,7 @@ bool2 DirectionalShadowCalculator::IsShadowed(const float3 shadowCoord, const ui
 }
 
 float DirectionalShadowCalculator::GetVisibility()
-{   
+{
     ComputeShadowCoords();
 
     // Todo: slope bias exhibits noticeable artifacts, especially with sharp normal values derived from fullscreen
@@ -196,12 +204,12 @@ float DirectionalShadowCalculator::GetVisibility()
         {
             return 0;
         }
-    
+
         // Calculate slope bias
         NdotL = max(NdotL, 0.01);
         const float sinTheta = sqrt(1 - NdotL * NdotL);
         const float tanTheta = sinTheta / NdotL;
-        for (uint cascadeIndex = 0; cascadeIndex < ViewSrg::MaxCascadeCount; ++cascadeIndex)
+        for (int cascadeIndex = 0; cascadeIndex < m_cascadeCount; ++cascadeIndex)
         {
             const float slopeBiasBase = ViewSrg::m_directionalLightShadows[m_lightIndex].m_slopeBiasBase[cascadeIndex];
             m_slopeBias[cascadeIndex] = slopeBiasBase * tanTheta;
@@ -209,13 +217,20 @@ float DirectionalShadowCalculator::GetVisibility()
     }
     else
     {
-        for (uint cascadeIndex = 0; cascadeIndex < ViewSrg::MaxCascadeCount; ++cascadeIndex)
+        for (int cascadeIndex = 0; cascadeIndex < m_cascadeCount; ++cascadeIndex)
         {
             m_slopeBias[cascadeIndex] = 0;
         }
     }
 
     float lit = 1;
+
+    [branch]
+    if (m_cascadeIndex < 0)
+    {
+        return lit;
+    }
+
     switch(m_filterMode)
     {
         case ShadowFilterMethod::None:
@@ -231,25 +246,21 @@ float DirectionalShadowCalculator::GetVisibility()
             lit = GetVisibilityFromLightEsmPcf();
             break;
     }
-                
+
     return lit;
 }
 
 float DirectionalShadowCalculator::GetVisibilityFromLightNoFilter()
-{       
-    if (m_cascadeIndex >= 0)
+{
+    const bool2 checkedShadowed = IsShadowed(m_shadowCoords[m_cascadeIndex], m_cascadeIndex);
+    if (checkedShadowed.x)
     {
-        const bool2 checkedShadowed = IsShadowed(m_shadowCoords[m_cascadeIndex], m_cascadeIndex);
-
-        if (checkedShadowed.x)
-        {
-            return checkedShadowed.y ? 0. : 1.;
-        }
+        return checkedShadowed.y ? 0. : 1.;
     }
     return 1.;
-}    
+}
 
-float DirectionalShadowCalculator::SamplePcfBicubic(const float3 shadowCoord, const uint indexOfCascade)
+float DirectionalShadowCalculator::SamplePcfBicubic(const float3 shadowCoord, const int indexOfCascade)
 {
     const uint filteringSampleCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_filteringSampleCount;
     const uint size = ViewSrg::m_directionalLightShadows[m_lightIndex].m_shadowmapSize;
@@ -261,10 +272,15 @@ float DirectionalShadowCalculator::SamplePcfBicubic(const float3 shadowCoord, co
     param.invShadowMapSize = rcp(size); 
     param.comparisonValue = shadowCoord.z;
     param.samplerState = SceneSrg::m_hwPcfSampler;
+
+#if USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+    param.receiverPlaneDepthBias = 0;
+#else
     param.receiverPlaneDepthBias = m_receiverShadowPlaneBiasEnable ? ComputeReceiverPlaneDepthBias(m_shadowPosDX[indexOfCascade], m_shadowPosDY[indexOfCascade]) : 0;
+#endif
     
-    [branch]     
-    if (filteringSampleCount <= 4)       
+    [branch]
+    if (filteringSampleCount <= 4)
     {
         return SampleShadowMapBicubic_4Tap(param);
     }
@@ -279,51 +295,41 @@ float DirectionalShadowCalculator::SamplePcfBicubic(const float3 shadowCoord, co
 }
 
 float DirectionalShadowCalculator::GetVisibilityFromLightPcf()
-{   
-    const uint size = ViewSrg::m_directionalLightShadows[m_lightIndex].m_shadowmapSize;
-    const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
+{
+    float lit = SamplePcfBicubic(m_shadowCoords[m_cascadeIndex], m_cascadeIndex);
 
-    [branch]
-    if (m_cascadeIndex >= 0)
+    if(m_blendBetweenCascadesEnable) 
     {
-        float lit = SamplePcfBicubic(m_shadowCoords[m_cascadeIndex], m_cascadeIndex);
-        
-        if(m_blendBetweenCascadesEnable) 
-        {  
-            const float blendBetweenCascadesAmount = CalculateCascadeBlendAmount(m_shadowCoords[m_cascadeIndex].xyz);
-
-            const int nextCascadeIndex = m_cascadeIndex + 1;
-            [branch]
-            if (blendBetweenCascadesAmount < 1.0f && nextCascadeIndex < cascadeCount)
-            {
-                const float nextLit = SamplePcfBicubic(m_shadowCoords[nextCascadeIndex], nextCascadeIndex);
-                lit = lerp(nextLit, lit, blendBetweenCascadesAmount);             
-            }
-        } 
+        const float blendBetweenCascadesAmount = CalculateCascadeBlendAmount(m_shadowCoords[m_cascadeIndex].xyz);
 
-        return lit;
-    }
+        const int nextCascadeIndex = m_cascadeIndex + 1;
+        [branch]
+        if (blendBetweenCascadesAmount < 1.0f && nextCascadeIndex < m_cascadeCount)
+        {
+            const float nextLit = SamplePcfBicubic(m_shadowCoords[nextCascadeIndex], nextCascadeIndex);
+            lit = lerp(nextLit, lit, blendBetweenCascadesAmount);
+        }
+    } 
 
-    return 1.;
+    return lit;
 } 
 
 float DirectionalShadowCalculator::GetVisibilityFromLightEsm()
 {
-    const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
-
-    for (uint indexOfCascade = m_cascadeIndex; indexOfCascade < cascadeCount; ++indexOfCascade)
+    for (int indexOfCascade = m_cascadeIndex; indexOfCascade < m_cascadeCount; ++indexOfCascade)
     {
         const float3 shadowCoord = m_shadowCoords[indexOfCascade];
-        const float distanceMin = ViewSrg::m_esmsDirectional[indexOfCascade].m_lightDistanceOfCameraViewFrustum;
         bool2 checkedShadowed = IsShadowed(shadowCoord, indexOfCascade);
+
+        const float distanceMin = ViewSrg::m_esmsDirectional[indexOfCascade].m_lightDistanceOfCameraViewFrustum;
         const float depthDiff = shadowCoord.z - distanceMin;
-    
+
         [branch]
         if (checkedShadowed.x && depthDiff >= 0)
         {
             const float distanceWithinCameraView = depthDiff / (1. - distanceMin);
             const float3 coord = float3(shadowCoord.xy, indexOfCascade);
-            const float occluder = m_directionalLightExponentialShadowmap.Sample(PassSrg::LinearSampler, coord).r;                        
+            const float occluder = m_directionalLightExponentialShadowmap.SampleLevel(PassSrg::LinearSampler, coord, 0).r;
             const float exponent = -EsmExponentialShift * (distanceWithinCameraView - occluder);
             const float ratio = exp(exponent);
 
@@ -335,21 +341,20 @@ float DirectionalShadowCalculator::GetVisibilityFromLightEsm()
 
 float DirectionalShadowCalculator::GetVisibilityFromLightEsmPcf()
 {
-    const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
-
-    for (uint indexOfCascade = m_cascadeIndex; indexOfCascade < cascadeCount; ++indexOfCascade)
+    for (int indexOfCascade = m_cascadeIndex; indexOfCascade < m_cascadeCount; ++indexOfCascade)
     {
         const float3 shadowCoord = m_shadowCoords[indexOfCascade];
-        const float distanceMin = ViewSrg::m_esmsDirectional[indexOfCascade].m_lightDistanceOfCameraViewFrustum;
         bool2 checkedShadowed = IsShadowed(shadowCoord, indexOfCascade);
+
+        const float distanceMin = ViewSrg::m_esmsDirectional[indexOfCascade].m_lightDistanceOfCameraViewFrustum;
         const float depthDiff = shadowCoord.z - distanceMin;
-    
+
         [branch]
         if (checkedShadowed.x && depthDiff >= 0)
         {
             const float distanceWithinCameraView = depthDiff / (1. - distanceMin);
             const float3 coord = float3(shadowCoord.xy, indexOfCascade);
-            const float occluder = m_directionalLightExponentialShadowmap.Sample(PassSrg::LinearSampler, coord).r;
+            const float occluder = m_directionalLightExponentialShadowmap.SampleLevel(PassSrg::LinearSampler, coord, 0).r;
             const float exponent = -EsmExponentialShift * (distanceWithinCameraView - occluder);
             float ratio = exp(exponent);
 
@@ -364,7 +369,6 @@ float DirectionalShadowCalculator::GetVisibilityFromLightEsmPcf()
     return 1.;
 }
 
-
 float DirectionalShadowCalculator::CalculateCascadeBlendAmount(const float3 texCoord)
 {
     const float CascadeBlendArea = 0.015f; // might be worth exposing this as a slider.
@@ -372,4 +376,4 @@ float DirectionalShadowCalculator::CalculateCascadeBlendAmount(const float3 texC
     const float distanceToOneMin = min3(1.0f - texCoord);
     const float currentPixelsBlendBandLocation = min(min(texCoord.x, texCoord.y), distanceToOneMin);
     return currentPixelsBlendBandLocation / CascadeBlendArea;
-}
+}

+ 53 - 16
Gems/Atom/Feature/Common/Assets/Shaders/Shadow/FullscreenShadow.azsl

@@ -6,23 +6,27 @@
  *
  */
 
+#define THREADS 16
 
+// Todo: test Compute Shader version with async compute and LDS optimizations
+#define USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT 0
 
 #include <Atom/Features/SrgSemantics.azsli>
+#include <viewsrg.srgi>
+#include <scenesrg.srgi>
+
+#include <Atom/RPI/Math.azsli>
+
+#if !USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+    #include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
+    #include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
+#endif
 
-#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
-#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
-#include <Atom/Features/PostProcessing/PostProcessUtil.azsli>
-#include <Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli>
 #include <Atom/Features/Shadow/NormalOffsetShadows.azsli>
 #include <Atom/Features/Shadow/BicubicPcfFilters.azsli>
 #include <Atom/Features/Shadow/Shadow.azsli>
-#include <Atom/RPI/Math.azsli>
-#include <viewsrg.srgi>
-#include <scenesrg.srgi>
-
 
-ShaderResourceGroup PassSrg : SRG_PerPass
+ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
 {
     Sampler PointSampler
     {
@@ -60,18 +64,29 @@ ShaderResourceGroup PassSrg : SRG_PerPass
     Texture2DArray<float> m_directionalShadowmapsESM;
     Texture2DMS<float> m_depth;
     Texture2D<float> m_depthLinear;
+#if USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+    RWTexture2D<float> m_fullscreenShadowOutput;
+#endif
 }
 
-#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
 #include <Atom/Features/Shadow/DirectionalLightShadowCalculator.azsli>
 
-void ComputeWorldNormalAndPosition(VSOutput IN, out float3 outPositionWS, out float3 outNormalWS)
+#if USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+    void ComputeWorldNormalAndPosition(const uint2 screenPos, out float3 outPositionWS, out float3 outNormalWS)
+#else
+    void ComputeWorldNormalAndPosition(VSOutput IN, out float3 outPositionWS, out float3 outNormalWS)
+#endif
 {
-    const int2   screenPos = IN.m_position.xy;          // The coordinates of the screen pixel being shaded
-    const float2 screenUV  = IN.m_texCoord.xy;          // The UV value [0, 1] of the screen pixel
     const float2 pixelSize = rcp(PassSrg::m_constantData.m_screenSize.xy);  // How big a pixel is in screen UV space
     const float2 halfPixel = pixelSize * 0.5f;
 
+#if USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+    const float2 screenUV  = screenPos * pixelSize + halfPixel;             // The UV value [0, 1] of the screen pixel
+#else
+    const int2   screenPos = IN.m_position.xy;          // The coordinates of the screen pixel being shaded
+    const float2 screenUV  = IN.m_texCoord.xy;          // The UV value [0, 1] of the screen pixel
+#endif
+
     // Do 2 depth gather ops to get 5 depth values (cross centered on pixel being shaded). Reminder that gather is laid out like so:
     //  W Z
     //  X Y
@@ -106,13 +121,34 @@ void ComputeWorldNormalAndPosition(VSOutput IN, out float3 outPositionWS, out fl
     outNormalWS   = mul(ViewSrg::m_viewMatrixInverse, float4(normalVS, 0) ).xyz;
 }
 
+#if USING_COMPUTE_SHADER_DIRECTIONAL_LIGHT
+
+[numthreads(THREADS, THREADS, 1)]
+void MainCS(uint3 thread_id : SV_GroupThreadID, uint3 group_id : SV_GroupID, uint3 dispatch_id: SV_DispatchThreadID, uint linear_id : SV_GroupIndex)
+{
+    float3 positionWS;
+    float3 normalWS;
+    ComputeWorldNormalAndPosition(dispatch_id.xy, positionWS, normalWS);
+   
+    DirectionalShadowCalculator calc;
+    calc.SetLightIndex(PassSrg::m_constantData.m_lightIndex);
+    calc.SetWorldNormal(normalWS);
+    calc.SetReceiverShadowPlaneBiasEnable(PassSrg::m_constantData.m_receiverShadowPlaneBiasEnable);
+    calc.SetFilterMode((ShadowFilterMethod)PassSrg::m_constantData.m_filterMode);
+    calc.SetBlendBetweenCascadesEnable(PassSrg::m_constantData.m_blendBetweenCascadesEnable);
+    calc.SetShadowmaps(PassSrg::m_directionalShadowmaps, PassSrg::m_directionalShadowmapsESM);
+    calc.SetWorldPos(positionWS);
+
+   PassSrg::m_fullscreenShadowOutput[dispatch_id.xy] = calc.GetVisibility();
+}
+
+#else
+
 PSOutput MainPS(VSOutput IN)
 {
     float3 positionWS;
     float3 normalWS;
     ComputeWorldNormalAndPosition(IN, positionWS, normalWS);
-   
-    PSOutput OUT;
 
     DirectionalShadowCalculator calc;
     calc.SetLightIndex(PassSrg::m_constantData.m_lightIndex);
@@ -123,10 +159,11 @@ PSOutput MainPS(VSOutput IN)
     calc.SetShadowmaps(PassSrg::m_directionalShadowmaps, PassSrg::m_directionalShadowmapsESM);
     calc.SetWorldPos(positionWS);
 
+    PSOutput OUT;
     float vis = calc.GetVisibility();
     OUT.m_color = saturate(vis.xxxx);
    
     return OUT; 
 }
 
-
+#endif

+ 13 - 0
Gems/Atom/Feature/Common/Assets/Shaders/Shadow/FullscreenShadow.shader

@@ -38,4 +38,17 @@
             }
         }
     ]
+
+    // Todo: test Compute Shader version with async compute and LDS optimizations
+    // "ProgramSettings" :
+    // {
+    //     "EntryPoints":
+    //     [
+    //         {
+    //             "name" : "MainCS",
+    //             "type" : "Compute"
+    //         }
+    //     ]
+    // }
+
 }

+ 13 - 1
Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake

@@ -33,6 +33,11 @@ set(FILES
     Materials/Types/EnhancedPBR_Shadowmap_WithPS.shader
     Materials/Types/EnhancedPBR_SubsurfaceState.lua
     Materials/Types/EnhancedSurface_ForwardPass.azsli
+    Materials/Types/Eye.azsl
+    Materials/Types/Eye.materialtype
+    Materials/Types/Eye.shader
+    Materials/Types/EyeSurface_ForwardPass.azsli
+    Materials/Types/Eye_Common.azsli
     Materials/Types/Skin.azsl
     Materials/Types/Skin.materialtype
     Materials/Types/Skin.shader
@@ -62,6 +67,7 @@ set(FILES
     Materials/Types/StandardPBR_ForwardPass.azsl
     Materials/Types/StandardPBR_ForwardPass.shader
     Materials/Types/StandardPBR_ForwardPass_EDS.shader
+    Materials/Types/StandardPBR_HandleIrradianceColorSource.lua
     Materials/Types/StandardPBR_HandleOpacityDoubleSided.lua
     Materials/Types/StandardPBR_HandleOpacityMode.lua
     Materials/Types/StandardPBR_LowEndForward.shader
@@ -75,10 +81,12 @@ set(FILES
     Materials/Types/StandardSurface_ForwardPass.azsli
     Materials/Types/MaterialFunctions/EnhancedParallaxDepth.azsli
     Materials/Types/MaterialFunctions/EvaluateEnhancedSurface.azsli
+    Materials/Types/MaterialFunctions/EvaluateEyeSurface.azsli
     Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli
     Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli
     Materials/Types/MaterialFunctions/MultilayerParallaxDepth.azsli
     Materials/Types/MaterialFunctions/ParallaxDepth.azsli
+    Materials/Types/MaterialFunctions/ParallaxShadowUtil.azsli
     Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli
     Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli
     Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli
@@ -146,6 +154,7 @@ set(FILES
     Passes/DiffuseProbeGridClassification.pass
     Passes/DiffuseProbeGridDownsample.pass
     Passes/DiffuseProbeGridPrepare.pass
+    Passes/DiffuseProbeGridQuery.pass
     Passes/DiffuseProbeGridRayTracing.pass
     Passes/DiffuseProbeGridRelocation.pass
     Passes/DiffuseProbeGridRender.pass
@@ -174,8 +183,8 @@ set(FILES
     Passes/ForwardMSAA.pass
     Passes/ForwardSubsurfaceMSAA.pass
     Passes/FullscreenCopy.pass
-    Passes/FullscreenShadow.pass
     Passes/FullscreenOutputOnly.pass
+    Passes/FullscreenShadow.pass
     Passes/HDRColorGrading.pass
     Passes/ImGui.pass
     Passes/KawaseShadowBlur.pass
@@ -294,6 +303,7 @@ set(FILES
     ShaderLib/Atom/Features/PBR/Lighting/BaseLighting.azsli
     ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli
     ShaderLib/Atom/Features/PBR/Lighting/EnhancedLighting.azsli
+    ShaderLib/Atom/Features/PBR/Lighting/EyeLighting.azsli
     ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli
     ShaderLib/Atom/Features/PBR/Lighting/SkinLighting.azsli
     ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli
@@ -317,6 +327,7 @@ set(FILES
     ShaderLib/Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli
     ShaderLib/Atom/Features/PBR/Surfaces/DualSpecularSurface.azsli
     ShaderLib/Atom/Features/PBR/Surfaces/EnhancedSurface.azsli
+    ShaderLib/Atom/Features/PBR/Surfaces/EyeSurface.azsli
     ShaderLib/Atom/Features/PBR/Surfaces/SkinSurface.azsli
     ShaderLib/Atom/Features/PBR/Surfaces/StandardSurface.azsli
     ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli
@@ -340,6 +351,7 @@ set(FILES
     ShaderLib/Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli
     ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli
     ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli
+    ShaderLib/Atom/Features/Shadow/DirectionalLightShadowCalculator.azsli
     ShaderLib/Atom/Features/Shadow/ESM.azsli
     ShaderLib/Atom/Features/Shadow/NormalOffsetShadows.azsli
     ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli

+ 5 - 5
Gems/Atom/Feature/Common/Code/Source/Shadows/FullscreenShadowPass.cpp

@@ -28,7 +28,7 @@ namespace AZ
         }
 
         FullscreenShadowPass::FullscreenShadowPass(const RPI::PassDescriptor& descriptor)
-            : RPI::FullscreenTrianglePass(descriptor)
+            : Base(descriptor)
             , m_outputName("Output")
             , m_depthInputName("Depth")
         {
@@ -37,12 +37,12 @@ namespace AZ
         void FullscreenShadowPass::CompileResources(const RHI::FrameGraphCompileContext& context)
         {
             SetConstantData();
-            FullscreenTrianglePass::CompileResources(context);
+            Base::CompileResources(context);
         }
 
-        AZ::RHI::Size FullscreenShadowPass::GetDepthBufferDimensions()
+        RHI::Size FullscreenShadowPass::GetDepthBufferDimensions()
         {
-            AZ::RPI::PassAttachmentBinding* outputBinding = RPI::Pass::FindAttachmentBinding(m_outputName);
+            RPI::PassAttachmentBinding* outputBinding = RPI::Pass::FindAttachmentBinding(m_outputName);
             auto outputDim = outputBinding->GetAttachment()->m_descriptor.m_image.m_size;
             AZ_Assert(outputDim.m_width > 0 && outputDim.m_height > 0, "Height and width are not valid\n");
             return outputDim;
@@ -50,7 +50,7 @@ namespace AZ
 
         int FullscreenShadowPass::GetDepthBufferMSAACount()
         {
-            AZ::RPI::PassAttachmentBinding* outputBinding = RPI::Pass::FindAttachmentBinding(m_outputName);
+            RPI::PassAttachmentBinding* outputBinding = RPI::Pass::FindAttachmentBinding(m_outputName);
             return outputBinding->GetAttachment()->m_descriptor.m_image.m_multisampleState.m_samples;
         }       
 

+ 3 - 1
Gems/Atom/Feature/Common/Code/Source/Shadows/FullscreenShadowPass.h

@@ -27,7 +27,9 @@ namespace AZ
         class FullscreenShadowPass final
             : public RPI::FullscreenTrianglePass
         {
-            AZ_RPI_PASS(FullscreenShadow);
+            AZ_RPI_PASS(FullscreenShadowPass);
+
+            using Base = RPI::FullscreenTrianglePass;
 
         public:
             AZ_RTTI(AZ::Render::FullscreenShadowPass, "{A7D3076A-DD01-4B79-AF34-4BB72DAD35E2}", RPI::FullscreenTrianglePass);