RtShadows.ankiprog 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 RAYS_PER_PIXEL 1 2 4 8
  6. #pragma anki technique RtShadows rgen miss
  7. #include <AnKi/Shaders/ImportanceSampling.hlsl>
  8. #include <AnKi/Shaders/PackFunctions.hlsl>
  9. #include <AnKi/Shaders/RtShadows.hlsl>
  10. #include <AnKi/Shaders/MaterialShadersCommon.hlsl>
  11. #include <AnKi/Shaders/ClusteredShadingFunctions.hlsl>
  12. #if ANKI_RAY_GEN_SHADER
  13. # define SPACE space2
  14. ConstantBuffer<GlobalRendererConstants> g_globalRendererConstants : register(b0, SPACE);
  15. SamplerState g_trilinearRepeatSampler : register(s0, SPACE);
  16. RWTexture2D<Vec4> g_shadowsImage : register(u0, SPACE);
  17. Texture2D<Vec4> g_historyShadowsTex : register(t0, SPACE);
  18. SamplerState g_linearAnyClampSampler : register(s1, SPACE);
  19. Texture2D<Vec4> g_depthRt : register(t1, SPACE);
  20. Texture2D<Vec4> g_motionVectorsRt : register(t2, SPACE);
  21. Texture2D<Vec4> g_historyLengthTex : register(t3, SPACE);
  22. Texture2D<Vec4> g_normalRt : register(t4, SPACE);
  23. RaytracingAccelerationStructure g_tlas : register(t5, SPACE);
  24. Texture2D<Vec4> g_prevMomentsTex : register(t6, SPACE);
  25. RWTexture2D<Vec4> g_momentsImage : register(u1, SPACE);
  26. Texture2D<Vec4> g_blueNoiseTex : register(t7, SPACE);
  27. F32 trace(const Vec3 rayOrigin, const Vec3 rayDir, F32 tMax)
  28. {
  29. const U32 flags = RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER;
  30. const U32 cullMask = 0xFFu;
  31. const U32 sbtRecordOffset = 0u;
  32. const U32 sbtRecordStride = 0u;
  33. const U32 missIndex = 0u;
  34. RayDesc ray;
  35. ray.Origin = rayOrigin;
  36. ray.TMin = 0.1;
  37. ray.Direction = rayDir;
  38. ray.TMax = tMax;
  39. RtShadowsRayPayload payload;
  40. payload.m_shadowFactor = 0.0;
  41. TraceRay(g_tlas, flags, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, ray, payload);
  42. return payload.m_shadowFactor;
  43. }
  44. Vec3 genRandomDirection(U32 rayIdx, Vec2 uv)
  45. {
  46. const U32 frameIdx = g_globalRendererConstants.m_frame * RAYS_PER_PIXEL + rayIdx;
  47. Vec2 noiseTexSize;
  48. g_blueNoiseTex.GetDimensions(noiseTexSize.x, noiseTexSize.y);
  49. Vec3 random = g_blueNoiseTex.SampleLevel(g_trilinearRepeatSampler, Vec2(DispatchRaysDimensions().xy) / noiseTexSize * uv, 0.0).rgb;
  50. random = animateBlueNoise(random, frameIdx);
  51. random = random * 2.0 - 1.0; // In [-1.0, 1.0]
  52. return random;
  53. }
  54. [shader("raygeneration")] void main()
  55. {
  56. // World position
  57. const Vec2 uv = (Vec2(DispatchRaysIndex().xy) + 0.5) / Vec2(DispatchRaysDimensions().xy);
  58. const Vec2 ndc = uvToNdc(uv);
  59. const F32 depth = g_depthRt.SampleLevel(g_linearAnyClampSampler, uv, 0.0).r;
  60. const Vec4 worldPos4 = mul(g_globalRendererConstants.m_matrices.m_invertedViewProjectionJitter, Vec4(ndc, depth, 1.0));
  61. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  62. if(depth == 1.0)
  63. {
  64. g_shadowsImage[DispatchRaysIndex().xy] = 0.0f;
  65. g_momentsImage[DispatchRaysIndex().xy] = 0.0f;
  66. return;
  67. }
  68. // World normal
  69. const Vec3 normal = unpackNormalFromGBuffer(g_normalRt.SampleLevel(g_linearAnyClampSampler, uv, 0.0));
  70. // Dir light
  71. F32 shadowFactor = 0.0f;
  72. const DirectionalLight dirLight = g_globalRendererConstants.m_directionalLight;
  73. for(U32 i = 0; i < RAYS_PER_PIXEL; ++i)
  74. {
  75. const Vec3 dirLightPos = worldPos + -dirLight.m_direction * 10.0 + genRandomDirection(i, uv);
  76. const Vec3 rayDir = normalize(dirLightPos - worldPos);
  77. const F32 lambertTerm = dot(rayDir, normal);
  78. [branch] if(lambertTerm > 0.0)
  79. {
  80. shadowFactor += trace(worldPos, rayDir, 10000.0) / F32(RAYS_PER_PIXEL);
  81. }
  82. }
  83. // Get history length
  84. const Vec2 historyUv = uv + g_motionVectorsRt.SampleLevel(g_linearAnyClampSampler, uv, 0.0).xy;
  85. const F32 historyLength = g_historyLengthTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).x * kRtShadowsMaxHistoryLength;
  86. // Compute blend fractor
  87. const F32 lowestBlendFactor = 0.1;
  88. const F32 stableFrames = 4.0;
  89. const F32 historyGoodnessFactor = min(1.0, (historyLength - 1.0) / stableFrames);
  90. const F32 historyBlendFactor = lerp(1.0, lowestBlendFactor, historyGoodnessFactor);
  91. // Blend with history
  92. const F32 history = g_historyShadowsTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0).r;
  93. shadowFactor = lerp(history, shadowFactor, historyBlendFactor);
  94. // Store the shadows image
  95. g_shadowsImage[DispatchRaysIndex().xy] = shadowFactor;
  96. // Compute the moments that will give temporal variance
  97. Vec2 moments;
  98. moments.x = shadowFactor;
  99. moments.y = moments.x * moments.x;
  100. // Blend the moments
  101. const Vec2 prevMoments = g_prevMomentsTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0).xy;
  102. const F32 lowestMomentsBlendFactor = 0.2;
  103. const F32 momentsBlendFactor = lerp(1.0, lowestMomentsBlendFactor, historyGoodnessFactor);
  104. moments = lerp(prevMoments, moments, momentsBlendFactor);
  105. // Store the moments
  106. g_momentsImage[DispatchRaysIndex().xy] = Vec4(moments, 0.0, 0.0);
  107. }
  108. #endif // ANKI_RAY_GEN_SHADER
  109. #if ANKI_MISS_SHADER
  110. [shader("miss")] void main(inout RtShadowsRayPayload payload)
  111. {
  112. payload.m_shadowFactor = 1.0;
  113. }
  114. #endif // ANKI_MISS_SHADER