From e9eb1f4e31913478ad50a8d36694ffd09b50b0f1 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Tue, 30 May 2023 12:24:28 +0200 Subject: [PATCH] Implemented upscaling using FSR2. Currently only works when outputting directly to camera target. --- .../Runtime/Effects/SuperResolution.cs | 22 +++++++---------- .../Runtime/PostProcessLayer.cs | 24 +++++++++++++++---- .../Runtime/PostProcessRenderContext.cs | 8 +++++++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/SuperResolution.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/SuperResolution.cs index 13599f7..4caaa96 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/SuperResolution.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/SuperResolution.cs @@ -114,12 +114,15 @@ namespace UnityEngine.Rendering.PostProcessing public void ConfigureCameraViewport(PostProcessRenderContext context) { - var cam = context.camera; - _displaySize = new Vector2Int(cam.pixelWidth, cam.pixelHeight); // TODO: also support render texture targets properly - _originalRect = cam.rect; + var camera = context.camera; + _originalRect = camera.rect; + + _displaySize = new Vector2Int(camera.pixelWidth, camera.pixelHeight); // TODO: also support render texture targets properly + Fsr2.GetRenderResolutionFromQualityMode(out int renderWidth, out int renderHeight, _displaySize.x, _displaySize.y, qualityMode); + _renderSize = new Vector2Int(renderWidth, renderHeight); - cam.aspect = (_displaySize.x * _originalRect.width) / (_displaySize.y * _originalRect.height); - cam.rect = new Rect(0, 0, _originalRect.width * _renderSize.x / cam.pixelWidth, _originalRect.height * _renderSize.y / cam.pixelHeight); + camera.aspect = (_displaySize.x * _originalRect.width) / (_displaySize.y * _originalRect.height); + camera.rect = new Rect(0, 0, _originalRect.width * _renderSize.x / camera.pixelWidth, _originalRect.height * _renderSize.y / camera.pixelHeight); } public void ResetCameraViewport(PostProcessRenderContext context) @@ -154,7 +157,6 @@ namespace UnityEngine.Rendering.PostProcessing } cmd.GetTemporaryRT(Fsr2ShaderIDs.UavUpscaledOutput, _displaySize.x, _displaySize.y, 0, default, context.sourceFormat, default, 1, true); - // _dispatchDescription.Output = _upscaledOutput; _fsrContext.Dispatch(_dispatchDescription, cmd); @@ -167,15 +169,8 @@ namespace UnityEngine.Rendering.PostProcessing private void CreateFsrContext(PostProcessRenderContext context) { - _displaySize = new Vector2Int(context.width, context.height); // TODO: get rid of this - _prevDisplaySize = _displaySize; - // TODO: re-enable actual resolution scaling - // Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, _displaySize.x, _displaySize.y, qualityMode); - // _renderSize = new Vector2Int(renderWidth, renderHeight); - _renderSize = _displaySize; - Fsr2.InitializationFlags flags = 0; if (context.camera.allowHDR) flags |= Fsr2.InitializationFlags.EnableHighDynamicRange; if (enableFP16) flags |= Fsr2.InitializationFlags.EnableFP16Usage; @@ -244,6 +239,7 @@ namespace UnityEngine.Rendering.PostProcessing _dispatchDescription.MotionVectorScale.x = -_renderSize.x; _dispatchDescription.MotionVectorScale.y = -_renderSize.y; _dispatchDescription.RenderSize = _renderSize; + _dispatchDescription.InputResourceSize = new Vector2Int(context.width, context.height); _dispatchDescription.FrameTimeDelta = Time.unscaledDeltaTime; _dispatchDescription.CameraNear = camera.nearClipPlane; _dispatchDescription.CameraFar = camera.farClipPlane; diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessLayer.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessLayer.cs index 2655935..7e1cc09 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessLayer.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessLayer.cs @@ -574,6 +574,13 @@ namespace UnityEngine.Rendering.PostProcessing m_LegacyCmdBuffer.Clear(); SetupContext(context); + + // Modify internal rendering resolution for both the camera and the pre-upscaling post-processing effects + if (context.IsSuperResolutionActive()) + { + superResolution.ConfigureCameraViewport(context); + context.SetRenderSize(superResolution.renderSize); + } context.command = m_LegacyCmdBufferOpaque; TextureLerper.instance.BeginFrame(context); @@ -620,6 +627,7 @@ namespace UnityEngine.Rendering.PostProcessing bool isFogActive = fog.IsEnabledAndSupported(context); bool hasCustomOpaqueOnlyEffects = HasOpaqueOnlyEffects(context); int opaqueOnlyEffects = 0; + // TODO: if FSR2 is active, add opaque-only copy step opaqueOnlyEffects += isScreenSpaceReflectionsActive ? 1 : 0; opaqueOnlyEffects += isFogActive ? 1 : 0; opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0; @@ -643,6 +651,8 @@ namespace UnityEngine.Rendering.PostProcessing cmd.BuiltinBlit(context.source, context.destination, RuntimeUtilities.copyStdMaterial, stopNaNPropagation ? 1 : 0); UpdateSrcDstForOpaqueOnly(ref srcTarget, ref dstTarget, context, cameraTarget, opaqueOnlyEffects); } + + // TODO: create opaque-only texture copy for FSR2 auto-reactive/TCR if (isScreenSpaceReflectionsActive) { @@ -720,6 +730,12 @@ namespace UnityEngine.Rendering.PostProcessing if (RuntimeUtilities.scriptableRenderPipelineActive) return; + // Set the camera back to its original parameters, so we can output at full display resolution + if (m_CurrentContext.IsSuperResolutionActive()) + { + superResolution.ResetCameraViewport(m_CurrentContext); + } + if (m_CurrentContext.IsTemporalAntialiasingActive() || m_CurrentContext.IsSuperResolutionActive()) { #if UNITY_2018_2_OR_NEWER @@ -862,6 +878,7 @@ namespace UnityEngine.Rendering.PostProcessing bundle.Value.ResetHistory(); temporalAntialiasing.ResetHistory(); + superResolution.ResetHistory(); } /// @@ -1098,10 +1115,11 @@ namespace UnityEngine.Rendering.PostProcessing } else if (context.IsSuperResolutionActive()) { - // TODO: perform camera projection jitter superResolution.ConfigureJitteredProjectionMatrix(context); - // TODO: setup source and destination render textures (temp RTs) + // Set the upscaler's output to full display resolution, as well as for all following post-processing effects + context.SetRenderSize(superResolution.displaySize); + var fsrTarget = m_TargetPool.Get(); var finalDestination = context.destination; context.GetScreenSpaceTemporaryRT(cmd, fsrTarget, 0, context.sourceFormat); @@ -1114,8 +1132,6 @@ namespace UnityEngine.Rendering.PostProcessing cmd.ReleaseTemporaryRT(lastTarget); lastTarget = fsrTarget; - - // TODO: this is probably where we perform the camera viewport trick as well } bool hasBeforeStackEffects = HasActiveEffects(PostProcessEvent.BeforeStack, context); diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessRenderContext.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessRenderContext.cs index 467abaa..fee5028 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessRenderContext.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessRenderContext.cs @@ -71,6 +71,14 @@ namespace UnityEngine.Rendering.PostProcessing } } + public void SetRenderSize(Vector2Int renderSize) + { + // TODO: I suppose we should support XR as well at some point + width = renderSize.x; + height = renderSize.y; + m_sourceDescriptor.width = width; + m_sourceDescriptor.height = height; + } /// /// The command buffer to fill render commands in.