CameraMotionVector.azsl 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <viewsrg.srgi>
  9. #include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
  10. ShaderResourceGroup PassSrg : SRG_PerPass
  11. {
  12. // D32_FLOAT_S8X24_UINT (Format:15) depthStencil texture
  13. Texture2D<float2> m_depthStencil;
  14. Sampler PointSampler
  15. {
  16. MinFilter = Point;
  17. MagFilter = Point;
  18. MipFilter = Point;
  19. AddressU = Clamp;
  20. AddressV = Clamp;
  21. AddressW = Clamp;
  22. };
  23. }
  24. struct PSOutput
  25. {
  26. float2 m_motion : SV_Target0;
  27. };
  28. PSOutput MainPS(VSOutput IN)
  29. {
  30. PSOutput OUT;
  31. float depth = PassSrg::m_depthStencil.Sample(PassSrg::PointSampler, IN.m_texCoord).r;
  32. // If depth is 0, that means depth is on the far plane. This should be treated as being infinitely far
  33. // away, not actually on the far plane, because the infinitely far background shouldn't move as a result
  34. // of camera translation. Tweaking the depth to -near/far distance makes that happen. Keep in mind near
  35. // and far are inverted, so this normally a very small value.
  36. if (depth == 0.0)
  37. {
  38. depth = -ViewSrg::GetFarZ() / ViewSrg::GetNearZ();
  39. }
  40. float2 clipPos = float2(mad(IN.m_texCoord.x, 2.0, -1.0), mad(IN.m_texCoord.y, -2.0, 1.0));
  41. float4 worldPos = mul(ViewSrg::m_viewProjectionInverseMatrix, float4(clipPos, depth, 1.0));
  42. float4 clipPosPrev = mul(ViewSrg::m_viewProjectionPrevMatrix, float4((worldPos / worldPos.w).xyz, 1.0));
  43. clipPosPrev = (clipPosPrev / clipPosPrev.w);
  44. // Clip space is from -1.0 to 1.0, so the motion vectors are 2x as big as they should be
  45. OUT.m_motion = (clipPos - clipPosPrev.xy) * 0.5;
  46. // Flip y to line up with uv coordinates
  47. OUT.m_motion.y = -OUT.m_motion.y;
  48. return OUT;
  49. }