ExponentialShadowmappingResolve.ankiprog 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. ANKI_SPECIALIZATION_CONSTANT_UVEC2(INPUT_TEXTURE_SIZE, 0u);
  6. #pragma anki start comp
  7. #include <AnKi/Shaders/GaussianBlurCommon.glsl>
  8. #include <AnKi/Shaders/LightFunctions.glsl>
  9. #include <AnKi/Shaders/Include/ShadowMappingTypes.h>
  10. layout(local_size_x = 8, local_size_y = 8) in;
  11. const F32 OFFSET = 1.25;
  12. layout(set = 0, binding = 0, std430) readonly buffer b_unis
  13. {
  14. ShadowMappingUniforms u_uniforms[];
  15. };
  16. layout(set = 0, binding = 1) uniform sampler u_linearAnyClampSampler;
  17. layout(set = 0, binding = 2) uniform texture2D u_inputTex;
  18. layout(set = 0, binding = 3) uniform writeonly image2D u_outImg;
  19. Vec4 computeMoments(Vec2 uv)
  20. {
  21. const F32 d = textureLod(u_inputTex, u_linearAnyClampSampler, uv, 0.0).r;
  22. const Vec2 posAndNeg = evsmProcessDepth(d);
  23. return Vec4(posAndNeg.x, posAndNeg.x * posAndNeg.x, posAndNeg.y, posAndNeg.y * posAndNeg.y);
  24. }
  25. void main()
  26. {
  27. const ShadowMappingUniforms uni = u_uniforms[gl_GlobalInvocationID.z];
  28. // Compute the read UV
  29. Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / uni.m_viewportZW;
  30. uv = uv * uni.m_uvScale + uni.m_uvTranslation;
  31. // Compute the UV limits. We can't sample beyond those
  32. const Vec2 TEXEL_SIZE = 1.0 / Vec2(INPUT_TEXTURE_SIZE);
  33. const Vec2 HALF_TEXEL_SIZE = TEXEL_SIZE / 2.0;
  34. const Vec2 maxUv = uni.m_uvMax - HALF_TEXEL_SIZE;
  35. const Vec2 minUv = uni.m_uvMin + HALF_TEXEL_SIZE;
  36. // Sample
  37. const Vec2 UV_OFFSET = OFFSET * TEXEL_SIZE;
  38. const F32 w0 = BOX_WEIGHTS[0u];
  39. const F32 w1 = BOX_WEIGHTS[1u];
  40. const F32 w2 = BOX_WEIGHTS[2u];
  41. Vec4 moments;
  42. if(uni.m_blur != 0u)
  43. {
  44. moments = computeMoments(uv) * w0;
  45. moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
  46. moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
  47. moments += computeMoments(clamp(uv + Vec2(0.0, UV_OFFSET.y), minUv, maxUv)) * w1;
  48. moments += computeMoments(clamp(uv + Vec2(0.0, -UV_OFFSET.y), minUv, maxUv)) * w1;
  49. moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
  50. moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
  51. moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
  52. moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
  53. }
  54. else
  55. {
  56. moments = computeMoments(uv);
  57. }
  58. // Write the results
  59. #if ANKI_EVSM4
  60. const Vec4 outColor = moments;
  61. #else
  62. const Vec4 outColor = Vec4(moments.xy, 0.0, 0.0);
  63. #endif
  64. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy) + uni.m_viewportXY, outColor);
  65. }
  66. #pragma anki end