MotionBlur.glsl 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Shaders/Common.glsl>
  7. // Perform motion blur.
  8. ANKI_RP Vec3 motionBlur(texture2D motionVectorsRt, sampler motionVectorsRtSampler, ANKI_RP texture2D toBlurRt,
  9. Vec2 toBlurRtSize, sampler toBlurRtSampler, Vec2 uv, U32 maxSamples)
  10. {
  11. // Compute velocity. Get the max velocity around the curent sample to avoid outlines. TAA's result and the motion
  12. // vectors RT do not quite overlap
  13. Vec2 velocityMin = textureLod(motionVectorsRt, motionVectorsRtSampler, uv, 0.0).rg;
  14. Vec2 velocityMax = velocityMin;
  15. Vec2 v = textureLodOffset(sampler2D(motionVectorsRt, motionVectorsRtSampler), uv, 0.0, ivec2(-2, -2)).rg;
  16. velocityMin = min(velocityMin, v);
  17. velocityMax = max(velocityMax, v);
  18. v = textureLodOffset(sampler2D(motionVectorsRt, motionVectorsRtSampler), uv, 0.0, ivec2(2, 2)).rg;
  19. velocityMin = min(velocityMin, v);
  20. velocityMax = max(velocityMax, v);
  21. v = textureLodOffset(sampler2D(motionVectorsRt, motionVectorsRtSampler), uv, 0.0, ivec2(-2, 2)).rg;
  22. velocityMin = min(velocityMin, v);
  23. velocityMax = max(velocityMax, v);
  24. v = textureLodOffset(sampler2D(motionVectorsRt, motionVectorsRtSampler), uv, 0.0, ivec2(2, -2)).rg;
  25. velocityMin = min(velocityMin, v);
  26. velocityMax = max(velocityMax, v);
  27. const F32 mag0 = length(velocityMin);
  28. const F32 mag1 = length(velocityMax);
  29. const Vec2 velocity = (mag0 > mag1) ? velocityMin : velocityMax;
  30. // Compute the sample count
  31. const Vec2 slopes = abs(velocity);
  32. const Vec2 sampleCount2D = slopes * toBlurRtSize;
  33. F32 sampleCountf = max(sampleCount2D.x, sampleCount2D.y);
  34. sampleCountf = clamp(sampleCountf, 1.0, F32(maxSamples));
  35. sampleCountf = round(sampleCountf);
  36. // Sample
  37. const ANKI_RP F32 weight = 1.0 / sampleCountf;
  38. ANKI_RP Vec3 outColor = textureLod(toBlurRt, toBlurRtSampler, uv, 0.0).rgb * weight;
  39. ANKI_LOOP for(F32 s = 1.0; s < sampleCountf; s += 1.0)
  40. {
  41. const F32 f = s / sampleCountf;
  42. const Vec2 sampleUv = uv + velocity * f;
  43. outColor += textureLod(toBlurRt, toBlurRtSampler, sampleUv, 0.0).rgb * weight;
  44. }
  45. return outColor;
  46. }