GBufferPost.ankiprog 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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 comp
  6. #include <AnKi/Shaders/PackFunctions.hlsl>
  7. #include <AnKi/Shaders/Functions.hlsl>
  8. #include <AnKi/Shaders/ClusteredShadingFunctions.hlsl>
  9. #include <AnKi/Shaders/Include/MiscRendererTypes.h>
  10. RWTexture2D<Vec4> g_gbuffer0Tex : register(u0);
  11. RWTexture2D<Vec4> g_gbuffer1Tex : register(u1);
  12. RWTexture2D<Vec4> g_gbuffer2Tex : register(u2);
  13. Texture2D<Vec4> g_depthTex : register(t0);
  14. StructuredBuffer<Decal> g_decals : register(t1);
  15. StructuredBuffer<Cluster> g_clusters : register(t2);
  16. ConstantBuffer<GlobalRendererConstants> g_globalConstants : register(b0);
  17. SamplerState g_linearAnyClampSampler : register(s0);
  18. [numthreads(8, 8, 1)] void main(UVec2 svDispatchThreadId : SV_DISPATCHTHREADID)
  19. {
  20. UVec2 viewportSize;
  21. g_depthTex.GetDimensions(viewportSize.x, viewportSize.y);
  22. if(any(svDispatchThreadId >= viewportSize))
  23. {
  24. return;
  25. }
  26. // Get worldPos
  27. const F32 depth = g_depthTex[svDispatchThreadId].r;
  28. const Vec2 ndc = uvToNdc(Vec2(svDispatchThreadId) / Vec2(viewportSize));
  29. const Vec4 worldPos4 = mul(g_globalConstants.m_matrices.m_invertedViewProjectionJitter, Vec4(ndc, depth, 1.0));
  30. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  31. // Get the cluster. Make sure it's dynamically uniform because we are accessing bindless textures later on
  32. Cluster cluster = getClusterFragCoord<true>(g_clusters, g_globalConstants, Vec3(svDispatchThreadId, depth));
  33. // Make the decalsMask uniform across the wave because we are accessing bindless textures later on
  34. U32 decalsMask = cluster.m_decalsMask[0];
  35. for(U32 i = 1; i < kMaxVisibleDecals / 32; ++i)
  36. {
  37. decalsMask |= cluster.m_decalsMask[i];
  38. }
  39. if(decalsMask == 0)
  40. {
  41. return;
  42. }
  43. GbufferInfo<F16> gbuffer = (GbufferInfo<F16>)0;
  44. unpackGBufferNoVelocity<F16>(g_gbuffer0Tex[svDispatchThreadId], g_gbuffer1Tex[svDispatchThreadId], g_gbuffer2Tex[svDispatchThreadId], gbuffer);
  45. HVec3 diffuse = gbuffer.m_diffuse;
  46. F16 roughness = gbuffer.m_roughness;
  47. F16 metalness = gbuffer.m_metallic;
  48. U32 idx;
  49. [loop] while((idx = iterateDecals(cluster)) != kMaxU32)
  50. {
  51. const Decal decal = g_decals[idx];
  52. // Project pos to decal space
  53. const Vec4 texCoords4 = mul(decal.m_textureMatrix, Vec4(worldPos, 1.0));
  54. const F32 depth = texCoords4.z / texCoords4.w;
  55. const Vec2 uv = texCoords4.xy / texCoords4.w;
  56. if(any(Vec3(uv, depth) < 0.0) || any(Vec3(uv, depth) > 1.0))
  57. {
  58. // Outside the volume
  59. continue;
  60. }
  61. // Fade a bit when approaching depth 0 or 1
  62. const F16 edgeFactor = 1.0 - pow(abs(2.0 * depth - 1.0), 8.0);
  63. F16 factor = edgeFactor;
  64. // Do diffuse
  65. if(decal.m_diffuseTexture != kMaxU32)
  66. {
  67. const HVec4 col = getBindlessTexture2DVec4(decal.m_diffuseTexture).SampleLevel(g_linearAnyClampSampler, uv, 0.0);
  68. factor *= col.a;
  69. diffuse = lerp(diffuse, col.rgb, factor * decal.m_diffuseBlendFactor);
  70. }
  71. // Do metal roughness
  72. if(decal.m_roughnessMetalnessTexture != kMaxU32)
  73. {
  74. const HVec3 col = getBindlessTexture2DVec4(decal.m_roughnessMetalnessTexture).SampleLevel(g_linearAnyClampSampler, uv, 0.0).gba;
  75. if(decal.m_diffuseTexture == kMaxU32)
  76. {
  77. // Can't use the diffuse tex for alpha. Try the alpha from the roughness/metal texture
  78. factor *= col.z;
  79. }
  80. roughness = lerp(roughness, col.x, factor * decal.m_roughnessMetalnessFactor);
  81. metalness = lerp(metalness, col.y, factor * decal.m_roughnessMetalnessFactor);
  82. }
  83. }
  84. if(any(diffuse != gbuffer.m_diffuse) || roughness != gbuffer.m_roughness || metalness != gbuffer.m_metallic)
  85. {
  86. gbuffer.m_diffuse = diffuse;
  87. gbuffer.m_roughness = roughness;
  88. gbuffer.m_metallic = metalness;
  89. const GBufferPixelOut gbufferOut = packGBuffer(gbuffer);
  90. g_gbuffer0Tex[svDispatchThreadId] = gbufferOut.m_rt0;
  91. g_gbuffer1Tex[svDispatchThreadId] = gbufferOut.m_rt1;
  92. g_gbuffer2Tex[svDispatchThreadId] = gbufferOut.m_rt2;
  93. }
  94. }