ExponentialShadowmappingResolve.ankiprog 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright (C) 2009-2020, 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, 0, UVec2(1));
  6. #pragma anki start comp
  7. #include <shaders/GaussianBlurCommon.glsl>
  8. #include <shaders/LightFunctions.glsl>
  9. layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
  10. const F32 OFFSET = 1.25;
  11. struct Uniforms
  12. {
  13. UVec4 m_viewport;
  14. Vec2 m_uvScale;
  15. Vec2 m_uvTranslation;
  16. U32 m_blur;
  17. U32 m_padding0;
  18. U32 m_padding1;
  19. U32 m_padding2;
  20. };
  21. layout(push_constant, std430) uniform pc_
  22. {
  23. Uniforms u_uniforms;
  24. };
  25. layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
  26. layout(set = 0, binding = 1) uniform texture2D u_inputTex;
  27. layout(set = 0, binding = 2) uniform writeonly image2D u_outImg;
  28. Vec4 computeMoments(Vec2 uv)
  29. {
  30. const F32 d = textureLod(u_inputTex, u_linearAnyClampSampler, uv, 0.0).r;
  31. const Vec2 posAndNeg = evsmProcessDepth(d);
  32. return Vec4(posAndNeg.x, posAndNeg.x * posAndNeg.x, posAndNeg.y, posAndNeg.y * posAndNeg.y);
  33. }
  34. void main()
  35. {
  36. if(gl_GlobalInvocationID.x >= u_uniforms.m_viewport.z || gl_GlobalInvocationID.y >= u_uniforms.m_viewport.w)
  37. {
  38. // Skip if it's out of bounds
  39. return;
  40. }
  41. // Compute the read UV
  42. Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_uniforms.m_viewport.zw);
  43. uv = uv * u_uniforms.m_uvScale + u_uniforms.m_uvTranslation;
  44. // Compute the UV limits. We can't sample beyond those
  45. const Vec2 TEXEL_SIZE = 1.0 / Vec2(INPUT_TEXTURE_SIZE);
  46. const Vec2 HALF_TEXEL_SIZE = TEXEL_SIZE / 2.0;
  47. const Vec2 maxUv = (Vec2(1.0) * u_uniforms.m_uvScale + u_uniforms.m_uvTranslation) - HALF_TEXEL_SIZE;
  48. const Vec2 minUv = (Vec2(0.0) * u_uniforms.m_uvScale + u_uniforms.m_uvTranslation) + HALF_TEXEL_SIZE;
  49. // Sample
  50. const Vec2 UV_OFFSET = OFFSET * TEXEL_SIZE;
  51. const F32 w0 = BOX_WEIGHTS[0u];
  52. const F32 w1 = BOX_WEIGHTS[1u];
  53. const F32 w2 = BOX_WEIGHTS[2u];
  54. Vec4 moments;
  55. if(u_uniforms.m_blur != 0)
  56. {
  57. moments = computeMoments(uv) * w0;
  58. moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
  59. moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
  60. moments += computeMoments(clamp(uv + Vec2(0.0, UV_OFFSET.y), minUv, maxUv)) * w1;
  61. moments += computeMoments(clamp(uv + Vec2(0.0, -UV_OFFSET.y), minUv, maxUv)) * w1;
  62. moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
  63. moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
  64. moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
  65. moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
  66. }
  67. else
  68. {
  69. moments = computeMoments(uv);
  70. }
  71. // Write the results
  72. #if ANKI_EVSM4
  73. const Vec4 outColor = moments;
  74. #else
  75. const Vec4 outColor = Vec4(moments.xy, 0.0, 0.0);
  76. #endif
  77. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy) + IVec2(u_uniforms.m_viewport.xy), outColor);
  78. }
  79. #pragma anki end