DeferredLighting.azsl 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <viewsrg.srgi>
  9. #include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
  10. #include <Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli>
  11. // The shader variant system needs a fallback if you have non-static options.
  12. #include <Atom/RPI/ShaderResourceGroups/UnusedFallbackDrawSrg.azsli>
  13. ShaderResourceGroup PassSrg : SRG_PerPass
  14. {
  15. Texture2DArray<float> m_directionalLightShadowmap;
  16. Texture2DArray<float> m_directionalLightExponentialShadowmap;
  17. Texture2DArray<float> m_projectedShadowmaps;
  18. Texture2DArray<float> m_projectedExponentialShadowmap;
  19. Texture2D m_brdfMap;
  20. Texture2D<float> m_fullscreenShadow;
  21. Sampler LinearSampler
  22. {
  23. MinFilter = Linear;
  24. MagFilter = Linear;
  25. MipFilter = Linear;
  26. AddressU = Clamp;
  27. AddressV = Clamp;
  28. AddressW = Clamp;
  29. };
  30. Sampler PointSampler
  31. {
  32. MinFilter = Point;
  33. MagFilter = Point;
  34. MipFilter = Point;
  35. AddressU = Clamp;
  36. AddressV = Clamp;
  37. AddressW = Clamp;
  38. };
  39. Texture2D<uint4> m_tileLightData;
  40. StructuredBuffer<uint> m_lightListRemapped;
  41. Texture2DMS<float2> m_depthStencilTexture;
  42. Texture2DMS<float4> m_baseColor;
  43. Texture2DMS<float4> m_roughnessMetal;
  44. Texture2DMS<float4> m_normal;
  45. }
  46. #define FORCE_OPAQUE 1 // Because there is no transparency in deferred, so we don't want the o_opacity_mode shader option
  47. //TODO(DeferredPOC): Support multiple lighting models, not just StandardLighting
  48. #include <Atom/Features/PBR/Lighting/StandardLighting.azsli>
  49. #include <Atom/Features/PBR/Lights/Ibl.azsli>
  50. #include <Atom/Features/PBR/Decals.azsli>
  51. // Copied from ForwardPassOutput
  52. struct PSOutput
  53. {
  54. float4 m_diffuseColor : SV_Target0; //!< RGB = Diffuse Lighting, A = Blend Alpha (for blended surfaces) OR A = special encoding of surfaceScatteringFactor, m_subsurfaceScatteringQuality, o_enableSubsurfaceScattering
  55. float4 m_specularColor : SV_Target1; //!< RGB = Specular Lighting, A = Unused
  56. float4 m_albedo : SV_Target2; //!< RGB = Surface albedo pre-multiplied by other factors that will be multiplied later by diffuse GI, A = specularOcclusion
  57. float4 m_specularF0 : SV_Target3; //!< RGB = Specular F0, A = roughness
  58. };
  59. // Since the visual results of the deferred pipeline are (in theory) identical to the results
  60. // of the main pipeline, this option can be enabled to draw a watermark that confirms what
  61. // you are seeing is actually the deferred pipeline.
  62. // TODO(DeferredPOC): Make a way to turn this on as needed for testing. Right now we don't have a way to turn it on programmatically.
  63. option bool o_deferredPipelineWatermark = false;
  64. PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
  65. {
  66. float3 views[MAX_SHADING_VIEWS];
  67. views[0] = ViewSrg::m_worldPosition.xyz; // Assume one view for forward pass for now
  68. uint2 screenCoords = IN.m_position.xy;
  69. // ------- Unpack G-Buffers -------
  70. float zDepth = PassSrg::m_depthStencilTexture.Load(screenCoords, sampleIndex).r;
  71. float3 surfacePosWS = WorldPositionFromDepthBufferMS(PassSrg::m_depthStencilTexture, zDepth, IN.m_position.xy).xyz;
  72. float3 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex).xyz;
  73. float3 normal = DecodeNormalSignedOctahedron(encodedNormal.xyz);
  74. float2 roughnessMetallic = PassSrg::m_roughnessMetal.Load(screenCoords, sampleIndex).rg;
  75. float3 baseColor = PassSrg::m_baseColor.Load(screenCoords, sampleIndex).rgb;
  76. if(o_deferredPipelineWatermark)
  77. {
  78. if(abs(IN.m_texCoord.x-0.5) < 0.01 || abs(IN.m_texCoord.y-0.5) < 0.01)
  79. {
  80. float t = sin(50 * (IN.m_texCoord.x + IN.m_texCoord.y)) * 0.5 + 0.5;
  81. baseColor *= lerp(float3(1,0.2,1), float3(0.5,1,1), t);
  82. }
  83. }
  84. // Copied from Gems\Atom\Feature\Common\Assets\Materials\Pipelines\MainPipeline\ForwardPass.azsli
  85. // ------- Surface -------
  86. Surface surface;
  87. surface.position = surfacePosWS;
  88. // TODO(DeferredPOC): We don't actually have the vertex normal, so just use the per-pixel normal for now
  89. surface.vertexNormal = normal;
  90. surface.normal = normal;
  91. surface.roughnessLinear = roughnessMetallic.x;
  92. float specularF0Factor = 0.5f; // TODO(DeferredPOC): Consider passing the actual specF0 through a GBuffer
  93. surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, roughnessMetallic.y);
  94. surface.clearCoat.InitializeToZero();
  95. surface.CalculateRoughnessA();
  96. // ------- LightingData -------
  97. LightingData lightingData;
  98. // Light iterator
  99. lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData);
  100. lightingData.Init(surface.position, surface.normal, surface.roughnessLinear, views);
  101. // Diffuse and Specular response
  102. lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.GetSpecularNdotV(), surface.GetSpecularF0(), surface.roughnessLinear);
  103. lightingData.diffuseResponse = 1.0f - lightingData.specularResponse;
  104. const float alpha = 1.0f;
  105. // ------- Lighting Calculation -------
  106. // Apply Decals
  107. ApplyDecals(lightingData.tileIterator, surface);
  108. // Apply Direct Lighting
  109. ApplyDirectLighting(surface, lightingData, IN.m_position);
  110. // Apply Image Based Lighting (IBL)
  111. // TODO(DeferredPOC): how can we support a localized reflection probe in deferred?
  112. ReflectionProbeData unusedReflectionProbe;
  113. TextureCube unusedReflectionProbeCubeMap;
  114. ApplyIBL(surface, lightingData, true, false, unusedReflectionProbe, unusedReflectionProbeCubeMap);
  115. // Finalize Lighting
  116. lightingData.FinalizeLighting();
  117. PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
  118. // ------- Output -------
  119. PSOutput OUT;
  120. OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
  121. OUT.m_diffuseColor.w = -1; // Subsurface scattering is disabled
  122. OUT.m_specularColor = lightingOutput.m_specularColor;
  123. OUT.m_specularF0 = lightingOutput.m_specularF0;
  124. OUT.m_albedo = lightingOutput.m_albedo;
  125. return OUT;
  126. }