LightShading.ankiprog 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // Copyright (C) 2009-2021, 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 USE_SHADOW_LAYERS 0 1
  6. ANKI_SPECIALIZATION_CONSTANT_UVEC2(TILE_COUNTS, 0u);
  7. ANKI_SPECIALIZATION_CONSTANT_U32(Z_SPLIT_COUNT, 2u);
  8. ANKI_SPECIALIZATION_CONSTANT_U32(TILE_SIZE, 3u);
  9. ANKI_SPECIALIZATION_CONSTANT_U32(IR_MIPMAP_COUNT, 4u);
  10. #pragma anki start vert
  11. #include <AnKi/Shaders/QuadVert.glsl>
  12. #pragma anki end
  13. #pragma anki start frag
  14. #include <AnKi/Shaders/Pack.glsl>
  15. #include <AnKi/Shaders/Functions.glsl>
  16. #include <AnKi/Shaders/RtShadows.glsl>
  17. #define CLUSTERED_SHADING_SET 0
  18. #define CLUSTERED_SHADING_UNIFORMS_BINDING 0
  19. #define CLUSTERED_SHADING_LIGHTS_BINDING 1
  20. #define CLUSTERED_SHADING_REFLECTIONS_BINDING 4
  21. #define CLUSTERED_SHADING_GI_BINDING 7
  22. #define CLUSTERED_SHADING_CLUSTERS_BINDING 9
  23. #include <AnKi/Shaders/ClusteredShadingCommon.glsl>
  24. layout(set = 0, binding = 10) uniform sampler u_nearestAnyClampSampler;
  25. layout(set = 0, binding = 11) uniform sampler u_trilinearClampSampler;
  26. layout(set = 0, binding = 12) uniform texture2D u_msRt0;
  27. layout(set = 0, binding = 13) uniform texture2D u_msRt1;
  28. layout(set = 0, binding = 14) uniform texture2D u_msRt2;
  29. layout(set = 0, binding = 15) uniform texture2D u_msDepthRt;
  30. layout(set = 0, binding = 16) uniform texture2D u_ssrRt;
  31. layout(set = 0, binding = 17) uniform texture2D u_ssaoRt;
  32. layout(set = 0, binding = 18) uniform texture2D u_ssgiRt;
  33. #if USE_SHADOW_LAYERS
  34. layout(set = 0, binding = 19) uniform utexture2D u_shadowLayersTex;
  35. #else
  36. layout(set = 0, binding = 20) uniform texture2D u_resolvedSm;
  37. #endif
  38. layout(location = 0) in Vec2 in_uv;
  39. layout(location = 0) out Vec3 out_color;
  40. // Common code for lighting
  41. #define LIGHTING_COMMON_BRDF() \
  42. const Vec3 frag2Light = light.m_position - worldPos; \
  43. const Vec3 l = normalize(frag2Light); \
  44. const Vec3 specC = computeSpecularColorBrdf(gbuffer, viewDir, l); \
  45. const Vec3 diffC = diffuseLambert(gbuffer.m_diffuse); \
  46. const F32 att = computeAttenuationFactor(light.m_squareRadiusOverOne, frag2Light); \
  47. F32 lambert = max(0.0, dot(gbuffer.m_normal, l));
  48. void main()
  49. {
  50. const F32 depth = textureLod(u_msDepthRt, u_nearestAnyClampSampler, in_uv, 0.0).r;
  51. const Vec2 ndc = UV_TO_NDC(in_uv);
  52. if(depth == 1.0)
  53. {
  54. out_color = Vec3(0.0);
  55. return;
  56. }
  57. // Get world position
  58. const Vec4 worldPos4 = u_clusteredShading.m_matrices.m_invertedViewProjectionJitter * Vec4(ndc, depth, 1.0);
  59. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  60. // Get the cluster
  61. Cluster cluster = getClusterFragCoord(Vec3(gl_FragCoord.xy, depth), TILE_SIZE, TILE_COUNTS, Z_SPLIT_COUNT,
  62. u_clusteredShading.m_zSplitMagic.x, u_clusteredShading.m_zSplitMagic.y);
  63. // out_color = clusterHeatmap(cluster, 1u << CLUSTER_OBJECT_TYPE_POINT_LIGHT); return;
  64. // Decode GBuffer
  65. GbufferInfo gbuffer;
  66. readGBuffer(u_msRt0, u_msRt1, u_msRt2, u_nearestAnyClampSampler, in_uv, 0.0, gbuffer);
  67. gbuffer.m_subsurface = max(gbuffer.m_subsurface, SUBSURFACE_MIN);
  68. // SM
  69. #if USE_SHADOW_LAYERS
  70. F32 resolvedSm[MAX_RT_SHADOW_LAYERS];
  71. unpackRtShadows(textureLod(u_shadowLayersTex, u_nearestAnyClampSampler, in_uv, 0.0), resolvedSm);
  72. #else
  73. Vec4 resolvedSm = textureLod(u_resolvedSm, u_trilinearClampSampler, in_uv, 0.0);
  74. U32 resolvedSmIdx = 0u;
  75. #endif
  76. // SSAO
  77. const F32 ssao = textureLod(u_ssaoRt, u_trilinearClampSampler, in_uv, 0.0).r;
  78. gbuffer.m_diffuse *= ssao;
  79. // Ambient and emissive color
  80. out_color = gbuffer.m_diffuse * gbuffer.m_emission;
  81. // Dir light
  82. const Vec3 viewDir = normalize(u_clusteredShading.m_cameraPosition - worldPos);
  83. const DirectionalLight dirLight = u_clusteredShading.m_directionalLight;
  84. if(dirLight.m_active != 0u)
  85. {
  86. F32 shadowFactor;
  87. if(dirLight.m_cascadeCount > 0u)
  88. {
  89. #if USE_SHADOW_LAYERS
  90. shadowFactor = resolvedSm[dirLight.m_shadowLayer];
  91. #else
  92. shadowFactor = resolvedSm[0];
  93. ++resolvedSmIdx;
  94. #endif
  95. }
  96. else
  97. {
  98. shadowFactor = 1.0;
  99. }
  100. const Vec3 l = -dirLight.m_direction;
  101. const F32 lambert = max(gbuffer.m_subsurface, dot(l, gbuffer.m_normal));
  102. const Vec3 diffC = diffuseLambert(gbuffer.m_diffuse);
  103. const Vec3 specC = computeSpecularColorBrdf(gbuffer, viewDir, l);
  104. out_color += (diffC + specC) * dirLight.m_diffuseColor * (shadowFactor * lambert);
  105. }
  106. // Point lights
  107. ANKI_LOOP while(cluster.m_pointLightsMask != 0ul)
  108. {
  109. const I32 idx = findLSB64(cluster.m_pointLightsMask);
  110. cluster.m_pointLightsMask &= ~(1ul << U64(idx));
  111. const PointLight light = u_pointLights2[idx];
  112. LIGHTING_COMMON_BRDF();
  113. ANKI_BRANCH if(light.m_shadowAtlasTileScale >= 0.0)
  114. {
  115. #if USE_SHADOW_LAYERS
  116. const F32 shadow = resolvedSm[light.m_shadowLayer];
  117. #else
  118. const F32 shadow = resolvedSm[resolvedSmIdx++];
  119. #endif
  120. lambert *= shadow;
  121. }
  122. out_color += (diffC + specC) * light.m_diffuseColor * (att * max(gbuffer.m_subsurface, lambert));
  123. }
  124. // Spot lights
  125. ANKI_LOOP while(cluster.m_spotLightsMask != 0ul)
  126. {
  127. const I32 idx = findLSB64(cluster.m_spotLightsMask);
  128. cluster.m_spotLightsMask &= ~(1ul << U64(idx));
  129. const SpotLight light = u_spotLights2[idx];
  130. LIGHTING_COMMON_BRDF();
  131. const F32 spot = computeSpotFactor(l, light.m_outerCos, light.m_innerCos, light.m_direction);
  132. ANKI_BRANCH if(light.m_shadowLayer != MAX_U32)
  133. {
  134. #if USE_SHADOW_LAYERS
  135. const F32 shadow = resolvedSm[light.m_shadowLayer];
  136. #else
  137. const F32 shadow = resolvedSm[resolvedSmIdx++];
  138. #endif
  139. lambert *= shadow;
  140. }
  141. out_color += (diffC + specC) * light.m_diffuseColor * (att * spot * max(gbuffer.m_subsurface, lambert));
  142. }
  143. // Indirect specular
  144. {
  145. // Do the probe read
  146. Vec3 specIndirect = Vec3(0.0);
  147. const Vec3 reflDir = reflect(-viewDir, gbuffer.m_normal);
  148. const F32 reflLod = F32(IR_MIPMAP_COUNT - 1u) * gbuffer.m_roughness;
  149. if(bitCount(cluster.m_reflectionProbesMask) == 1)
  150. {
  151. // Only one probe, do a fast path without blend weight
  152. const ReflectionProbe probe = u_reflectionProbes2[findLSB(cluster.m_reflectionProbesMask)];
  153. // Sample
  154. const Vec3 cubeUv = intersectProbe(worldPos, reflDir, probe.m_aabbMin, probe.m_aabbMax, probe.m_position);
  155. const Vec4 cubeArrUv = Vec4(cubeUv, probe.m_cubemapIndex);
  156. specIndirect = textureLod(u_reflectionsTex2, u_trilinearClampSampler, cubeArrUv, reflLod).rgb;
  157. }
  158. else
  159. {
  160. // Zero or more than one probes, do a slow path that blends them together
  161. F32 totalBlendWeight = EPSILON;
  162. // Loop probes
  163. ANKI_LOOP while(cluster.m_reflectionProbesMask != 0u)
  164. {
  165. const U32 idx = U32(findLSB(cluster.m_reflectionProbesMask));
  166. cluster.m_reflectionProbesMask &= ~(1u << idx);
  167. const ReflectionProbe probe = u_reflectionProbes2[idx];
  168. // Compute blend weight
  169. const F32 blendWeight = computeProbeBlendWeight(worldPos, probe.m_aabbMin, probe.m_aabbMax, 0.2);
  170. totalBlendWeight += blendWeight;
  171. // Sample reflections
  172. const Vec3 cubeUv =
  173. intersectProbe(worldPos, reflDir, probe.m_aabbMin, probe.m_aabbMax, probe.m_position);
  174. const Vec4 cubeArrUv = Vec4(cubeUv, probe.m_cubemapIndex);
  175. const Vec3 c = textureLod(u_reflectionsTex2, u_trilinearClampSampler, cubeArrUv, reflLod).rgb;
  176. specIndirect += c * blendWeight;
  177. }
  178. // Normalize the colors
  179. specIndirect /= totalBlendWeight;
  180. }
  181. // Read the SSL result
  182. const Vec4 ssr = textureLod(u_ssrRt, u_trilinearClampSampler, in_uv, 0.0);
  183. // Combine the SSR and probe reflections and write the result
  184. const Vec3 finalSpecIndirect = specIndirect * ssr.a + ssr.rgb;
  185. // Compute env BRDF
  186. const F32 NoV = max(EPSILON, dot(gbuffer.m_normal, viewDir));
  187. const Vec3 env =
  188. envBRDF(gbuffer.m_specular, gbuffer.m_roughness, u_integrationLut2, u_trilinearClampSampler, NoV);
  189. out_color += finalSpecIndirect * env;
  190. }
  191. // Indirect diffuse
  192. {
  193. Vec3 diffIndirect;
  194. if(bitCount(cluster.m_giProbesMask) == 1)
  195. {
  196. // All subgroups point to the same probe and there is only one probe, do a fast path without blend weight
  197. const GlobalIlluminationProbe probe = u_giProbes[findLSB(cluster.m_giProbesMask)];
  198. // Sample
  199. diffIndirect = sampleGlobalIllumination(worldPos, gbuffer.m_normal, probe, u_globalIlluminationTextures,
  200. u_trilinearClampSampler);
  201. }
  202. else
  203. {
  204. // Zero or more than one probes, do a slow path that blends them together
  205. F32 totalBlendWeight = EPSILON;
  206. diffIndirect = Vec3(0.0);
  207. // Loop probes
  208. ANKI_LOOP while(cluster.m_giProbesMask != 0u)
  209. {
  210. const U32 idx = U32(findLSB(cluster.m_giProbesMask));
  211. cluster.m_giProbesMask &= ~(1u << idx);
  212. const GlobalIlluminationProbe probe = u_giProbes[idx];
  213. // Compute blend weight
  214. const F32 blendWeight =
  215. computeProbeBlendWeight(worldPos, probe.m_aabbMin, probe.m_aabbMax, probe.m_fadeDistance);
  216. totalBlendWeight += blendWeight;
  217. // Sample
  218. const Vec3 c = sampleGlobalIllumination(worldPos, gbuffer.m_normal, probe, u_globalIlluminationTextures,
  219. u_trilinearClampSampler);
  220. diffIndirect += c * blendWeight;
  221. }
  222. // Normalize
  223. diffIndirect /= totalBlendWeight;
  224. }
  225. const Vec3 ssgi = textureLod(u_ssgiRt, u_trilinearClampSampler, in_uv, 0.0).rgb;
  226. diffIndirect += ssgi;
  227. out_color += diffIndirect * gbuffer.m_diffuse;
  228. }
  229. }
  230. #pragma anki end