DeferredLighting.azsl 6.0 KB

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