| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <viewsrg.srgi>
- #include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
- ShaderResourceGroup PassSrg : SRG_PerPass
- {
- // D32_FLOAT_S8X24_UINT (Format:15) depthStencil texture
- Texture2D<float2> m_depthStencil;
- Sampler PointSampler
- {
- MinFilter = Point;
- MagFilter = Point;
- MipFilter = Point;
- AddressU = Clamp;
- AddressV = Clamp;
- AddressW = Clamp;
- };
- }
- struct PSOutput
- {
- float2 m_motion : SV_Target0;
- };
- PSOutput MainPS(VSOutput IN)
- {
- PSOutput OUT;
- float depth = PassSrg::m_depthStencil.Sample(PassSrg::PointSampler, IN.m_texCoord).r;
- // If depth is 0, that means depth is on the far plane. This should be treated as being infinitely far
- // away, not actually on the far plane, because the infinitely far background shouldn't move as a result
- // of camera translation. Tweaking the depth to -near/far distance makes that happen. Keep in mind near
- // and far are inverted, so this normally a very small value.
- if (depth == 0.0)
- {
- depth = -ViewSrg::GetFarZ() / ViewSrg::GetNearZ();
- }
- float2 clipPos = float2(mad(IN.m_texCoord.x, 2.0, -1.0), mad(IN.m_texCoord.y, -2.0, 1.0));
- float4 worldPos = mul(ViewSrg::m_viewProjectionInverseMatrix, float4(clipPos, depth, 1.0));
- float4 clipPosPrev = mul(ViewSrg::m_viewProjectionPrevMatrix, float4((worldPos / worldPos.w).xyz, 1.0));
- clipPosPrev = (clipPosPrev / clipPosPrev.w);
- // Clip space is from -1.0 to 1.0, so the motion vectors are 2x as big as they should be
- OUT.m_motion = (clipPos - clipPosPrev.xy) * 0.5;
- // Flip y to line up with uv coordinates
- OUT.m_motion.y = -OUT.m_motion.y;
- return OUT;
- }
|