using System; using UnityEngine; namespace FidelityFX { public static class Fsr2 { // Allow overriding of certain Unity resource management behaviors by the programmer public static Fsr2Callbacks GlobalCallbacks { get; set; } = new Fsr2Callbacks(); public enum QualityMode { Quality = 1, Balanced = 2, Performance = 3, UltraPerformance = 4, } [Flags] public enum InitializationFlags { EnableHighDynamicRange = 1 << 0, EnableDisplayResolutionMotionVectors = 1 << 1, EnableMotionVectorsJitterCancellation = 1 << 2, EnableDepthInverted = 1 << 3, EnableDepthInfinite = 1 << 4, EnableAutoExposure = 1 << 5, EnableDynamicResolution = 1 << 6, EnableTexture1DUsage = 1 << 7, } public class ContextDescription { public InitializationFlags Flags; public Vector2Int MaxRenderSize; public Vector2Int DisplaySize; public Fsr2Callbacks Callbacks; } public class DispatchDescription { // Texture2D Color, Depth, MotionVectors; // Will be passed using ComputeShader.SetTextureFromGlobal public Texture2D Exposure; public Texture2D Reactive; public Texture2D TransparencyAndComposition; public RenderTexture Input; public RenderTexture Output; public Vector2 JitterOffset; public Vector2 MotionVectorScale; public Vector2Int RenderSize; public bool EnableSharpening; public float Sharpness; public float FrameTimeDelta; public float PreExposure; public bool Reset; public float CameraNear; public float CameraFar; public float CameraFovAngleVertical; } /// /// Creates a new FSR2 context with standard parameters that are appropriate for the current platform. /// public static Fsr2Context CreateContext(InitializationFlags flags = 0) { // flags |= InitializationFlags.EnableDepthInverted; // Depends on the runtime platform var contextDescription = new ContextDescription { Flags = flags, DisplaySize = new Vector2Int(Screen.width, Screen.height), Callbacks = GlobalCallbacks, }; var context = new Fsr2Context(); context.Create(contextDescription); return context; } public static float GetUpscaleRatioFromQualityMode(QualityMode qualityMode) { switch (qualityMode) { case QualityMode.Quality: return 1.5f; case QualityMode.Balanced: return 1.7f; case QualityMode.Performance: return 2.0f; case QualityMode.UltraPerformance: return 3.0f; default: return 1.0f; } } public static void GetRenderResolutionFromQualityMode( out uint renderWidth, out uint renderHeight, int displayWidth, int displayHeight, QualityMode qualityMode) { float ratio = GetUpscaleRatioFromQualityMode(qualityMode); renderWidth = (uint)(displayWidth / ratio); renderHeight = (uint)(displayHeight / ratio); } public static int GetJitterPhaseCount(int renderWidth, int displayWidth) { const float basePhaseCount = 8.0f; int jitterPhaseCount = (int)(basePhaseCount * Mathf.Pow((float)displayWidth / renderWidth, 2.0f)); return jitterPhaseCount; } public static void GetJitterOffset(out float outX, out float outY, int index, int phaseCount) { outX = Halton((index % phaseCount) + 1, 2) - 0.5f; outY = Halton((index % phaseCount) + 1, 3) - 0.5f; } // Calculate halton number for index and base. private static float Halton(int index, int @base) { float f = 1.0f, result = 0.0f; for (int currentIndex = index; currentIndex > 0;) { f /= @base; result += f * (currentIndex % @base); currentIndex = (int)Mathf.Floor((float)currentIndex / @base); } return result; } } }