LightShading.ankiprog 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma anki mutator INDIRECT_DIFFUSE_TEX 0 1
  6. #pragma anki technique vert pixel
  7. #include <AnKi/Shaders/QuadVert.hlsl>
  8. #if ANKI_PIXEL_SHADER
  9. # include <AnKi/Shaders/PackFunctions.hlsl>
  10. # include <AnKi/Shaders/Functions.hlsl>
  11. # include <AnKi/Shaders/RtShadows.hlsl>
  12. # include <AnKi/Shaders/ClusteredShadingFunctions.hlsl>
  13. ConstantBuffer<GlobalRendererConstants> g_globalConstants : register(b0);
  14. StructuredBuffer<PointLight> g_pointLights : register(t0);
  15. StructuredBuffer<SpotLight> g_spotLights : register(t1);
  16. # if INDIRECT_DIFFUSE_TEX
  17. Texture2D<Vec4> g_indirectDiffuseTex : register(t2);
  18. # else
  19. StructuredBuffer<GlobalIlluminationProbe> g_giProbes : register(t2);
  20. # endif
  21. StructuredBuffer<Cluster> g_clusters : register(t4);
  22. SamplerState g_nearestAnyClampSampler : register(s0);
  23. SamplerState g_trilinearClampSampler : register(s1);
  24. Texture2D<Vec4> g_gbuffer0Tex : register(t5);
  25. Texture2D<Vec4> g_gbuffer1Tex : register(t6);
  26. Texture2D<Vec4> g_gbuffer2Tex : register(t7);
  27. Texture2D g_depthTex : register(t8);
  28. Texture2D<Vec4> g_resolvedShadowsTex : register(t9);
  29. Texture2D<Vec4> g_ssaoTex : register(t10);
  30. Texture2D<Vec4> g_reflectionsTex : register(t11);
  31. Texture2D<Vec4> g_integrationLut : register(t12);
  32. // Common code for lighting
  33. # define LIGHTING_COMMON_BRDF() \
  34. const Vec3 frag2Light = light.m_position - worldPos; \
  35. const HVec3 l = normalize(frag2Light); \
  36. const HVec3 specC = specularIsotropicLobe(gbuffer.m_normal, gbuffer.m_f0, gbuffer.m_roughness, viewDir, l); \
  37. const HVec3 diffC = diffuseLobe(gbuffer.m_diffuse); \
  38. const F16 att = computeAttenuationFactor<F16>(light.m_radius, frag2Light); \
  39. F16 lambert = max(F16(0.0), dot(gbuffer.m_normal, l));
  40. Vec4 main(VertOut input) : SV_TARGET0
  41. {
  42. const Vec2 uv = input.m_uv;
  43. const Vec2 ndc = uvToNdc(uv);
  44. const UVec2 coord = input.m_svPosition;
  45. const F32 depth = g_depthTex[coord].r;
  46. if(depth == 1.0)
  47. {
  48. return 0.0;
  49. }
  50. // Get world position
  51. const Vec4 worldPos4 = mul(g_globalConstants.m_matrices.m_invertedViewProjectionJitter, Vec4(ndc, depth, 1.0));
  52. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  53. const HVec3 viewDir = normalize(g_globalConstants.m_cameraPosition - worldPos);
  54. // Get the cluster
  55. Cluster cluster = getClusterFragCoord(g_clusters, g_globalConstants, Vec3(input.m_svPosition.xy, depth));
  56. // return clusterHeatmap(cluster, 1u << (U32)GpuSceneNonRenderableObjectType::kLight, 3);
  57. // Decode GBuffer
  58. GbufferInfo<F16> gbuffer = (GbufferInfo<F16>)0;
  59. unpackGBufferNoVelocity<F16>(g_gbuffer0Tex[coord], g_gbuffer1Tex[coord], g_gbuffer2Tex[coord], gbuffer);
  60. gbuffer.m_subsurface = max(gbuffer.m_subsurface, kSubsurfaceMin);
  61. // Apply SSAO
  62. const HVec4 ssaoAndBentNormals = g_ssaoTex.SampleLevel(g_trilinearClampSampler, uv, 0.0);
  63. const F16 ssao = ssaoAndBentNormals.w;
  64. const HVec3 bentNormal = ssaoAndBentNormals.xyz;
  65. gbuffer.m_diffuse *= ssao;
  66. // Ambient and emissive color
  67. HVec3 outColor = gbuffer.m_emission;
  68. // Indirect diffuse
  69. # if INDIRECT_DIFFUSE_TEX
  70. const HVec3 indirectCol = g_indirectDiffuseTex[coord];
  71. outColor += indirectCol * gbuffer.m_diffuse / kPi;
  72. # else
  73. const HVec3 probeColor = sampleGiProbes<F16>(cluster, g_giProbes, bentNormal, worldPos, g_trilinearClampSampler);
  74. outColor += probeColor * gbuffer.m_diffuse;
  75. # endif
  76. // Indirect specular
  77. {
  78. HVec3 refl = g_reflectionsTex[coord].xyz;
  79. // Apply the reflection
  80. const F16 NoV = max(0.0, dot(gbuffer.m_normal, viewDir));
  81. const Vec3 env = specularDFG<F16>(gbuffer.m_f0, gbuffer.m_roughness, g_integrationLut, g_trilinearClampSampler, NoV);
  82. refl *= env;
  83. outColor += refl;
  84. }
  85. // SM
  86. HVec4 resolvedSm = g_resolvedShadowsTex.SampleLevel(g_nearestAnyClampSampler, uv, 0.0);
  87. U32 resolvedSmIdx = 0u;
  88. // Dir light
  89. const DirectionalLight dirLight = g_globalConstants.m_directionalLight;
  90. if(dirLight.m_active)
  91. {
  92. F16 shadowFactor;
  93. if(dirLight.m_shadowCascadeCount)
  94. {
  95. shadowFactor = resolvedSm[0];
  96. ++resolvedSmIdx;
  97. }
  98. else
  99. {
  100. shadowFactor = 1.0;
  101. }
  102. const HVec3 l = -dirLight.m_direction;
  103. const F16 lambert = max(gbuffer.m_subsurface, dot(l, gbuffer.m_normal));
  104. const HVec3 diffC = diffuseLobe(gbuffer.m_diffuse);
  105. const HVec3 specC = specularIsotropicLobe(gbuffer.m_normal, gbuffer.m_f0, gbuffer.m_roughness, viewDir, l);
  106. outColor += (diffC + specC) * dirLight.m_diffuseColor * (shadowFactor * lambert);
  107. }
  108. // Point lights
  109. U32 idx;
  110. [loop] while((idx = iteratePointLights(cluster)) != kMaxU32)
  111. {
  112. const PointLight light = g_pointLights[idx];
  113. LIGHTING_COMMON_BRDF();
  114. [branch] if(light.m_shadow)
  115. {
  116. const F16 shadow = resolvedSm[resolvedSmIdx++];
  117. lambert *= shadow;
  118. }
  119. outColor += (diffC + specC) * light.m_diffuseColor * (att * max(gbuffer.m_subsurface, lambert));
  120. }
  121. // Spot lights
  122. [loop] while((idx = iterateSpotLights(cluster)) != kMaxU32)
  123. {
  124. const SpotLight light = g_spotLights[idx];
  125. LIGHTING_COMMON_BRDF();
  126. const F16 spot = computeSpotFactor<F16>(l, light.m_outerCos, light.m_innerCos, light.m_direction);
  127. [branch] if(light.m_shadow)
  128. {
  129. const F16 shadow = resolvedSm[resolvedSmIdx++];
  130. lambert *= shadow;
  131. }
  132. outColor += (diffC + specC) * light.m_diffuseColor * (att * spot * max(gbuffer.m_subsurface, lambert));
  133. }
  134. if(any(isnan(outColor)) || any(isinf(outColor)))
  135. {
  136. outColor = 0.0;
  137. }
  138. return Vec4(outColor, 0.0);
  139. }
  140. #endif // ANKI_PIXEL_SHADER