TraditionalDeferredShading.ankiprog 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. // Classic deferred lighting shader
  6. #pragma anki mutator SPECULAR 0 1
  7. #pragma anki mutator INDIRECT_DIFFUSE 0 1 2
  8. #pragma anki technique vert pixel
  9. #include <AnKi/Shaders/QuadVert.hlsl>
  10. #if ANKI_PIXEL_SHADER
  11. # include <AnKi/Shaders/PackFunctions.hlsl>
  12. # include <AnKi/Shaders/LightFunctions.hlsl>
  13. # include <AnKi/Shaders/IndirectDiffuseClipmaps.hlsl>
  14. # include <AnKi/Shaders/Include/TraditionalDeferredShadingTypes.h>
  15. # include <AnKi/Shaders/Include/GpuSceneTypes.h>
  16. ConstantBuffer<TraditionalDeferredShadingConstants> g_consts : register(b0);
  17. StructuredBuffer<U32> g_visibleLightIds : register(t0);
  18. StructuredBuffer<GpuSceneLight> g_lights : register(t1);
  19. SamplerState g_gbufferSampler : register(s0);
  20. Texture2D<Vec4> g_gbufferTex0 : register(t2);
  21. Texture2D<Vec4> g_gbufferTex1 : register(t3);
  22. Texture2D<Vec4> g_gbufferTex2 : register(t4);
  23. Texture2D<Vec4> g_depthTex : register(t5);
  24. // For directional light:
  25. SamplerComparisonState g_shadowMapSampler : register(s1);
  26. Texture2D<Vec4> g_shadowMap : register(t6);
  27. # if INDIRECT_DIFFUSE
  28. StructuredBuffer<GpuSceneGlobalIlluminationProbe> g_giProbes : register(t7);
  29. SamplerState g_linearAnyClampSampler : register(s2);
  30. # endif
  31. ConstantBuffer<GlobalRendererConstants> g_globalRendererConsts : register(b1);
  32. # if INDIRECT_DIFFUSE
  33. Vec3 getDiffuseIndirect(Vec3 worldPos, Vec3 worldNormal)
  34. {
  35. # if INDIRECT_DIFFUSE == 1
  36. const U32 probeCount = getStructuredBufferElementCount(g_giProbes);
  37. U32 i;
  38. for(i = 0; i < probeCount; ++i)
  39. {
  40. if(all(worldPos < g_giProbes[i].m_aabbMax) && all(worldPos > g_giProbes[i].m_aabbMin))
  41. {
  42. break;
  43. }
  44. }
  45. const Bool probeFound = (i != probeCount);
  46. if(probeFound)
  47. {
  48. const GpuSceneGlobalIlluminationProbe probe = g_giProbes[i];
  49. return sampleGlobalIllumination<F32>(worldPos, worldNormal, probe, getBindlessTexture3DVec4(probe.m_volumeTexture), g_linearAnyClampSampler);
  50. }
  51. else
  52. {
  53. return 0.0;
  54. }
  55. # else
  56. constexpr SampleClipmapFlag flags =
  57. kSampleClipmapFlagBackfacingProbeRejection | kSampleClipmapFlagBiasSamplePointSurfaceNormal | kSampleClipmapFlagUsePreviousFrame;
  58. const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConsts.m_indirectDiffuseClipmaps;
  59. const Vec3 irradiance =
  60. sampleClipmapIrradiance(worldPos, worldNormal, g_globalRendererConsts.m_cameraPosition, idConsts, g_linearAnyClampSampler, flags);
  61. return irradiance;
  62. # endif
  63. }
  64. # endif
  65. Vec4 main(VertOut input) : SV_TARGET0
  66. {
  67. const Vec2 uv = input.m_uv;
  68. const F32 depth = g_depthTex.SampleLevel(g_gbufferSampler, uv, 0.0).r;
  69. if(depth == 1.0f)
  70. {
  71. discard;
  72. }
  73. // Decode and process gbuffer
  74. GbufferInfo<F32> gbuffer = (GbufferInfo<F32>)0;
  75. unpackGBufferNoVelocity(g_gbufferTex0.SampleLevel(g_gbufferSampler, uv, 0.0), g_gbufferTex1.SampleLevel(g_gbufferSampler, uv, 0.0),
  76. g_gbufferTex2.SampleLevel(g_gbufferSampler, uv, 0.0), gbuffer);
  77. gbuffer.m_subsurface = max(gbuffer.m_subsurface, kSubsurfaceMin * 8.0);
  78. const Vec4 worldPos4 = mul(g_consts.m_invViewProjMat, Vec4(uvToNdc(uv), depth, 1.0));
  79. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  80. // Compute diff
  81. const Vec3 diffC = diffuseLobe(gbuffer.m_diffuse);
  82. Vec3 outColor = gbuffer.m_emission;
  83. const Vec3 viewDir = normalize(g_consts.m_cameraPos - worldPos);
  84. ANKI_MAYBE_UNUSED(viewDir);
  85. # if INDIRECT_DIFFUSE
  86. outColor += getDiffuseIndirect(worldPos, gbuffer.m_normal) * gbuffer.m_diffuse;
  87. # endif
  88. // Dir light
  89. if(g_globalRendererConsts.m_directionalLight.m_active)
  90. {
  91. const F32 dist = length(g_consts.m_cameraPos - worldPos);
  92. F32 shadowFactor;
  93. if(dist < g_consts.m_dirLight.m_effectiveShadowDistance)
  94. {
  95. // Acceptable distance
  96. shadowFactor = computeShadowFactorDirLight<F32>(g_consts.m_dirLight.m_lightMatrix, worldPos, g_shadowMap, g_shadowMapSampler);
  97. }
  98. else
  99. {
  100. shadowFactor = 1.0;
  101. }
  102. const Vec3 l = -g_globalRendererConsts.m_directionalLight.m_direction;
  103. const F32 lambert = dot(l, gbuffer.m_normal);
  104. const F32 factor = shadowFactor * max(gbuffer.m_subsurface, lambert);
  105. # if SPECULAR == 1
  106. const Vec3 specC = specularIsotropicLobe(gbuffer.m_normal, gbuffer.m_f0, gbuffer.m_roughness, viewDir, l);
  107. # else
  108. const Vec3 specC = Vec3(0.0, 0.0, 0.0);
  109. # endif
  110. outColor += (specC + diffC) * g_globalRendererConsts.m_directionalLight.m_diffuseColor * factor;
  111. }
  112. // For all (other) lights
  113. const U32 lightCount = g_visibleLightIds[0];
  114. for(U32 i = 1; i <= lightCount; ++i)
  115. {
  116. const GpuSceneLight light = g_lights[g_visibleLightIds[i]];
  117. const Vec3 frag2Light = light.m_position - worldPos;
  118. const Vec3 l = normalize(frag2Light);
  119. const F32 nol = max(0.0, dot(gbuffer.m_normal, l));
  120. const F32 att = computeAttenuationFactor<F32>(light.m_radius, frag2Light);
  121. const F32 lambert = nol;
  122. const F32 spot = light.m_isSpotLight ? computeSpotFactor<F32>(l, light.m_outerCos, light.m_innerCos, light.m_direction) : 1.0f;
  123. const F32 factor = att * spot * max(lambert, gbuffer.m_subsurface);
  124. # if SPECULAR == 1
  125. const Vec3 specC = specularIsotropicLobe(gbuffer.m_normal, gbuffer.m_f0, gbuffer.m_roughness, viewDir, l);
  126. # else
  127. const Vec3 specC = Vec3(0.0, 0.0, 0.0);
  128. # endif
  129. outColor += (specC + diffC) * light.m_diffuseColor * factor;
  130. }
  131. return Vec4(outColor, 0.0);
  132. }
  133. #endif // ANKI_PIXEL_SHADER