Browse Source

Fixed the ESRAM-related visual issue on Xbox One when auto-reactive or auto-TCR is enabled, by explicitly controlling the lifecycle of the opaque-only color input render texture.

Previously the code relied on undefined behavior, whereby an already released temporary render texture just happened to remain in memory at the same location. On Xbox One with its unique ESRAM cache this would fail.
hdrp
Nico de Poel 3 years ago
parent
commit
3cd852ba8f
  1. 31
      Assets/Scripts/Fsr2ImageEffect.cs
  2. 3
      README.md

31
Assets/Scripts/Fsr2ImageEffect.cs

@ -69,9 +69,13 @@ namespace FidelityFX
[Serializable] [Serializable]
public class GenerateReactiveParameters public class GenerateReactiveParameters
{ {
[Tooltip("A value to scale the output")]
[Range(0, 2)] public float scale = 0.5f; [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; [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; [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; public Fsr2.GenerateReactiveFlags flags = Fsr2.GenerateReactiveFlags.ApplyTonemap | Fsr2.GenerateReactiveFlags.ApplyThreshold | Fsr2.GenerateReactiveFlags.UseComponentsMax;
} }
@ -120,6 +124,7 @@ namespace FidelityFX
private CommandBuffer _dispatchCommandBuffer; private CommandBuffer _dispatchCommandBuffer;
private CommandBuffer _opaqueInputCommandBuffer; private CommandBuffer _opaqueInputCommandBuffer;
private RenderTexture _colorOpaqueOnly;
private Material _copyWithDepthMaterial; private Material _copyWithDepthMaterial;
@ -169,11 +174,7 @@ namespace FidelityFX
_context = Fsr2.CreateContext(_displaySize, _renderSize, Callbacks, flags); _context = Fsr2.CreateContext(_displaySize, _renderSize, Callbacks, flags);
_dispatchCommandBuffer = new CommandBuffer { name = "FSR2 Dispatch" }; _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 = 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) if (autoGenerateReactiveMask || autoGenerateTransparencyAndComposition)
{ {
@ -269,10 +270,18 @@ namespace FidelityFX
_renderCamera.rect = new Rect(0, 0, _originalRect.width * _renderSize.x / _renderCamera.pixelWidth, _originalRect.height * _renderSize.y / _renderCamera.pixelHeight); _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 // Set up the parameters to auto-generate a reactive mask
if (autoGenerateReactiveMask) if (autoGenerateReactiveMask)
{ {
_genReactiveDescription.ColorOpaqueOnly = null;
_genReactiveDescription.ColorOpaqueOnly = _colorOpaqueOnly;
_genReactiveDescription.ColorPreUpscale = null; _genReactiveDescription.ColorPreUpscale = null;
_genReactiveDescription.OutReactive = null; _genReactiveDescription.OutReactive = null;
_genReactiveDescription.RenderSize = _renderSize; _genReactiveDescription.RenderSize = _renderSize;
@ -310,9 +319,11 @@ namespace FidelityFX
_dispatchDescription.Reset = _reset; _dispatchDescription.Reset = _reset;
_reset = false; _reset = false;
// Set up the parameters for the optional experimental auto-TCR feature
_dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition; _dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition;
if (autoGenerateTransparencyAndComposition) if (autoGenerateTransparencyAndComposition)
{ {
_dispatchDescription.ColorOpaqueOnly = _colorOpaqueOnly;
_dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold; _dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold;
_dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale; _dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale;
_dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale; _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); _dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, _renderSize.x, _renderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
_context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer); _context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer);
_dispatchCommandBuffer.ReleaseTemporaryRT(Fsr2ShaderIDs.SrvOpaqueOnly);
_dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive; _dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive;
} }
@ -390,13 +400,14 @@ namespace FidelityFX
_dispatchCommandBuffer.ReleaseTemporaryRT(Fsr2ShaderIDs.UavAutoReactive); _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 // Shut up the Unity warning about not writing to the destination texture
RenderTexture.active = dest; RenderTexture.active = dest;
} }

3
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. - Enabling Auto Exposure causes artifacting on OpenGL Core.
It's uncertain what is causing this. Further investigation is required. It's uncertain what is causing this. Further investigation is required.
Workaround: disable Auto Exposure on affected platforms. 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. - 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. This causes blurry textures as the internal render resolution is lowered. This is a Unity issue of some sort.
Workaround: no known workaround yet. Workaround: no known workaround yet.

Loading…
Cancel
Save