BloomUpscale.ankiprog 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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(FB_SIZE, 0u);
  6. ANKI_SPECIALIZATION_CONSTANT_UVEC2(INPUT_TEX_SIZE, 2u);
  7. const UVec2 WORKGROUP_SIZE = UVec2(16u, 16u);
  8. #pragma anki start comp
  9. #include <AnKi/Shaders/Common.glsl>
  10. layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
  11. layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
  12. layout(set = 0, binding = 1) uniform texture2D u_tex;
  13. layout(set = 0, binding = 2) uniform texture2D u_lensDirtTex;
  14. layout(set = 0, binding = 3) writeonly uniform image2D out_img;
  15. // Constants
  16. const U32 MAX_GHOSTS = 4u;
  17. const F32 GHOST_DISPERSAL = 0.7;
  18. const F32 HALO_WIDTH = 0.4;
  19. const F32 CHROMATIC_DISTORTION = 3.0;
  20. #define ENABLE_CHROMATIC_DISTORTION 1
  21. #define ENABLE_HALO 1
  22. const F32 HALO_OPACITY = 0.5;
  23. Vec3 textureDistorted(texture2D tex, sampler sampl, Vec2 uv,
  24. Vec2 direction, // direction of DISTORTION
  25. Vec3 DISTORTION) // per-channel DISTORTION factor
  26. {
  27. #if ENABLE_CHROMATIC_DISTORTION
  28. return Vec3(textureLod(tex, sampl, uv + direction * DISTORTION.r, 0.0).r,
  29. textureLod(tex, sampl, uv + direction * DISTORTION.g, 0.0).g,
  30. textureLod(tex, sampl, uv + direction * DISTORTION.b, 0.0).b);
  31. #else
  32. return textureLod(tex, uv, 0.0).rgb;
  33. #endif
  34. }
  35. Vec3 ssLensFlare(Vec2 uv)
  36. {
  37. const Vec2 TEXEL_SIZE = 1.0 / Vec2(INPUT_TEX_SIZE);
  38. const Vec3 DISTORTION = Vec3(-TEXEL_SIZE.x * CHROMATIC_DISTORTION, 0.0, TEXEL_SIZE.x * CHROMATIC_DISTORTION);
  39. const F32 LEN_OF_HALF = length(Vec2(0.5));
  40. const Vec2 flipUv = Vec2(1.0) - uv;
  41. const Vec2 ghostVec = (Vec2(0.5) - flipUv) * GHOST_DISPERSAL;
  42. const Vec2 direction = normalize(ghostVec);
  43. Vec3 result = Vec3(0.0);
  44. // sample ghosts:
  45. ANKI_UNROLL for(U32 i = 0u; i < MAX_GHOSTS; ++i)
  46. {
  47. const Vec2 offset = fract(flipUv + ghostVec * F32(i));
  48. F32 weight = length(Vec2(0.5) - offset) / LEN_OF_HALF;
  49. weight = pow(1.0 - weight, 10.0);
  50. result += textureDistorted(u_tex, u_linearAnyClampSampler, offset, direction, DISTORTION) * weight;
  51. }
  52. // Sample halo
  53. #if ENABLE_HALO
  54. const Vec2 haloVec = normalize(ghostVec) * HALO_WIDTH;
  55. F32 weight = length(Vec2(0.5) - fract(flipUv + haloVec)) / LEN_OF_HALF;
  56. weight = pow(1.0 - weight, 20.0);
  57. result += textureDistorted(u_tex, u_linearAnyClampSampler, flipUv + haloVec, direction, DISTORTION)
  58. * (weight * HALO_OPACITY);
  59. #endif
  60. // Lens dirt
  61. result *= textureLod(u_lensDirtTex, u_linearAnyClampSampler, uv, 0.0).rgb;
  62. return result;
  63. }
  64. Vec3 upscale(Vec2 uv)
  65. {
  66. Vec3 result = textureLod(u_tex, u_linearAnyClampSampler, uv, 0.0).rgb;
  67. result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, +1)).rgb;
  68. result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, -1)).rgb;
  69. result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, -1)).rgb;
  70. result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, +1)).rgb;
  71. result *= (1.0 / 5.0);
  72. return result;
  73. }
  74. void main()
  75. {
  76. if((FB_SIZE.x % WORKGROUP_SIZE.x) != 0u || (FB_SIZE.y % WORKGROUP_SIZE.y) != 0u) // This check is free
  77. {
  78. if(gl_GlobalInvocationID.x >= FB_SIZE.x || gl_GlobalInvocationID.y >= FB_SIZE.y)
  79. {
  80. return;
  81. }
  82. }
  83. const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(FB_SIZE);
  84. const Vec3 outColor = ssLensFlare(uv) + upscale(uv);
  85. imageStore(out_img, IVec2(gl_GlobalInvocationID.xy), Vec4(outColor, 0.0));
  86. }
  87. #pragma anki end