IndirectDiffuse.ankiprog 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 technique RtMaterialFetch rgen
  6. #include <AnKi/Shaders/RtMaterialFetch.hlsl>
  7. #include <AnKi/Shaders/Include/GpuSceneTypes.h>
  8. #include <AnKi/Shaders/PackFunctions.hlsl>
  9. #include <AnKi/Shaders/ImportanceSampling.hlsl>
  10. #include <AnKi/Shaders/Functions.hlsl>
  11. #include <AnKi/Shaders/LightFunctions.hlsl>
  12. // Config and consts
  13. constexpr Bool kTryShadowmapFirst = true;
  14. constexpr F32 kTMax = 1000.0;
  15. // Functions
  16. Vec3 getDiffuseIndirect(StructuredBuffer<GpuSceneGlobalIlluminationProbe> giProbes, Vec3 worldPos, Vec3 worldNormal,
  17. SamplerState linearAnyClampSampler)
  18. {
  19. const U32 probeCount = getStructuredBufferElementCount(giProbes);
  20. U32 i;
  21. for(i = 0; i < probeCount; ++i)
  22. {
  23. if(any(worldPos >= giProbes[i].m_aabbMax) || any(worldPos <= giProbes[i].m_aabbMin))
  24. {
  25. continue;
  26. }
  27. else
  28. {
  29. break;
  30. }
  31. }
  32. const Bool probeFound = (i != probeCount);
  33. if(probeFound)
  34. {
  35. const GpuSceneGlobalIlluminationProbe probe = giProbes[i];
  36. return sampleGlobalIllumination<F32>(worldPos, worldNormal, probe, getBindlessTexture3DVec4(probe.m_volumeTexture), linearAnyClampSampler);
  37. }
  38. else
  39. {
  40. return 0.0;
  41. }
  42. }
  43. Vec3 lightShading(Vec3 rayOrigin, Vec3 rayDir, Vec3 hitPos, Vec3 hitNormal, Vec3 emission, Vec3 diffuse, Bool isSky)
  44. {
  45. Vec3 color = 0;
  46. if(isSky)
  47. {
  48. color = sampleSkyCheap<F32>(g_globalRendererConstants.m_sky, rayDir, g_linearAnyClampSampler);
  49. }
  50. else
  51. {
  52. const DirectionalLight dirLight = g_globalRendererConstants.m_directionalLight;
  53. // Trace shadow
  54. Vec4 vv4 = mul(g_globalRendererConstants.m_matrices.m_viewProjection, Vec4(hitPos, 1.0));
  55. vv4.xy /= vv4.w;
  56. const Bool bInsideFrustum = all(vv4.xy > -1.0) && all(vv4.xy < 1.0) && vv4.w > 0.0;
  57. F32 shadow;
  58. if(bInsideFrustum && kTryShadowmapFirst)
  59. {
  60. const F32 negativeZViewSpace = -mul(g_globalRendererConstants.m_matrices.m_view, Vec4(hitPos, 1.0)).z;
  61. const U32 shadowCascadeCount = dirLight.m_shadowCascadeCount;
  62. const U32 cascadeIdx = computeShadowCascadeIndex(negativeZViewSpace, dirLight.m_shadowCascadeDistances, shadowCascadeCount);
  63. shadow = computeShadowFactorDirLight<F32>(dirLight, cascadeIdx, hitPos, g_shadowAtlasTex, g_shadowSampler);
  64. }
  65. else
  66. {
  67. constexpr U32 qFlags = RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH;
  68. RayQuery<qFlags> q;
  69. const U32 flags = RAY_FLAG_FORCE_OPAQUE;
  70. const U32 cullMask = 0xFFu;
  71. RayDesc ray;
  72. ray.Origin = hitPos;
  73. ray.TMin = 0.01;
  74. ray.Direction = -dirLight.m_direction;
  75. ray.TMax = kTMax;
  76. q.TraceRayInline(g_tlas, qFlags, cullMask, ray);
  77. q.Proceed();
  78. shadow = (q.CommittedStatus() == COMMITTED_TRIANGLE_HIT) ? 0.0 : 1.0;
  79. }
  80. // Do simple light shading
  81. color = emission;
  82. const Vec3 indirectDiffuse = getDiffuseIndirect(g_giProbes, hitPos, hitNormal, g_linearAnyClampSampler);
  83. // color += diffuse * indirectDiffuse;
  84. const Vec3 l = -dirLight.m_direction;
  85. const F32 lambert = max(0.0, dot(l, hitNormal));
  86. const Vec3 diffC = diffuseLobe(diffuse);
  87. color += diffC * dirLight.m_diffuseColor * lambert * shadow;
  88. }
  89. return color;
  90. }
  91. [Shader("raygeneration")] void main()
  92. {
  93. Vec2 outSize;
  94. g_colorAndPdfTex.GetDimensions(outSize.x, outSize.y);
  95. const UVec2 coord = DispatchRaysIndex().xy;
  96. const Vec2 uv = Vec2(coord) / outSize;
  97. const F32 depth = g_depthTex[coord].x;
  98. const Vec4 rt2 = g_gbufferRt2[coord];
  99. const Vec3 worldNormal = unpackNormalFromGBuffer(rt2);
  100. const Vec4 v4 = mul(g_globalRendererConstants.m_matrices.m_invertedViewProjectionJitter, Vec4(uvToNdc(uv), depth, 1.0));
  101. const Vec3 worldPos = v4.xyz / v4.w;
  102. // Rand
  103. const UVec3 seed = rand3DPCG16(UVec3(coord, g_globalRendererConstants.m_frame % 8u));
  104. const Vec2 randFactors = hammersleyRandom16(g_globalRendererConstants.m_frame % 64u, 64u, seed);
  105. Vec3 rayOrigin = worldPos;
  106. Vec3 normal = worldNormal;
  107. Vec3 outColor = 0.0;
  108. Vec3 diffuse = 1.0;
  109. [unroll] for(U32 bounce = 0; bounce < 3; ++bounce)
  110. {
  111. const Mat3 tbn = rotationFromDirection(normal);
  112. const Vec3 rayDir = normalize(mul(tbn, hemisphereSampleCos(randFactors)));
  113. RtMaterialFetchRayPayload payload;
  114. payload.m_textureLod = 100.0;
  115. const U32 flags = RAY_FLAG_FORCE_OPAQUE;
  116. const U32 sbtRecordOffset = 0u;
  117. const U32 sbtRecordStride = 0u;
  118. const U32 missIndex = 0u;
  119. const U32 cullMask = 0xFFu;
  120. RayDesc ray;
  121. ray.Origin = rayOrigin;
  122. ray.TMin = 0.01;
  123. ray.Direction = rayDir;
  124. ray.TMax = kTMax;
  125. TraceRay(g_tlas, flags, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, ray, payload);
  126. F32 rayT = payload.m_rayT;
  127. const Bool hasHitSky = rayT < 0.0;
  128. if(hasHitSky)
  129. {
  130. rayT = kTMax;
  131. }
  132. const Vec3 hitPos = rayOrigin + rayDir * rayT;
  133. outColor += diffuse * lightShading(worldPos, rayDir, hitPos, payload.m_worldNormal, payload.m_emission, payload.m_diffuseColor, hasHitSky);
  134. if(hasHitSky)
  135. {
  136. break;
  137. }
  138. rayOrigin = hitPos;
  139. normal = payload.m_worldNormal;
  140. diffuse = payload.m_diffuseColor;
  141. }
  142. g_colorAndPdfTex[coord] = Vec4(outColor, 0.0);
  143. // g_colorAndPdfTex[coord] = Vec4(lerp(outColor, g_colorAndPdfTex[coord].xyz, 0.98), 0.0);
  144. }