diff --git a/Assets/Scripts/Fsr2ImageEffect.cs b/Assets/Scripts/Fsr2ImageEffect.cs index 962d439..fff3418 100644 --- a/Assets/Scripts/Fsr2ImageEffect.cs +++ b/Assets/Scripts/Fsr2ImageEffect.cs @@ -157,7 +157,30 @@ namespace FidelityFX } _helper = GetComponent(); + _copyWithDepthMaterial = new Material(Shader.Find("Hidden/BlitCopyWithDepth")); + CreateFsrContext(); + CreateCommandBuffers(); + } + + private void OnDisable() + { + DestroyCommandBuffers(); + DestroyFsrContext(); + + if (_copyWithDepthMaterial != null) + { + Destroy(_copyWithDepthMaterial); + _copyWithDepthMaterial = null; + } + + // Restore the camera's original state + _renderCamera.depthTextureMode = _originalDepthTextureMode; + _renderCamera.targetTexture = _originalRenderTarget; + } + + private void CreateFsrContext() + { // Initialize FSR2 context Fsr2.InitializationFlags flags = 0; if (_renderCamera.allowHDR) flags |= Fsr2.InitializationFlags.EnableHighDynamicRange; @@ -166,48 +189,33 @@ namespace FidelityFX _context = Fsr2.CreateContext(_displaySize, _renderSize, Callbacks, flags); - _dispatchCommandBuffer = new CommandBuffer { name = "FSR2 Dispatch" }; - _opaqueInputCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" }; - _renderCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, _opaqueInputCommandBuffer); - - _copyWithDepthMaterial = new Material(Shader.Find("Hidden/BlitCopyWithDepth")); - _prevDisplaySize = _displaySize; _prevQualityMode = qualityMode; _prevAutoExposure = enableAutoExposure; - // Apply a mipmap bias so that textures retain their sharpness - float biasOffset = Fsr2.GetMipmapBiasOffset(_renderSize.x, _displaySize.x); - if (!float.IsNaN(biasOffset) && !float.IsInfinity(biasOffset)) - { - Callbacks.ApplyMipmapBias(biasOffset); - _appliedBiasOffset = biasOffset; - } - else - { - _appliedBiasOffset = 0f; - } + ApplyMipmapBias(); } - private void OnDisable() + private void DestroyFsrContext() { - // Undo the current mipmap bias offset - if (!float.IsNaN(_appliedBiasOffset) && !float.IsInfinity(_appliedBiasOffset) && _appliedBiasOffset != 0f) + UndoMipmapBias(); + + if (_context != null) { - Callbacks.ApplyMipmapBias(-_appliedBiasOffset); - _appliedBiasOffset = 0f; + _context.Destroy(); + _context = null; } + } - // Restore the camera's original state - _renderCamera.depthTextureMode = _originalDepthTextureMode; - _renderCamera.targetTexture = _originalRenderTarget; + private void CreateCommandBuffers() + { + _dispatchCommandBuffer = new CommandBuffer { name = "FSR2 Dispatch" }; + _opaqueInputCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" }; + _renderCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, _opaqueInputCommandBuffer); + } - if (_copyWithDepthMaterial != null) - { - Destroy(_copyWithDepthMaterial); - _copyWithDepthMaterial = null; - } - + private void DestroyCommandBuffers() + { if (_opaqueInputCommandBuffer != null) { _renderCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, _opaqueInputCommandBuffer); @@ -220,11 +228,30 @@ namespace FidelityFX _dispatchCommandBuffer.Release(); _dispatchCommandBuffer = null; } + } + + private void ApplyMipmapBias() + { + // Apply a mipmap bias so that textures retain their sharpness + float biasOffset = Fsr2.GetMipmapBiasOffset(_renderSize.x, _displaySize.x); + if (!float.IsNaN(biasOffset) && !float.IsInfinity(biasOffset)) + { + Callbacks.ApplyMipmapBias(biasOffset); + _appliedBiasOffset = biasOffset; + } + else + { + _appliedBiasOffset = 0f; + } + } - if (_context != null) + private void UndoMipmapBias() + { + // Undo the current mipmap bias offset + if (!float.IsNaN(_appliedBiasOffset) && !float.IsInfinity(_appliedBiasOffset) && _appliedBiasOffset != 0f) { - _context.Destroy(); - _context = null; + Callbacks.ApplyMipmapBias(-_appliedBiasOffset); + _appliedBiasOffset = 0f; } } @@ -267,19 +294,18 @@ namespace FidelityFX _opaqueInputCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, _colorOpaqueOnly); } - // Set up the parameters to auto-generate a reactive mask if (autoGenerateReactiveMask) { - _genReactiveDescription.ColorOpaqueOnly = _colorOpaqueOnly; - _genReactiveDescription.ColorPreUpscale = null; - _genReactiveDescription.OutReactive = null; - _genReactiveDescription.RenderSize = _renderSize; - _genReactiveDescription.Scale = generateReactiveParameters.scale; - _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; - _genReactiveDescription.BinaryValue = generateReactiveParameters.binaryValue; - _genReactiveDescription.Flags = generateReactiveParameters.flags; + SetupAutoReactiveDescription(); } + SetupDispatchDescription(); + + ApplyJitter(); + } + + private void SetupDispatchDescription() + { // Set up the main FSR2 dispatch parameters // The input and output textures are left blank here, as they are already being bound elsewhere in this source file _dispatchDescription.Color = null; @@ -324,7 +350,23 @@ namespace FidelityFX // Swap the near and far clip plane distances as FSR2 expects this when using inverted depth (_dispatchDescription.CameraNear, _dispatchDescription.CameraFar) = (_dispatchDescription.CameraFar, _dispatchDescription.CameraNear); } + } + + private void SetupAutoReactiveDescription() + { + // Set up the parameters to auto-generate a reactive mask + _genReactiveDescription.ColorOpaqueOnly = _colorOpaqueOnly; + _genReactiveDescription.ColorPreUpscale = null; + _genReactiveDescription.OutReactive = null; + _genReactiveDescription.RenderSize = _renderSize; + _genReactiveDescription.Scale = generateReactiveParameters.scale; + _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; + _genReactiveDescription.BinaryValue = generateReactiveParameters.binaryValue; + _genReactiveDescription.Flags = generateReactiveParameters.flags; + } + private void ApplyJitter() + { // Perform custom jittering of the camera's projection matrix according to FSR2's recipe int jitterPhaseCount = Fsr2.GetJitterPhaseCount(_renderSize.x, _displaySize.x); Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount); @@ -385,9 +427,12 @@ namespace FidelityFX _dispatchCommandBuffer.ReleaseTemporaryRT(Fsr2ShaderIDs.UavAutoReactive); Graphics.ExecuteCommandBuffer(_dispatchCommandBuffer); - - RenderTexture.ReleaseTemporary(_colorOpaqueOnly); - _colorOpaqueOnly = null; + + if (_colorOpaqueOnly != null) + { + RenderTexture.ReleaseTemporary(_colorOpaqueOnly); + _colorOpaqueOnly = null; + } // Shut up the Unity warning about not writing to the destination texture RenderTexture.active = dest;