暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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