From c43c8d11f9e92cba2ebf15e21242b6152a41a5fb Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Sat, 21 Dec 2024 15:08:24 +0100 Subject: [PATCH] Reworked SGSR2 classes, moving more logic to the base class, and implemented clip-space delta matrix as well as the is-camera-still logic. --- .../Runtime/Effects/Upscaling/SGSR2/SGSR2.cs | 5 ++ .../Effects/Upscaling/SGSR2Upscaler.cs | 65 ++++++++++++++++++- .../Upscaling/SGSR2Upscaler_2PassCS.cs | 37 +---------- .../Upscaling/SGSR2Upscaler_3PassCS.cs | 37 +---------- 4 files changed, 75 insertions(+), 69 deletions(-) diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/SGSR2.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/SGSR2.cs index d719336..8fd8c84 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/SGSR2.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/SGSR2.cs @@ -10,15 +10,20 @@ public static class SGSR2 { public Vector2Int renderSize; public Vector2Int displaySize; + public Vector2 renderSizeRcp; public Vector2 displaySizeRcp; + public Vector2 jitterOffset; public Vector2 padding1; + public Matrix4x4 clipToPrevClip; + public float preExposure; public float cameraFovAngleHor; public float cameraNear; public float minLerpContribution; + public uint bSameCamera; public uint reset; } diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler.cs index 615491e..b8dad18 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler.cs @@ -8,6 +8,8 @@ namespace UnityEngine.Rendering.PostProcessing { public static bool IsSupported => SystemInfo.supportsComputeShaders; + protected abstract string VariantName { get; } + protected RenderTexture _colorLuma; protected RenderTexture _motionDepthAlpha; protected RenderTexture _motionDepthClipAlpha; @@ -17,7 +19,7 @@ namespace UnityEngine.Rendering.PostProcessing protected readonly ConstantsBuffer _paramsBuffer = new(); protected uint _frameCount = 0; - + public override void CreateContext(PostProcessRenderContext context, Upscaling config) { CreateRenderTexture(ref _colorLuma, "ColorLuma", config.MaxRenderSize, GraphicsFormat.R32_UInt, true); @@ -41,5 +43,66 @@ namespace UnityEngine.Rendering.PostProcessing DestroyRenderTexture(ref _motionDepthAlpha); DestroyRenderTexture(ref _colorLuma); } + + public override void Render(PostProcessRenderContext context, Upscaling config) + { + var cmd = context.command; + cmd.BeginSample(VariantName); + + Matrix4x4 clipToPrevClip = Matrix4x4.identity; + bool isCameraStill = false; + if (_frameCount > 0 && !config.Reset) + { + // We need to use the projection matrix as it is used on the GPU to match what Unity keeps in Camera.previousViewProjectionMatrix + Matrix4x4 viewProj = GL.GetGPUProjectionMatrix(context.camera.nonJitteredProjectionMatrix, true) * context.camera.worldToCameraMatrix; + clipToPrevClip = context.camera.previousViewProjectionMatrix * viewProj.inverse; + isCameraStill = IsCameraStill(viewProj, context.camera.previousViewProjectionMatrix); + } + + ref var parms = ref _paramsBuffer.Value; + parms.renderSize = config.GetScaledRenderSize(context.camera); + parms.displaySize = config.UpscaleSize; + parms.renderSizeRcp = new Vector2(1.0f / parms.renderSize.x, 1.0f / parms.renderSize.y); + parms.displaySizeRcp = new Vector2(1.0f / parms.displaySize.x, 1.0f / parms.displaySize.y); + parms.jitterOffset = config.JitterOffset; + parms.clipToPrevClip = clipToPrevClip; + parms.preExposure = config.preExposure; + parms.cameraFovAngleHor = Mathf.Tan(context.camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * (float)parms.renderSize.x / parms.renderSize.y; + parms.cameraNear = context.camera.nearClipPlane; + parms.minLerpContribution = 0f; + parms.bSameCamera = isCameraStill ? 1u : 0u; + parms.reset = config.Reset ? 1u : 0u; + _paramsBuffer.UpdateBufferData(cmd); + + if (_frameCount == 0 || config.Reset) + { + cmd.SetRenderTarget(_lumaHistory[0]); + cmd.ClearRenderTarget(false, true, Color.clear); + cmd.SetRenderTarget(_lumaHistory[1]); + cmd.ClearRenderTarget(false, true, Color.clear); + cmd.SetRenderTarget(_upscaleHistory[0]); + cmd.ClearRenderTarget(false, true, Color.clear); + cmd.SetRenderTarget(_upscaleHistory[1]); + cmd.ClearRenderTarget(false, true, Color.clear); + } + + DoRender(cmd, context, config); + + cmd.EndSample(VariantName); + _frameCount++; + } + + protected abstract void DoRender(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config); + + private static bool IsCameraStill(in Matrix4x4 currViewProj, in Matrix4x4 prevViewProj, float threshold = 1e-5f) + { + float vpDiff = 0f; + for (int i = 0; i < 16; i++) + { + vpDiff += Mathf.Abs(currViewProj[i] - prevViewProj[i]); + } + + return vpDiff < threshold; + } } } diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_2PassCS.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_2PassCS.cs index c2a7600..a5666e1 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_2PassCS.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_2PassCS.cs @@ -4,43 +4,12 @@ namespace UnityEngine.Rendering.PostProcessing { internal class SGSR2Upscaler_2PassCS: SGSR2Upscaler { - public override void Render(PostProcessRenderContext context, Upscaling config) - { - var cmd = context.command; - cmd.BeginSample("SGSR2 2-Pass CS"); - - ref var parms = ref _paramsBuffer.Value; - parms.renderSize = config.GetScaledRenderSize(context.camera); - parms.displaySize = config.UpscaleSize; - parms.renderSizeRcp = new Vector2(1.0f / parms.renderSize.x, 1.0f / parms.renderSize.y); - parms.displaySizeRcp = new Vector2(1.0f / parms.displaySize.x, 1.0f / parms.displaySize.y); - parms.jitterOffset = config.JitterOffset; - parms.clipToPrevClip = Matrix4x4.identity; // TODO: clipToPrevClip => (previous_view_proj * inv_vp) - parms.preExposure = config.preExposure; - parms.cameraFovAngleHor = Mathf.Tan(context.camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * (float)parms.renderSize.x / parms.renderSize.y; - parms.cameraNear = context.camera.nearClipPlane; - parms.minLerpContribution = 0f; - parms.bSameCamera = 0u; - parms.reset = config.Reset ? 1u : 0u; - _paramsBuffer.UpdateBufferData(cmd); - - if (_frameCount == 0 || config.Reset) - { - cmd.SetRenderTarget(_lumaHistory[0]); - cmd.ClearRenderTarget(false, true, Color.clear); - cmd.SetRenderTarget(_lumaHistory[1]); - cmd.ClearRenderTarget(false, true, Color.clear); - cmd.SetRenderTarget(_upscaleHistory[0]); - cmd.ClearRenderTarget(false, true, Color.clear); - cmd.SetRenderTarget(_upscaleHistory[1]); - cmd.ClearRenderTarget(false, true, Color.clear); - } + protected override string VariantName => "SGSR2 2-Pass CS"; + protected override void DoRender(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config) + { Convert(cmd, context, config); Upscale(cmd, context); - - cmd.EndSample("SGSR2 2-Pass CS"); - _frameCount++; } private void Convert(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config) diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_3PassCS.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_3PassCS.cs index a41aac7..a32e2e3 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_3PassCS.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler_3PassCS.cs @@ -4,44 +4,13 @@ namespace UnityEngine.Rendering.PostProcessing { internal class SGSR2Upscaler_3PassCS: SGSR2Upscaler { - public override void Render(PostProcessRenderContext context, Upscaling config) + protected override string VariantName => "SGSR2 3-Pass CS"; + + protected override void DoRender(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config) { - var cmd = context.command; - cmd.BeginSample("SGSR2 3-Pass CS"); - - ref var parms = ref _paramsBuffer.Value; - parms.renderSize = config.GetScaledRenderSize(context.camera); - parms.displaySize = config.UpscaleSize; - parms.renderSizeRcp = new Vector2(1.0f / parms.renderSize.x, 1.0f / parms.renderSize.y); - parms.displaySizeRcp = new Vector2(1.0f / parms.displaySize.x, 1.0f / parms.displaySize.y); - parms.jitterOffset = config.JitterOffset; - parms.clipToPrevClip = Matrix4x4.identity; // TODO: clipToPrevClip => (previous_view_proj * inv_vp) - parms.preExposure = config.preExposure; - parms.cameraFovAngleHor = Mathf.Tan(context.camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * (float)parms.renderSize.x / parms.renderSize.y; - parms.cameraNear = context.camera.nearClipPlane; - parms.minLerpContribution = 0f; - parms.bSameCamera = 0u; - parms.reset = config.Reset ? 1u : 0u; - _paramsBuffer.UpdateBufferData(cmd); - - if (_frameCount == 0 || config.Reset) - { - cmd.SetRenderTarget(_lumaHistory[0]); - cmd.ClearRenderTarget(false, true, Color.clear); - cmd.SetRenderTarget(_lumaHistory[1]); - cmd.ClearRenderTarget(false, true, Color.clear); - cmd.SetRenderTarget(_upscaleHistory[0]); - cmd.ClearRenderTarget(false, true, Color.clear); - cmd.SetRenderTarget(_upscaleHistory[1]); - cmd.ClearRenderTarget(false, true, Color.clear); - } - Convert(cmd, context, config); Activate(cmd, context); Upscale(cmd, context); - - cmd.EndSample("SGSR2 3-Pass CS"); - _frameCount++; } private void Convert(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config)