|
|
@ -26,7 +26,7 @@ namespace FidelityFX.FrameGen |
|
|
private readonly FrameInterpolationResources _resources = new FrameInterpolationResources(); |
|
|
private readonly FrameInterpolationResources _resources = new FrameInterpolationResources(); |
|
|
|
|
|
|
|
|
private readonly ConstantsBuffer<FrameInterpolation.Constants> _frameInterpolationConstants = new ConstantsBuffer<FrameInterpolation.Constants>(); |
|
|
private readonly ConstantsBuffer<FrameInterpolation.Constants> _frameInterpolationConstants = new ConstantsBuffer<FrameInterpolation.Constants>(); |
|
|
private readonly ConstantsBuffer<FrameInterpolation.InpaintingPyramidConstants> _spdConstants = new ConstantsBuffer<FrameInterpolation.InpaintingPyramidConstants>(); |
|
|
|
|
|
|
|
|
private readonly ConstantsBuffer<FfxSpd.SpdConstants> _spdConstants = new ConstantsBuffer<FfxSpd.SpdConstants>(); |
|
|
|
|
|
|
|
|
private readonly CustomSampler _sampler = CustomSampler.Create("Frame Interpolation"); |
|
|
private readonly CustomSampler _sampler = CustomSampler.Create("Frame Interpolation"); |
|
|
private readonly CustomSampler _prepareSampler = CustomSampler.Create("Frame Interpolation - Prepare"); |
|
|
private readonly CustomSampler _prepareSampler = CustomSampler.Create("Frame Interpolation - Prepare"); |
|
|
@ -172,7 +172,11 @@ namespace FidelityFX.FrameGen |
|
|
float aspectRatio = dispatchDescription.renderSize.x / (float)dispatchDescription.renderSize.y; |
|
|
float aspectRatio = dispatchDescription.renderSize.x / (float)dispatchDescription.renderSize.y; |
|
|
float cameraAngleHorizontal = Mathf.Atan(Mathf.Tan(dispatchDescription.cameraFovAngleVertical / 2) * aspectRatio) * 2; |
|
|
float cameraAngleHorizontal = Mathf.Atan(Mathf.Tan(dispatchDescription.cameraFovAngleVertical / 2) * aspectRatio) * 2; |
|
|
constants.tanHalfFOV = Mathf.Tan(cameraAngleHorizontal * 0.5f); |
|
|
constants.tanHalfFOV = Mathf.Tan(cameraAngleHorizontal * 0.5f); |
|
|
constants.deviceToViewDepth = SetupDeviceDepthToViewSpaceDepthParams(dispatchDescription); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool inverted = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) != 0; |
|
|
|
|
|
bool infinite = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInfinite) != 0; |
|
|
|
|
|
constants.deviceToViewDepth = FfxUtils.SetupDeviceDepthToViewSpaceDepthParams( |
|
|
|
|
|
dispatchDescription.renderSize, dispatchDescription.cameraNear, dispatchDescription.cameraFar, dispatchDescription.cameraFovAngleVertical, inverted, infinite); |
|
|
|
|
|
|
|
|
_frameInterpolationConstants.UpdateBufferData(commandBuffer); |
|
|
_frameInterpolationConstants.UpdateBufferData(commandBuffer); |
|
|
|
|
|
|
|
|
@ -196,7 +200,6 @@ namespace FidelityFX.FrameGen |
|
|
if (executePreparationPasses) |
|
|
if (executePreparationPasses) |
|
|
{ |
|
|
{ |
|
|
// Clear estimated depth resources
|
|
|
// Clear estimated depth resources
|
|
|
bool inverted = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) == FrameInterpolation.InitializationFlags.EnableDepthInverted; |
|
|
|
|
|
commandBuffer.SetRenderTarget(_resources.ReconstructedDepthInterpolatedFrame); |
|
|
commandBuffer.SetRenderTarget(_resources.ReconstructedDepthInterpolatedFrame); |
|
|
commandBuffer.ClearRenderTarget(false, true, inverted ? Color.clear : Color.white); |
|
|
commandBuffer.ClearRenderTarget(false, true, inverted ? Color.clear : Color.white); |
|
|
|
|
|
|
|
|
@ -236,66 +239,11 @@ namespace FidelityFX.FrameGen |
|
|
_gameVectorFieldInpaintingPyramidPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); |
|
|
_gameVectorFieldInpaintingPyramidPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private Vector4 SetupDeviceDepthToViewSpaceDepthParams(FrameInterpolation.DispatchDescription dispatchParams) |
|
|
|
|
|
{ |
|
|
|
|
|
bool inverted = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) != 0; |
|
|
|
|
|
bool infinite = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInfinite) != 0; |
|
|
|
|
|
|
|
|
|
|
|
// make sure it has no impact if near and far plane values are swapped in dispatch params
|
|
|
|
|
|
// the flags "inverted" and "infinite" will decide what transform to use
|
|
|
|
|
|
float min = Mathf.Min(dispatchParams.cameraNear, dispatchParams.cameraFar); |
|
|
|
|
|
float max = Mathf.Max(dispatchParams.cameraNear, dispatchParams.cameraFar); |
|
|
|
|
|
|
|
|
|
|
|
if (inverted) |
|
|
|
|
|
{ |
|
|
|
|
|
(min, max) = (max, min); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float q = max / (min - max); |
|
|
|
|
|
float d = -1.0f; |
|
|
|
|
|
|
|
|
|
|
|
Vector4 matrixElemC = new Vector4(q, -1.0f - Mathf.Epsilon, q, 0.0f + Mathf.Epsilon); |
|
|
|
|
|
Vector4 matrixElemE = new Vector4(q * min, -min - Mathf.Epsilon, q * min, max); |
|
|
|
|
|
|
|
|
|
|
|
// Revert x and y coords
|
|
|
|
|
|
float aspect = (float)dispatchParams.renderSize.x / dispatchParams.renderSize.y; |
|
|
|
|
|
float cotHalfFovY = Mathf.Cos(0.5f * dispatchParams.cameraFovAngleVertical) / Mathf.Sin(0.5f * dispatchParams.cameraFovAngleVertical); |
|
|
|
|
|
|
|
|
|
|
|
int matrixIndex = (inverted ? 2 : 0) + (infinite ? 1 : 0); |
|
|
|
|
|
return new Vector4( |
|
|
|
|
|
d * matrixElemC[matrixIndex], |
|
|
|
|
|
matrixElemE[matrixIndex], |
|
|
|
|
|
aspect / cotHalfFovY, |
|
|
|
|
|
1.0f / cotHalfFovY); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void SetupSpdConstants(Vector2Int resolution, out Vector2Int dispatchThreadGroupCount) |
|
|
private void SetupSpdConstants(Vector2Int resolution, out Vector2Int dispatchThreadGroupCount) |
|
|
{ |
|
|
{ |
|
|
RectInt rectInfo = new RectInt(0, 0, resolution.x, resolution.y); |
|
|
|
|
|
SpdSetup(rectInfo, out dispatchThreadGroupCount, out var workGroupOffset, out var numWorkGroupsAndMips); |
|
|
|
|
|
|
|
|
|
|
|
ref FrameInterpolation.InpaintingPyramidConstants spdConstants = ref _spdConstants.Value; |
|
|
|
|
|
spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; |
|
|
|
|
|
spdConstants.mips = (uint)Math.Min(numWorkGroupsAndMips.y, 7); |
|
|
|
|
|
spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; |
|
|
|
|
|
spdConstants.workGroupOffsetY = (uint)workGroupOffset.y; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void SpdSetup(RectInt rectInfo, out Vector2Int dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, int mips = -1) |
|
|
|
|
|
{ |
|
|
|
|
|
workGroupOffset = new Vector2Int(rectInfo.x / 64, rectInfo.y / 64); |
|
|
|
|
|
|
|
|
|
|
|
int endIndexX = (rectInfo.x + rectInfo.width - 1) / 64; |
|
|
|
|
|
int endIndexY = (rectInfo.y + rectInfo.height - 1) / 64; |
|
|
|
|
|
|
|
|
|
|
|
dispatchThreadGroupCount = new Vector2Int(endIndexX + 1 - workGroupOffset.x, endIndexY + 1 - workGroupOffset.y); |
|
|
|
|
|
|
|
|
|
|
|
numWorkGroupsAndMips = new Vector2Int(dispatchThreadGroupCount.x * dispatchThreadGroupCount.y, mips); |
|
|
|
|
|
if (mips < 0) |
|
|
|
|
|
{ |
|
|
|
|
|
float resolution = Math.Max(rectInfo.width, rectInfo.height); |
|
|
|
|
|
numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ref var spdConstants = ref _spdConstants.Value; |
|
|
|
|
|
FfxSpd.SetupSpdConstants(resolution, ref spdConstants, out dispatchThreadGroupCount); |
|
|
|
|
|
spdConstants.mips = Math.Min(spdConstants.mips, 7); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private int _debugIndex = 0; |
|
|
private int _debugIndex = 0; |
|
|
|