From 5236c28e7e839a365198b3aff52022bdc429700b Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Thu, 8 Jun 2023 14:21:19 +0200 Subject: [PATCH] Added support for dynamic resolution scaling using ScalableBufferManager. --- Assets/Scenes/SampleScene.unity | 2 +- Assets/Scripts/Debug/DebugDumper.cs | 16 +++++++++++ Assets/Scripts/Fsr2ImageEffect.cs | 38 ++++++++++++++++++++------- ProjectSettings/ProjectSettings.asset | 2 +- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index f36be96..db058b9 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -284,7 +284,7 @@ Camera: m_TargetEye: 3 m_HDR: 1 m_AllowMSAA: 0 - m_AllowDynamicResolution: 0 + m_AllowDynamicResolution: 1 m_ForceIntoRT: 0 m_OcclusionCulling: 1 m_StereoConvergence: 10 diff --git a/Assets/Scripts/Debug/DebugDumper.cs b/Assets/Scripts/Debug/DebugDumper.cs index de78b26..f7c1594 100644 --- a/Assets/Scripts/Debug/DebugDumper.cs +++ b/Assets/Scripts/Debug/DebugDumper.cs @@ -30,6 +30,9 @@ using UnityEngine; public class DebugDumper : MonoBehaviour { private Fsr2ImageEffect _fsr; + + private float _scaleFactor = 1.0f; + private float _lastScaleTime = 0f; void Start() { @@ -42,6 +45,8 @@ public class DebugDumper : MonoBehaviour Debug.Log(sb); _fsr = GetComponent(); + + ScalableBufferManager.ResizeBuffers(_scaleFactor, _scaleFactor); } void Update() @@ -77,6 +82,16 @@ public class DebugDumper : MonoBehaviour { _fsr.ResetHistory(); } + + float vertical = Input.GetAxis("Vertical"); + if (vertical is < -0.3f or > 0.3f && Time.realtimeSinceStartup > _lastScaleTime + 0.5f) + { + _scaleFactor += 0.1f * Math.Sign(vertical); + _scaleFactor = Mathf.Clamp(_scaleFactor, 0.1f, 1.0f); + + ScalableBufferManager.ResizeBuffers(_scaleFactor, _scaleFactor); + _lastScaleTime = Time.realtimeSinceStartup; + } } private void OnGUI() @@ -93,6 +108,7 @@ public class DebugDumper : MonoBehaviour GUILayout.Label($"FSR2: {(_fsr.enabled ? "Enabled" : "Disabled")}"); GUILayout.Label($"Quality: {_fsr.qualityMode}"); GUILayout.Label($"Auto-exposure: {(_fsr.enableAutoExposure ? "Enabled" : "Disabled")}"); + GUILayout.Label($"Scale: {_scaleFactor:0.00}"); if (Input.GetButton("Jump")) { GUILayout.Label("Reset"); diff --git a/Assets/Scripts/Fsr2ImageEffect.cs b/Assets/Scripts/Fsr2ImageEffect.cs index 5be9810..f25e2f3 100644 --- a/Assets/Scripts/Fsr2ImageEffect.cs +++ b/Assets/Scripts/Fsr2ImageEffect.cs @@ -186,6 +186,7 @@ namespace FidelityFX if (_renderCamera.allowHDR) flags |= Fsr2.InitializationFlags.EnableHighDynamicRange; if (enableFP16) flags |= Fsr2.InitializationFlags.EnableFP16Usage; if (enableAutoExposure) flags |= Fsr2.InitializationFlags.EnableAutoExposure; + if (UsingDynamicResolution()) flags |= Fsr2.InitializationFlags.EnableDynamicResolution; _context = Fsr2.CreateContext(_displaySize, _renderSize, Callbacks, flags); @@ -292,7 +293,8 @@ namespace FidelityFX _opaqueInputCommandBuffer.Clear(); if (autoGenerateReactiveMask || autoGenerateTransparencyAndComposition) { - _colorOpaqueOnly = RenderTexture.GetTemporary(_renderSize.x, _renderSize.y, 0, GetDefaultFormat()); + var scaledRenderSize = GetScaledRenderSize(); + _colorOpaqueOnly = RenderTexture.GetTemporary(scaledRenderSize.x, scaledRenderSize.y, 0, GetDefaultFormat()); _opaqueInputCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, _colorOpaqueOnly); } @@ -320,14 +322,16 @@ namespace FidelityFX if (!enableAutoExposure && exposure != null) _dispatchDescription.Exposure = exposure; if (reactiveMask != null) _dispatchDescription.Reactive = reactiveMask; if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = transparencyAndCompositionMask; + + var scaledRenderSize = GetScaledRenderSize(); _dispatchDescription.Output = null; _dispatchDescription.PreExposure = preExposure; _dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.Sharpness = sharpness; - _dispatchDescription.MotionVectorScale.x = -_renderSize.x; - _dispatchDescription.MotionVectorScale.y = -_renderSize.y; - _dispatchDescription.RenderSize = _renderSize; + _dispatchDescription.MotionVectorScale.x = -scaledRenderSize.x; + _dispatchDescription.MotionVectorScale.y = -scaledRenderSize.y; + _dispatchDescription.RenderSize = scaledRenderSize; _dispatchDescription.FrameTimeDelta = Time.unscaledDeltaTime; _dispatchDescription.CameraNear = _renderCamera.nearClipPlane; _dispatchDescription.CameraFar = _renderCamera.farClipPlane; @@ -360,7 +364,7 @@ namespace FidelityFX _genReactiveDescription.ColorOpaqueOnly = _colorOpaqueOnly; _genReactiveDescription.ColorPreUpscale = null; _genReactiveDescription.OutReactive = null; - _genReactiveDescription.RenderSize = _renderSize; + _genReactiveDescription.RenderSize = GetScaledRenderSize(); _genReactiveDescription.Scale = generateReactiveParameters.scale; _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; _genReactiveDescription.BinaryValue = generateReactiveParameters.binaryValue; @@ -369,14 +373,16 @@ namespace FidelityFX private void ApplyJitter() { + var scaledRenderSize = GetScaledRenderSize(); + // Perform custom jittering of the camera's projection matrix according to FSR2's recipe - int jitterPhaseCount = Fsr2.GetJitterPhaseCount(_renderSize.x, _displaySize.x); + int jitterPhaseCount = Fsr2.GetJitterPhaseCount(scaledRenderSize.x, _displaySize.x); Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount); _dispatchDescription.JitterOffset = new Vector2(jitterX, jitterY); - jitterX = 2.0f * jitterX / _renderSize.x; - jitterY = 2.0f * jitterY / _renderSize.y; + jitterX = 2.0f * jitterX / scaledRenderSize.x; + jitterY = 2.0f * jitterY / scaledRenderSize.y; var jitterTranslationMatrix = Matrix4x4.Translate(new Vector3(jitterX, jitterY, 0)); _renderCamera.nonJitteredProjectionMatrix = _renderCamera.projectionMatrix; @@ -401,7 +407,8 @@ namespace FidelityFX if (autoGenerateReactiveMask) { // The auto-reactive mask pass is executed separately from the main FSR2 passes - _dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, _renderSize.x, _renderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); + var scaledRenderSize = GetScaledRenderSize(); + _dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); _context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer); _dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive; } @@ -456,5 +463,18 @@ namespace FidelityFX return new Vector2Int(_renderCamera.pixelWidth, _renderCamera.pixelHeight); } + + private bool UsingDynamicResolution() + { + return _renderCamera.allowDynamicResolution || (_originalRenderTarget != null && _originalRenderTarget.useDynamicScale); + } + + private Vector2Int GetScaledRenderSize() + { + if (UsingDynamicResolution()) + return new Vector2Int(Mathf.CeilToInt(_renderSize.x * ScalableBufferManager.widthScaleFactor), Mathf.CeilToInt(_renderSize.y * ScalableBufferManager.heightScaleFactor)); + + return _renderSize; + } } } diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 6d72e5e..fe8848f 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -144,7 +144,7 @@ PlayerSettings: vrSettings: enable360StereoCapture: 0 isWsaHolographicRemotingEnabled: 0 - enableFrameTimingStats: 0 + enableFrameTimingStats: 1 enableOpenGLProfilerGPURecorders: 1 useHDRDisplay: 0 D3DHDRBitDepth: 0