diff --git a/Assets/Scripts/Fsr2ImageEffect.cs b/Assets/Scripts/Fsr2ImageEffect.cs index 7ee9ca3..e6e1f60 100644 --- a/Assets/Scripts/Fsr2ImageEffect.cs +++ b/Assets/Scripts/Fsr2ImageEffect.cs @@ -69,9 +69,13 @@ namespace FidelityFX [Serializable] public class GenerateReactiveParameters { + [Tooltip("A value to scale the output")] [Range(0, 2)] public float scale = 0.5f; + [Tooltip("A threshold value to generate a binary reactive mask")] [Range(0, 1)] public float cutoffThreshold = 0.2f; + [Tooltip("A value to set for the binary reactive mask")] [Range(0, 1)] public float binaryValue = 0.9f; + [Tooltip("Flags to determine how to generate the reactive mask")] public Fsr2.GenerateReactiveFlags flags = Fsr2.GenerateReactiveFlags.ApplyTonemap | Fsr2.GenerateReactiveFlags.ApplyThreshold | Fsr2.GenerateReactiveFlags.UseComponentsMax; } @@ -120,6 +124,7 @@ namespace FidelityFX private CommandBuffer _dispatchCommandBuffer; private CommandBuffer _opaqueInputCommandBuffer; + private RenderTexture _colorOpaqueOnly; private Material _copyWithDepthMaterial; @@ -169,11 +174,7 @@ namespace FidelityFX _context = Fsr2.CreateContext(_displaySize, _renderSize, Callbacks, flags); _dispatchCommandBuffer = new CommandBuffer { name = "FSR2 Dispatch" }; - - // Create command buffers to bind the camera's output at the right moments in the render loop _opaqueInputCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" }; - _opaqueInputCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.SrvOpaqueOnly, _renderSize.x, _renderSize.y, 0, default, GetDefaultFormat()); - _opaqueInputCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, Fsr2ShaderIDs.SrvOpaqueOnly); if (autoGenerateReactiveMask || autoGenerateTransparencyAndComposition) { @@ -268,11 +269,19 @@ namespace FidelityFX _renderCamera.aspect = (_displaySize.x * _originalRect.width) / (_displaySize.y * _originalRect.height); _renderCamera.rect = new Rect(0, 0, _originalRect.width * _renderSize.x / _renderCamera.pixelWidth, _originalRect.height * _renderSize.y / _renderCamera.pixelHeight); } + + // Set up the opaque-only command buffer to make a copy of the camera color buffer right before transparent drawing starts + _opaqueInputCommandBuffer.Clear(); + if (autoGenerateReactiveMask || autoGenerateTransparencyAndComposition) + { + _colorOpaqueOnly = RenderTexture.GetTemporary(_renderSize.x, _renderSize.y, 0, GetDefaultFormat()); + _opaqueInputCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, _colorOpaqueOnly); + } // Set up the parameters to auto-generate a reactive mask if (autoGenerateReactiveMask) { - _genReactiveDescription.ColorOpaqueOnly = null; + _genReactiveDescription.ColorOpaqueOnly = _colorOpaqueOnly; _genReactiveDescription.ColorPreUpscale = null; _genReactiveDescription.OutReactive = null; _genReactiveDescription.RenderSize = _renderSize; @@ -310,9 +319,11 @@ namespace FidelityFX _dispatchDescription.Reset = _reset; _reset = false; + // Set up the parameters for the optional experimental auto-TCR feature _dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition; if (autoGenerateTransparencyAndComposition) { + _dispatchDescription.ColorOpaqueOnly = _colorOpaqueOnly; _dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold; _dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale; _dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale; @@ -358,7 +369,6 @@ namespace FidelityFX { _dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, _renderSize.x, _renderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); _context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer); - _dispatchCommandBuffer.ReleaseTemporaryRT(Fsr2ShaderIDs.SrvOpaqueOnly); _dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive; } @@ -390,13 +400,14 @@ namespace FidelityFX _dispatchCommandBuffer.ReleaseTemporaryRT(Fsr2ShaderIDs.UavAutoReactive); } - if (autoGenerateTransparencyAndComposition) + Graphics.ExecuteCommandBuffer(_dispatchCommandBuffer); + + if (_colorOpaqueOnly != null) { - _dispatchCommandBuffer.ReleaseTemporaryRT(Fsr2ShaderIDs.SrvOpaqueOnly); + RenderTexture.ReleaseTemporary(_colorOpaqueOnly); + _colorOpaqueOnly = null; } - Graphics.ExecuteCommandBuffer(_dispatchCommandBuffer); - // Shut up the Unity warning about not writing to the destination texture RenderTexture.active = dest; } diff --git a/README.md b/README.md index ae06a0c..df6f461 100644 --- a/README.md +++ b/README.md @@ -148,9 +148,6 @@ The exposure value can be supplied to the `Fsr2ImageEffect` script through its E - Enabling Auto Exposure causes artifacting on OpenGL Core. It's uncertain what is causing this. Further investigation is required. Workaround: disable Auto Exposure on affected platforms. -- Auto Reactive Mask causes jitter artifacting on Xbox One when ESRAM is enabled. - This is due to some kind of issue in Unity related to render texture blitting. For unknown reasons the opaque-only render buffer used as reference for generating the reactive mask has an incorrect jitter offset (possibly it's a render buffer from a previous frame), causing the reactive mask to be incorrect as well. - Workaround: either disable ESRAM usage or disable the Auto Generate Reactive Mask feature. - Texture mipmap bias adjustment is not working on MacOS Metal. This causes blurry textures as the internal render resolution is lowered. This is a Unity issue of some sort. Workaround: no known workaround yet.