A game about forced loneliness, made by TACStudios
1using System; 2using Unity.Collections; 3using UnityEngine.Experimental.Rendering; 4 5namespace UnityEngine.Rendering 6{ 7 /// <summary> 8 /// Utility functions relating to FidelityFX Super Resolution (FSR) 9 /// 10 /// These functions are expected to be used in conjuction with the helper functions provided by FSRCommon.hlsl. 11 /// </summary> 12 public static class FSRUtils 13 { 14 /// Shader constant ids used to communicate with the FSR shader implementation 15 static class ShaderConstants 16 { 17 // EASU 18 public static readonly int _FsrEasuConstants0 = Shader.PropertyToID("_FsrEasuConstants0"); 19 public static readonly int _FsrEasuConstants1 = Shader.PropertyToID("_FsrEasuConstants1"); 20 public static readonly int _FsrEasuConstants2 = Shader.PropertyToID("_FsrEasuConstants2"); 21 public static readonly int _FsrEasuConstants3 = Shader.PropertyToID("_FsrEasuConstants3"); 22 23 // RCAS 24 public static readonly int _FsrRcasConstants = Shader.PropertyToID("_FsrRcasConstants"); 25 } 26 27 /// <summary> 28 /// Sets the constant values required by the FSR EASU shader on the provided command buffer 29 /// 30 /// Logic ported from "FsrEasuCon()" in Runtime/PostProcessing/Shaders/ffx/ffx_fsr1.hlsl 31 /// </summary> 32 /// <param name="cmd">Command buffer to modify</param> 33 /// <param name="inputViewportSizeInPixels">This the rendered image resolution being upscaled</param> 34 /// <param name="inputImageSizeInPixels">This is the resolution of the resource containing the input image (useful for dynamic resolution)</param> 35 /// <param name="outputImageSizeInPixels">This is the display resolution which the input image gets upscaled to</param> 36 public static void SetEasuConstants(CommandBuffer cmd, Vector2 inputViewportSizeInPixels, Vector2 inputImageSizeInPixels, Vector2 outputImageSizeInPixels) 37 { 38 Vector4 constants0; 39 Vector4 constants1; 40 Vector4 constants2; 41 Vector4 constants3; 42 43 // Output integer position to a pixel position in viewport. 44 constants0.x = (inputViewportSizeInPixels.x / outputImageSizeInPixels.x); 45 constants0.y = (inputViewportSizeInPixels.y / outputImageSizeInPixels.y); 46 constants0.z = (0.5f * inputViewportSizeInPixels.x / outputImageSizeInPixels.x - 0.5f); 47 constants0.w = (0.5f * inputViewportSizeInPixels.y / outputImageSizeInPixels.y - 0.5f); 48 49 // Viewport pixel position to normalized image space. 50 // This is used to get upper-left of 'F' tap. 51 constants1.x = (1.0f / inputImageSizeInPixels.x); 52 constants1.y = (1.0f / inputImageSizeInPixels.y); 53 54 // Centers of gather4, first offset from upper-left of 'F'. 55 // +---+---+ 56 // | | | 57 // +--(0)--+ 58 // | b | c | 59 // +---F---+---+---+ 60 // | e | f | g | h | 61 // +--(1)--+--(2)--+ 62 // | i | j | k | l | 63 // +---+---+---+---+ 64 // | n | o | 65 // +--(3)--+ 66 // | | | 67 // +---+---+ 68 constants1.z = (1.0f / inputImageSizeInPixels.x); 69 constants1.w = (-1.0f / inputImageSizeInPixels.y); 70 71 // These are from (0) instead of 'F'. 72 constants2.x = (-1.0f / inputImageSizeInPixels.x); 73 constants2.y = (2.0f / inputImageSizeInPixels.y); 74 constants2.z = (1.0f / inputImageSizeInPixels.x); 75 constants2.w = (2.0f / inputImageSizeInPixels.y); 76 77 constants3.x = (0.0f / inputImageSizeInPixels.x); 78 constants3.y = (4.0f / inputImageSizeInPixels.y); 79 80 // Fill the last constant with zeros to avoid using uninitialized memory 81 constants3.z = 0.0f; 82 constants3.w = 0.0f; 83 84 cmd.SetGlobalVector(ShaderConstants._FsrEasuConstants0, constants0); 85 cmd.SetGlobalVector(ShaderConstants._FsrEasuConstants1, constants1); 86 cmd.SetGlobalVector(ShaderConstants._FsrEasuConstants2, constants2); 87 cmd.SetGlobalVector(ShaderConstants._FsrEasuConstants3, constants3); 88 } 89 90 /// <summary> 91 /// Sets the constant values required by the FSR EASU shader on the provided command buffer 92 /// 93 /// Logic ported from "FsrEasuCon()" in Runtime/PostProcessing/Shaders/ffx/ffx_fsr1.hlsl 94 /// </summary> 95 /// <param name="cmd">RasterCommandBuffer/ComputeCommandBuffer/UnsafeCommandBuffer to modify</param> 96 /// <param name="inputViewportSizeInPixels">This the rendered image resolution being upscaled</param> 97 /// <param name="inputImageSizeInPixels">This is the resolution of the resource containing the input image (useful for dynamic resolution)</param> 98 /// <param name="outputImageSizeInPixels">This is the display resolution which the input image gets upscaled to</param> 99 public static void SetEasuConstants(BaseCommandBuffer cmd, Vector2 inputViewportSizeInPixels, 100 Vector2 inputImageSizeInPixels, Vector2 outputImageSizeInPixels) 101 { 102 SetEasuConstants(cmd.m_WrappedCommandBuffer, inputViewportSizeInPixels, inputImageSizeInPixels, outputImageSizeInPixels); 103 } 104 105 /// <summary> 106 /// The maximum sharpness value in stops before the effect of RCAS is no longer visible. 107 /// This value is used to map between linear and stops. 108 /// </summary> 109 internal const float kMaxSharpnessStops = 2.5f; 110 111 /// <summary> 112 /// AMD's FidelityFX Super Resolution integration guide recommends a value of 0.2 for the RCAS sharpness parameter when specified in stops 113 /// </summary> 114 public const float kDefaultSharpnessStops = 0.2f; 115 116 /// <summary> 117 /// The default RCAS sharpness parameter as a linear value 118 /// </summary> 119 public const float kDefaultSharpnessLinear = (1.0f - (kDefaultSharpnessStops / kMaxSharpnessStops)); 120 121 /// <summary> 122 /// Sets the constant values required by the FSR RCAS shader on the provided command buffer 123 /// 124 /// Logic ported from "FsrRcasCon()" in Runtime/PostProcessing/Shaders/ffx/ffx_fsr1.hlsl 125 /// For a more user-friendly version of this function, see SetRcasConstantsLinear(). 126 /// </summary> 127 /// <param name="cmd">Command buffer to modify</param> 128 /// <param name="sharpnessStops">The scale is {0.0 := maximum, to N>0, where N is the number of stops(halving) of the reduction of sharpness</param> 129 public static void SetRcasConstants(CommandBuffer cmd, float sharpnessStops = kDefaultSharpnessStops) 130 { 131 // Transform from stops to linear value. 132 float sharpnessLinear = Mathf.Pow(2.0f, -sharpnessStops); 133 134 Vector4 constants; 135 136 uint sharpnessAsHalf = Mathf.FloatToHalf(sharpnessLinear); 137 int packedSharpness = (int)(sharpnessAsHalf | (sharpnessAsHalf << 16)); 138 float packedSharpnessAsFloat = BitConverter.Int32BitsToSingle(packedSharpness); 139 140 constants.x = sharpnessLinear; 141 constants.y = packedSharpnessAsFloat; 142 143 // Fill the last constant with zeros to avoid using uninitialized memory 144 constants.z = 0.0f; 145 constants.w = 0.0f; 146 147 cmd.SetGlobalVector(ShaderConstants._FsrRcasConstants, constants); 148 } 149 150 /// <summary> 151 /// Sets the constant values required by the FSR RCAS shader on the provided command buffer 152 /// 153 /// Equivalent to SetRcasConstants(), but handles the sharpness parameter as a linear value instead of one specified in stops. 154 /// This is intended to simplify code that allows users to configure the sharpening behavior from a GUI. 155 /// </summary> 156 /// <param name="cmd">Command buffer to modify</param> 157 /// <param name="sharpnessLinear">The level of intensity of the sharpening filter where 0.0 is the least sharp and 1.0 is the most sharp</param> 158 public static void SetRcasConstantsLinear(CommandBuffer cmd, float sharpnessLinear = kDefaultSharpnessLinear) 159 { 160 // Ensure that the input value is between 0.0 and 1.0 prevent incorrect results 161 Assertions.Assert.IsTrue((sharpnessLinear >= 0.0f) && (sharpnessLinear <= 1.0f)); 162 163 float sharpnessStops = (1.0f - sharpnessLinear) * kMaxSharpnessStops; 164 165 SetRcasConstants(cmd, sharpnessStops); 166 } 167 168 /// <summary> 169 /// Sets the constant values required by the FSR RCAS shader on the provided command buffer 170 /// 171 /// Equivalent to SetRcasConstants(), but handles the sharpness parameter as a linear value instead of one specified in stops. 172 /// This is intended to simplify code that allows users to configure the sharpening behavior from a GUI. 173 /// </summary> 174 /// <param name="cmd">RasterCommandBuffer to modify</param> 175 /// <param name="sharpnessLinear">The level of intensity of the sharpening filter where 0.0 is the least sharp and 1.0 is the most sharp</param> 176 public static void SetRcasConstantsLinear(RasterCommandBuffer cmd, float sharpnessLinear = kDefaultSharpnessLinear) 177 { 178 SetRcasConstantsLinear(cmd.m_WrappedCommandBuffer, sharpnessLinear); 179 } 180 181 /// <summary> 182 /// Returns true if FidelityFX Super Resolution (FSR) is supported on the current system 183 /// FSR requires the textureGather shader instruction which wasn't supported by OpenGL ES until version 3.1 184 /// </summary> 185 /// <returns>True if supported</returns> 186 public static bool IsSupported() 187 { 188 return SystemInfo.graphicsShaderLevel >= 45; 189 } 190 } 191}