Browse Source

Rename FSR2 to FSR3 Upscaler, part 1: strings and comments.

fsr3
Nico de Poel 2 years ago
parent
commit
62a924ae83
  1. 2
      Assets/Resources/FSR3/ffx_fsr3upscaler_compute_luminance_pyramid_pass.compute
  2. 10
      Assets/Scripts/Core/Fsr2.cs
  3. 4
      Assets/Scripts/Core/Fsr2Callbacks.cs
  4. 9
      Assets/Scripts/Core/Fsr2Context.cs
  5. 6
      Assets/Scripts/Core/Fsr2Pass.cs
  6. 76
      Assets/Scripts/Core/Fsr2Resources.cs
  7. 6
      Assets/Scripts/Fsr2CameraHelper.cs
  8. 30
      Assets/Scripts/Fsr2ImageEffect.cs
  9. 4
      Assets/Scripts/Fsr2ImageEffectHelper.cs

2
Assets/Resources/FSR3/ffx_fsr3upscaler_compute_luminance_pyramid_pass.compute

@ -25,7 +25,7 @@
#pragma multi_compile_local __ FFX_FSR3UPSCALER_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ UNITY_FSR3UPSCALER_HDRP // TODO: look into generalizing this
#pragma multi_compile_local __ UNITY_FSR3UPSCALER_HDRP
#include "ffx_fsr3upscaler_unity_common.cginc"

10
Assets/Scripts/Core/Fsr2.cs

@ -26,12 +26,12 @@ using UnityEngine.Rendering;
namespace FidelityFX
{
/// <summary>
/// A collection of helper functions and data structures required by the FSR2 process.
/// A collection of helper functions and data structures required by the FSR3 Upscaler process.
/// </summary>
public static class Fsr2
{
/// <summary>
/// Creates a new FSR2 context with standard parameters that are appropriate for the current platform.
/// Creates a new FSR3 Upscaler context with standard parameters that are appropriate for the current platform.
/// </summary>
public static Fsr2Context CreateContext(Vector2Int displaySize, Vector2Int maxRenderSize, IFsr2Callbacks callbacks, InitializationFlags flags = 0)
{
@ -44,7 +44,7 @@ namespace FidelityFX
flags |= InitializationFlags.EnableDebugChecking;
#endif
Debug.Log($"Setting up FSR2 with render size: {maxRenderSize.x}x{maxRenderSize.y}, display size: {displaySize.x}x{displaySize.y}, flags: {flags}");
Debug.Log($"Setting up FSR3 Upscaler with render size: {maxRenderSize.x}x{maxRenderSize.y}, display size: {displaySize.x}x{displaySize.y}, flags: {flags}");
var contextDescription = new ContextDescription
{
@ -137,7 +137,7 @@ namespace FidelityFX
public enum QualityMode
{
NativeAA = 0,
UltraQuality = 1, // TODO: UltraQuality may become obsolete, and NativeAA can replace it at position 0
UltraQuality = 1,
Quality = 2,
Balanced = 3,
Performance = 4,
@ -234,7 +234,7 @@ namespace FidelityFX
/// <summary>
/// A structure encapsulating the parameters for automatic generation of a reactive mask.
/// The default values for Scale, CutoffThreshold, BinaryValue and Flags were taken from the FSR2 demo project.
/// The default values for Scale, CutoffThreshold, BinaryValue and Flags were taken from the FSR3 demo project.
/// </summary>
public class GenerateReactiveDescription
{

4
Assets/Scripts/Core/Fsr2Callbacks.cs

@ -23,8 +23,8 @@ using UnityEngine;
namespace FidelityFX
{
/// <summary>
/// A collection of callbacks required by the FSR2 process.
/// This allows some customization by the game dev on how to integrate FSR2 into their own game setup.
/// A collection of callbacks required by the FSR3 Upscaler process.
/// This allows some customization by the game dev on how to integrate FSR3 upscaling into their own game setup.
/// </summary>
public interface IFsr2Callbacks
{

9
Assets/Scripts/Core/Fsr2Context.cs

@ -19,7 +19,6 @@
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;
@ -27,8 +26,8 @@ using UnityEngine.Rendering;
namespace FidelityFX
{
/// <summary>
/// This class loosely matches the FfxFsr2Context struct from the original FSR2 codebase.
/// It manages the various resources and compute passes required by the FSR2 process.
/// This class loosely matches the FfxFsr2Context struct from the original FSR3 Upscaler codebase.
/// It manages the various resources and compute passes required by the FSR3 Upscaler process.
/// Note that this class does not know anything about Unity render pipelines; all it knows is CommandBuffers and RenderTargetIdentifiers.
/// This should make it suitable for integration with any of the available Unity render pipelines.
/// </summary>
@ -77,7 +76,7 @@ namespace FidelityFX
public void Create(Fsr2.ContextDescription contextDescription)
{
_contextDescription = contextDescription;
_commandBuffer = new CommandBuffer { name = "FSR2" };
_commandBuffer = new CommandBuffer { name = "FSR3 Upscaler" };
_fsr2ConstantsBuffer = CreateConstantBuffer<Fsr2.Fsr2Constants>();
_spdConstantsBuffer = CreateConstantBuffer<Fsr2.SpdConstants>();
@ -557,7 +556,7 @@ namespace FidelityFX
}
/// <summary>
/// The FSR2 C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the RCAS shader.
/// The FSR3 C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the RCAS shader.
/// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values.
/// </summary>
private static readonly Fsr2.RcasConstants[] RcasConfigs = new []

6
Assets/Scripts/Core/Fsr2Pass.cs

@ -26,13 +26,13 @@ using UnityEngine.Rendering;
namespace FidelityFX
{
/// <summary>
/// Base class for all of the compute passes that make up the FSR2 process.
/// This loosely matches the FfxPipelineState struct from the original FSR2 codebase, wrapped in an object-oriented blanket.
/// Base class for all of the compute passes that make up the FSR3 Upscaler process.
/// This loosely matches the FfxPipelineState struct from the original FSR3 Upscaler codebase, wrapped in an object-oriented blanket.
/// These classes are responsible for loading compute shaders, managing temporary resources, binding resources to shader kernels and dispatching said shaders.
/// </summary>
internal abstract class Fsr2Pass: IDisposable
{
internal const int ShadingChangeMipLevel = 4; // This matches the FFX_FSR2_SHADING_CHANGE_MIP_LEVEL define
internal const int ShadingChangeMipLevel = 4; // This matches the FFX_FSR3UPSCALER_SHADING_CHANGE_MIP_LEVEL define
protected readonly Fsr2.ContextDescription ContextDescription;
protected readonly Fsr2Resources Resources;

76
Assets/Scripts/Core/Fsr2Resources.cs

@ -26,7 +26,7 @@ using UnityEngine.Rendering;
namespace FidelityFX
{
/// <summary>
/// Helper class for bundling and managing persistent resources required by the FSR2 process.
/// Helper class for bundling and managing persistent resources required by the FSR3 Upscaler process.
/// This includes lookup tables, default fallback resources and double-buffered resources that get swapped between frames.
/// </summary>
internal class Fsr2Resources
@ -65,71 +65,71 @@ namespace FidelityFX
maximumBias[i] = MaximumBias[i] / 2.0f;
}
// Resource FSR2_LanczosLutData: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
// Resource FSR3UPSCALER_LanczosLutData: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
// R16_SNorm textures are not supported by Unity on most platforms, strangely enough. So instead we use R32_SFloat and upload pre-normalized float data.
LanczosLut = new Texture2D(lanczos2LutWidth, 1, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "FSR2_LanczosLutData" };
LanczosLut = new Texture2D(lanczos2LutWidth, 1, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "FSR3UPSCALER_LanczosLutData" };
LanczosLut.SetPixelData(lanczos2Weights, 0);
LanczosLut.Apply();
// Resource FSR2_MaximumUpsampleBias: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
MaximumBiasLut = new Texture2D(MaximumBiasTextureWidth, MaximumBiasTextureHeight, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "FSR2_MaximumUpsampleBias" };
// Resource FSR3UPSCALER_MaximumUpsampleBias: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
MaximumBiasLut = new Texture2D(MaximumBiasTextureWidth, MaximumBiasTextureHeight, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "FSR3UPSCALER_MaximumUpsampleBias" };
MaximumBiasLut.SetPixelData(maximumBias, 0);
MaximumBiasLut.Apply();
// Resource FSR2_DefaultExposure: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
DefaultExposure = new Texture2D(1, 1, GraphicsFormat.R32G32_SFloat, TextureCreationFlags.None) { name = "FSR2_DefaultExposure" };
// Resource FSR3UPSCALER_DefaultExposure: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
DefaultExposure = new Texture2D(1, 1, GraphicsFormat.R32G32_SFloat, TextureCreationFlags.None) { name = "FSR3UPSCALER_DefaultExposure" };
DefaultExposure.SetPixel(0, 0, Color.clear);
DefaultExposure.Apply();
// Resource FSR2_DefaultReactivityMask: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
DefaultReactive = new Texture2D(1, 1, GraphicsFormat.R8_UNorm, TextureCreationFlags.None) { name = "FSR2_DefaultReactivityMask" };
// Resource FSR3UPSCALER_DefaultReactivityMask: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
DefaultReactive = new Texture2D(1, 1, GraphicsFormat.R8_UNorm, TextureCreationFlags.None) { name = "FSR3UPSCALER_DefaultReactivityMask" };
DefaultReactive.SetPixel(0, 0, Color.clear);
DefaultReactive.Apply();
// Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
// Despite what the original FSR2 codebase says, this resource really isn't aliasable. Resetting this counter to 0 every frame breaks auto-exposure on MacOS Metal.
SpdAtomicCounter = new RenderTexture(1, 1, 0, GraphicsFormat.R32_UInt) { name = "FSR2_SpdAtomicCounter", enableRandomWrite = true };
// Resource FSR3UPSCALER_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
// Despite what the original FSR3 codebase says, this resource really isn't aliasable. Resetting this counter to 0 every frame breaks auto-exposure on MacOS Metal.
SpdAtomicCounter = new RenderTexture(1, 1, 0, GraphicsFormat.R32_UInt) { name = "FSR3UPSCALER_SpdAtomicCounter", enableRandomWrite = true };
SpdAtomicCounter.Create();
// Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
AutoExposure = new RenderTexture(1, 1, 0, GraphicsFormat.R32G32_SFloat) { name = "FSR2_AutoExposure", enableRandomWrite = true };
// Resource FSR3UPSCALER_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
AutoExposure = new RenderTexture(1, 1, 0, GraphicsFormat.R32G32_SFloat) { name = "FSR3UPSCALER_AutoExposure", enableRandomWrite = true };
AutoExposure.Create();
// Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// Resource FSR3UPSCALER_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// This is a rather special case: it's an aliasable resource, but because we require a mipmap chain and bind specific mip levels per shader, we can't easily use temporary RTs for this.
int w = contextDescription.MaxRenderSize.x / 2, h = contextDescription.MaxRenderSize.y / 2;
int mipCount = 1 + Mathf.FloorToInt(Mathf.Log(Math.Max(w, h), 2.0f));
SceneLuminance = new RenderTexture(w, h, 0, GraphicsFormat.R16_SFloat, mipCount) { name = "FSR2_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false };
SceneLuminance = new RenderTexture(w, h, 0, GraphicsFormat.R16_SFloat, mipCount) { name = "FSR3UPSCALER_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false };
SceneLuminance.Create();
// Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(DilatedMotionVectors, "FSR2_InternalDilatedVelocity", contextDescription.MaxRenderSize, GraphicsFormat.R16G16_SFloat);
// Resources FSR3UPSCALER_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(DilatedMotionVectors, "FSR3UPSCALER_InternalDilatedVelocity", contextDescription.MaxRenderSize, GraphicsFormat.R16G16_SFloat);
// Resources FSR2_LockStatus1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(LockStatus, "FSR2_LockStatus", contextDescription.DisplaySize, GraphicsFormat.R16G16_SFloat);
// Resources FSR3UPSCALER_LockStatus1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(LockStatus, "FSR3UPSCALER_LockStatus", contextDescription.DisplaySize, GraphicsFormat.R16G16_SFloat);
// Resources FSR2_InternalUpscaled1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(InternalUpscaled, "FSR2_InternalUpscaled", contextDescription.DisplaySize, GraphicsFormat.R16G16B16A16_SFloat);
// Resources FSR3UPSCALER_InternalUpscaled1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(InternalUpscaled, "FSR3UPSCALER_InternalUpscaled", contextDescription.DisplaySize, GraphicsFormat.R16G16B16A16_SFloat);
// Resources FSR2_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(LumaHistory, "FSR2_LumaHistory", contextDescription.DisplaySize, GraphicsFormat.R8G8B8A8_UNorm);
// Resources FSR3UPSCALER_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(LumaHistory, "FSR3UPSCALER_LumaHistory", contextDescription.DisplaySize, GraphicsFormat.R8G8B8A8_UNorm);
}
public void CreateTcrAutogenResources(Fsr2.ContextDescription contextDescription)
{
// Resource FSR2_AutoReactive: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
AutoReactive = new RenderTexture(contextDescription.MaxRenderSize.x, contextDescription.MaxRenderSize.y, 0, GraphicsFormat.R8_UNorm) { name = "FSR2_AutoReactive", enableRandomWrite = true };
// Resource FSR3UPSCALER_AutoReactive: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
AutoReactive = new RenderTexture(contextDescription.MaxRenderSize.x, contextDescription.MaxRenderSize.y, 0, GraphicsFormat.R8_UNorm) { name = "FSR3UPSCALER_AutoReactive", enableRandomWrite = true };
AutoReactive.Create();
// Resource FSR2_AutoComposition: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
AutoComposition = new RenderTexture(contextDescription.MaxRenderSize.x, contextDescription.MaxRenderSize.y, 0, GraphicsFormat.R8_UNorm) { name = "FSR2_AutoComposition", enableRandomWrite = true };
// Resource FSR3UPSCALER_AutoComposition: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
AutoComposition = new RenderTexture(contextDescription.MaxRenderSize.x, contextDescription.MaxRenderSize.y, 0, GraphicsFormat.R8_UNorm) { name = "FSR3UPSCALER_AutoComposition", enableRandomWrite = true };
AutoComposition.Create();
// Resources FSR2_PrevPreAlpha0/1: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R11G11B10_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(PrevPreAlpha, "FSR2_PrevPreAlpha", contextDescription.MaxRenderSize, GraphicsFormat.B10G11R11_UFloatPack32);
// Resources FSR3UPSCALER_PrevPreAlpha0/1: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R11G11B10_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(PrevPreAlpha, "FSR3UPSCALER_PrevPreAlpha", contextDescription.MaxRenderSize, GraphicsFormat.B10G11R11_UFloatPack32);
// Resources FSR2_PrevPostAlpha0/1: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R11G11B10_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(PrevPostAlpha, "FSR2_PrevPostAlpha", contextDescription.MaxRenderSize, GraphicsFormat.B10G11R11_UFloatPack32);
// Resources FSR3UPSCALER_PrevPostAlpha0/1: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R11G11B10_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(PrevPostAlpha, "FSR3UPSCALER_PrevPostAlpha", contextDescription.MaxRenderSize, GraphicsFormat.B10G11R11_UFloatPack32);
}
// Set up shared aliasable resources, i.e. temporary render textures
@ -139,22 +139,22 @@ namespace FidelityFX
Vector2Int displaySize = contextDescription.DisplaySize;
Vector2Int maxRenderSize = contextDescription.MaxRenderSize;
// FSR2_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
// FSR3UPSCALER_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavReconstructedPrevNearestDepth, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R32_UInt, 1, true);
// FSR2_DilatedDepth: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// FSR3UPSCALER_DilatedDepth: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavDilatedDepth, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R32_SFloat, 1, true);
// FSR2_LockInputLuma: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// FSR3UPSCALER_LockInputLuma: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavLockInputLuma, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R16_SFloat, 1, true);
// FSR2_DilatedReactiveMasks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
// FSR3UPSCALER_DilatedReactiveMasks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavDilatedReactiveMasks, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R8G8_UNorm, 1, true);
// FSR2_PreparedInputColor: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// FSR3UPSCALER_PreparedInputColor: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavPreparedInputColor, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R16G16B16A16_SFloat, 1, true);
// FSR2_NewLocks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
// FSR3UPSCALER_NewLocks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavNewLocks, displaySize.x, displaySize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
}

6
Assets/Scripts/Fsr2CameraHelper.cs

@ -44,7 +44,7 @@ namespace FidelityFX
private void OnEnable()
{
// Set up the original camera to output all of the required FSR2 input resources at the desired resolution
// Set up the original camera to output all of the required FSR3 Upscaler input resources at the desired resolution
_renderCamera = GetComponent<Camera>();
_originalDepthTextureMode = _renderCamera.depthTextureMode;
_renderCamera.depthTextureMode = _originalDepthTextureMode | DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
@ -65,7 +65,7 @@ namespace FidelityFX
if (_maxRenderSize.x == 0 || _maxRenderSize.y == 0)
{
Debug.LogError($"FSR2 render size is invalid: {_maxRenderSize.x}x{_maxRenderSize.y}. Please check your screen resolution and camera viewport parameters.");
Debug.LogError($"FSR3 Upscaler render size is invalid: {_maxRenderSize.x}x{_maxRenderSize.y}. Please check your screen resolution and camera viewport parameters.");
enabled = false;
}
@ -86,7 +86,7 @@ namespace FidelityFX
{
var scaledRenderSize = GetScaledRenderSize();
// Perform custom jittering of the camera's projection matrix according to FSR2's recipe
// Perform custom jittering of the camera's projection matrix according to FSR3's recipe
int jitterPhaseCount = Fsr2.GetJitterPhaseCount(scaledRenderSize.x, _displaySize.x);
Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);

30
Assets/Scripts/Fsr2ImageEffect.cs

@ -27,9 +27,9 @@ using UnityEngine.Rendering;
namespace FidelityFX
{
/// <summary>
/// This class is responsible for hooking into various Unity events and translating them to the FSR2 subsystem.
/// This includes creation and destruction of the FSR2 context, as well as dispatching commands at the right time.
/// This component also exposes various FSR2 parameters to the Unity inspector.
/// This class is responsible for hooking into various Unity events and translating them to the FSR3 Upscaler subsystem.
/// This includes creation and destruction of the FSR3 Upscaler context, as well as dispatching commands at the right time.
/// This component also exposes various FSR3 Upscaler parameters to the Unity inspector.
/// </summary>
[RequireComponent(typeof(Camera))]
public class Fsr2ImageEffect : MonoBehaviour
@ -128,7 +128,7 @@ namespace FidelityFX
private void OnEnable()
{
// Set up the original camera to output all of the required FSR2 input resources at the desired resolution
// Set up the original camera to output all of the required FSR3 input resources at the desired resolution
_renderCamera = GetComponent<Camera>();
_originalRenderTarget = _renderCamera.targetTexture;
_originalDepthTextureMode = _renderCamera.depthTextureMode;
@ -142,14 +142,14 @@ namespace FidelityFX
if (!SystemInfo.supportsComputeShaders)
{
Debug.LogError("FSR2 requires compute shader support!");
Debug.LogError("FSR3 Upscaler requires compute shader support!");
enabled = false;
return;
}
if (_maxRenderSize.x == 0 || _maxRenderSize.y == 0)
{
Debug.LogError($"FSR2 render size is invalid: {_maxRenderSize.x}x{_maxRenderSize.y}. Please check your screen resolution and camera viewport parameters.");
Debug.LogError($"FSR3 Upscaler render size is invalid: {_maxRenderSize.x}x{_maxRenderSize.y}. Please check your screen resolution and camera viewport parameters.");
enabled = false;
return;
}
@ -195,7 +195,7 @@ namespace FidelityFX
private void CreateFsrContext()
{
// Initialize FSR2 context
// Initialize FSR3 Upscaler context
Fsr2.InitializationFlags flags = 0;
if (_renderCamera.allowHDR) flags |= Fsr2.InitializationFlags.EnableHighDynamicRange;
if (enableFP16) flags |= Fsr2.InitializationFlags.EnableFP16Usage;
@ -224,8 +224,8 @@ namespace FidelityFX
private void CreateCommandBuffers()
{
_dispatchCommandBuffer = new CommandBuffer { name = "FSR2 Dispatch" };
_opaqueInputCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" };
_dispatchCommandBuffer = new CommandBuffer { name = "FSR3 Upscaler Dispatch" };
_opaqueInputCommandBuffer = new CommandBuffer { name = "FSR3 Upscaler Opaque Input" };
_renderCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, _opaqueInputCommandBuffer);
}
@ -263,7 +263,7 @@ namespace FidelityFX
private void Update()
{
// Monitor for any changes in parameters that require a reset of the FSR2 context
// Monitor for any changes in parameters that require a reset of the FSR3 Upscaler context
var displaySize = GetDisplaySize();
if (displaySize.x != _prevDisplaySize.x || displaySize.y != _prevDisplaySize.y || qualityMode != _prevQualityMode || enableAutoExposure != _prevAutoExposure)
{
@ -324,7 +324,7 @@ namespace FidelityFX
private void SetupDispatchDescription()
{
// Set up the main FSR2 dispatch parameters
// Set up the main FSR3 Upscaler dispatch parameters
_dispatchDescription.Color = new Fsr2.ResourceView(BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color);
_dispatchDescription.Depth = new Fsr2.ResourceView(BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth);
_dispatchDescription.MotionVectors = new Fsr2.ResourceView(BuiltinRenderTextureType.MotionVectors);
@ -366,7 +366,7 @@ namespace FidelityFX
if (SystemInfo.usesReversedZBuffer)
{
// Swap the near and far clip plane distances as FSR2 expects this when using inverted depth
// Swap the near and far clip plane distances as FSR3 expects this when using inverted depth
(_dispatchDescription.CameraNear, _dispatchDescription.CameraFar) = (_dispatchDescription.CameraFar, _dispatchDescription.CameraNear);
}
}
@ -388,7 +388,7 @@ namespace FidelityFX
{
var scaledRenderSize = GetScaledRenderSize();
// Perform custom jittering of the camera's projection matrix according to FSR2's recipe
// Perform custom jittering of the camera's projection matrix according to FSR3's recipe
int jitterPhaseCount = Fsr2.GetJitterPhaseCount(scaledRenderSize.x, _displaySize.x);
Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);
@ -416,14 +416,14 @@ namespace FidelityFX
if (autoGenerateReactiveMask)
{
// The auto-reactive mask pass is executed separately from the main FSR2 passes
// The auto-reactive mask pass is executed separately from the main FSR3 Upscaler passes
var scaledRenderSize = GetScaledRenderSize();
_dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
_context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer);
_dispatchDescription.Reactive = new Fsr2.ResourceView(Fsr2ShaderIDs.UavAutoReactive);
}
// The backbuffer is not set up to allow random-write access, so we need a temporary render texture for FSR2 to output to
// The backbuffer is not set up to allow random-write access, so we need a temporary render texture for FSR3 to output to
_dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavUpscaledOutput, _displaySize.x, _displaySize.y, 0, default, GetDefaultFormat(), default, 1, true);
_context.Dispatch(_dispatchDescription, _dispatchCommandBuffer);

4
Assets/Scripts/Fsr2ImageEffectHelper.cs

@ -25,10 +25,10 @@ namespace FidelityFX
{
/// <summary>
/// Small helper script to be used in conjunction with the Fsr2ImageEffect script.
/// The FSR2 image effect needs to be the last effect in the post-processing chain but for render scaling to work properly, it also needs to be the first to execute OnPreCull.
/// The FSR3 Upscaler image effect needs to be the last effect in the post-processing chain but for render scaling to work properly, it also needs to be the first to execute OnPreCull.
/// Unfortunately altering the script execution order does not affect the order in which OnPreCull is executed. Only the order of scripts on the same game object matters.
///
/// When combining FSR2 upscaling with other post-processing effects (most notably Unity's Post-Processing Stack V2),
/// When combining FSR3 upscaling with other post-processing effects (most notably Unity's Post-Processing Stack V2),
/// this script should be added to the same camera and moved up above any other scripts that have an OnPreCull method.
/// </summary>
[RequireComponent(typeof(Camera), typeof(Fsr2ImageEffect))]

Loading…
Cancel
Save