From 9647805dcc0bcfa44fea0e83dafcc451eca22d38 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Wed, 1 Mar 2023 12:52:57 +0100 Subject: [PATCH] Copy opaque-only render buffer to a temporary texture as input for the reactive mask generator, and clean up the RT after FSR2 is done. Generating the reactive mask now actually works and the difference is very noticeable in motion; much less artifacting on transparent effects. --- Assets/Scripts/Fsr2Controller.cs | 40 +++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/Fsr2Controller.cs b/Assets/Scripts/Fsr2Controller.cs index 7ae8e99..44913e0 100644 --- a/Assets/Scripts/Fsr2Controller.cs +++ b/Assets/Scripts/Fsr2Controller.cs @@ -38,10 +38,12 @@ namespace FidelityFX private Fsr2.QualityMode _prevQualityMode; private Vector2Int _prevDisplaySize; + private bool _prevGenReactiveMask; private CommandBuffer _dispatchCommandBuffer; private CommandBuffer _opaqueOnlyCommandBuffer; private CommandBuffer _inputsCommandBuffer; + private CommandBuffer _cleanupCommandBuffer; private void OnEnable() { @@ -63,15 +65,23 @@ namespace FidelityFX // Create command buffers to bind the camera's output at the right moments in the render loop _opaqueOnlyCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" }; - // TODO: may need to copy the opaque-only render buffer to a temp RT here, in which case we'll need an additional CommandBuffer to release the temp RT again - _opaqueOnlyCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvOpaqueOnly, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color); - _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer); + _opaqueOnlyCommandBuffer.GetTemporaryRT(Fsr2Pipeline.SrvOpaqueOnly, _renderSize.x, _renderSize.y, 0, default, RenderTextureFormat.ARGBHalf); + _opaqueOnlyCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, Fsr2Pipeline.SrvOpaqueOnly); _inputsCommandBuffer = new CommandBuffer { name = "FSR2 Inputs" }; _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputColor, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color); _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputDepth, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth); _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputMotionVectors, BuiltinRenderTextureType.MotionVectors); _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffects, _inputsCommandBuffer); + + _cleanupCommandBuffer = new CommandBuffer { name = "FSR2 Cleanup" }; + _cleanupCommandBuffer.ReleaseTemporaryRT(Fsr2Pipeline.SrvOpaqueOnly); + + if (generateReactiveMask) + { + _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer); + _renderCamera.AddCommandBuffer(CameraEvent.AfterImageEffects, _cleanupCommandBuffer); + } // Apply a mipmap bias so that textures retain their original sharpness float biasOffset = Fsr2.GetMipmapBiasOffset(_renderSize.x, _displaySize.x); @@ -79,6 +89,7 @@ namespace FidelityFX _prevDisplaySize = _displaySize; _prevQualityMode = qualityMode; + _prevGenReactiveMask = generateReactiveMask; } private void OnDisable() @@ -100,6 +111,13 @@ namespace FidelityFX _inputsCommandBuffer = null; } + if (_cleanupCommandBuffer != null) + { + _renderCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffects, _cleanupCommandBuffer); + _cleanupCommandBuffer.Release(); + _cleanupCommandBuffer = null; + } + if (_dispatchCommandBuffer != null) { _dispatchCommandBuffer.Release(); @@ -123,6 +141,22 @@ namespace FidelityFX OnDisable(); OnEnable(); } + + if (generateReactiveMask != _prevGenReactiveMask) + { + if (generateReactiveMask) + { + _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer); + _renderCamera.AddCommandBuffer(CameraEvent.AfterImageEffects, _cleanupCommandBuffer); + } + else + { + _renderCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer); + _renderCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffects, _cleanupCommandBuffer); + } + + _prevGenReactiveMask = generateReactiveMask; + } } public void Reset()