No Description
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.

MaterialQuality.cs 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System;
  2. using UnityEngine.Scripting.APIUpdating;
  3. namespace UnityEngine.Rendering
  4. {
  5. /// <summary>
  6. /// Material quality flags.
  7. /// </summary>
  8. [Flags]
  9. [MovedFrom("Utilities")]
  10. public enum MaterialQuality
  11. {
  12. /// <summary>Low Material Quality.</summary>
  13. Low = 1 << 0,
  14. /// <summary>Medium Material Quality.</summary>
  15. Medium = 1 << 1,
  16. /// <summary>High Material Quality.</summary>
  17. High = 1 << 2
  18. }
  19. /// <summary>
  20. /// Material Quality utility class.
  21. /// </summary>
  22. [MovedFrom("Utilities")]
  23. public static class MaterialQualityUtilities
  24. {
  25. /// <summary>
  26. /// Keywords strings for Material Quality levels.
  27. /// </summary>
  28. public static string[] KeywordNames =
  29. {
  30. "MATERIAL_QUALITY_LOW",
  31. "MATERIAL_QUALITY_MEDIUM",
  32. "MATERIAL_QUALITY_HIGH",
  33. };
  34. /// <summary>
  35. /// String representation of the MaterialQuality enum.
  36. /// </summary>
  37. public static string[] EnumNames = Enum.GetNames(typeof(MaterialQuality));
  38. /// <summary>
  39. /// Keywords for Material Quality levels.
  40. /// </summary>
  41. public static ShaderKeyword[] Keywords =
  42. {
  43. new ShaderKeyword(KeywordNames[0]),
  44. new ShaderKeyword(KeywordNames[1]),
  45. new ShaderKeyword(KeywordNames[2]),
  46. };
  47. /// <summary>
  48. /// Returns the highest available quality level in a MaterialQuality bitfield.
  49. /// </summary>
  50. /// <param name="levels">Input MaterialQuality bitfield.</param>
  51. /// <returns>The highest available quality level.</returns>
  52. public static MaterialQuality GetHighestQuality(this MaterialQuality levels)
  53. {
  54. for (var i = Keywords.Length - 1; i >= 0; --i)
  55. {
  56. var level = (MaterialQuality)(1 << i);
  57. if ((levels & level) != 0)
  58. return level;
  59. }
  60. return 0;
  61. }
  62. /// <summary>
  63. /// Returns the closest available quality level in a MaterialQuality bitfield.
  64. /// </summary>
  65. /// <param name="availableLevels">Available MaterialQuality bitfield.</param>
  66. /// <param name="requestedLevel">Input MaterialQuality level.</param>
  67. /// <returns>The closest available quality level.</returns>
  68. public static MaterialQuality GetClosestQuality(this MaterialQuality availableLevels, MaterialQuality requestedLevel)
  69. {
  70. // Special fallback when there are no available quality levels. Needs to match in the shader stripping code
  71. if (availableLevels == 0)
  72. return MaterialQuality.Low;
  73. // First we want to find the closest available quality level below the requested one.
  74. int requestedLevelIndex = ToFirstIndex(requestedLevel);
  75. MaterialQuality chosenQuality = (MaterialQuality)0;
  76. for (int i = requestedLevelIndex; i >= 0; --i)
  77. {
  78. var level = FromIndex(i);
  79. if ((level & availableLevels) != 0)
  80. {
  81. chosenQuality = level;
  82. break;
  83. }
  84. }
  85. if (chosenQuality != 0)
  86. return chosenQuality;
  87. // If none is found then we fallback to the closest above.
  88. for (var i = requestedLevelIndex + 1; i < Keywords.Length; ++i)
  89. {
  90. var level = FromIndex(i);
  91. var diff = Math.Abs(requestedLevel - level);
  92. if ((level & availableLevels) != 0)
  93. {
  94. chosenQuality = level;
  95. break;
  96. }
  97. }
  98. Debug.Assert(chosenQuality != 0);
  99. return chosenQuality;
  100. }
  101. /// <summary>
  102. /// Set the global keyword for the provided MaterialQuality.
  103. /// </summary>
  104. /// <param name="level">MaterialQuality level to set the keyword for.</param>
  105. public static void SetGlobalShaderKeywords(this MaterialQuality level)
  106. {
  107. for (var i = 0; i < KeywordNames.Length; ++i)
  108. {
  109. if ((level & (MaterialQuality)(1 << i)) != 0)
  110. Shader.EnableKeyword(KeywordNames[i]);
  111. else
  112. Shader.DisableKeyword(KeywordNames[i]);
  113. }
  114. }
  115. /// <summary>
  116. /// Set the global keyword for the provided MaterialQuality.
  117. /// </summary>
  118. /// <param name="level">MaterialQuality level to set the keyword for.</param>
  119. /// <param name="cmd">Command Buffer used to setup the keyword.</param>
  120. public static void SetGlobalShaderKeywords(this MaterialQuality level, CommandBuffer cmd)
  121. {
  122. for (var i = 0; i < KeywordNames.Length; ++i)
  123. {
  124. if ((level & (MaterialQuality)(1 << i)) != 0)
  125. cmd.EnableShaderKeyword(KeywordNames[i]);
  126. else
  127. cmd.DisableShaderKeyword(KeywordNames[i]);
  128. }
  129. }
  130. /// <summary>
  131. /// Returns the index (in the MaterialQuality enum) of the first available level.
  132. /// </summary>
  133. /// <param name="level">MaterialQuality bitfield.</param>
  134. /// <returns>The index of the first available level.</returns>
  135. public static int ToFirstIndex(this MaterialQuality level)
  136. {
  137. for (var i = 0; i < KeywordNames.Length; ++i)
  138. {
  139. if ((level & (MaterialQuality)(1 << i)) != 0)
  140. return i;
  141. }
  142. return -1;
  143. }
  144. /// <summary>
  145. /// Returns the enum equivalent of the index in the MaterialQuality enum list.
  146. /// </summary>
  147. /// <param name="index">Index of the material quality.</param>
  148. /// <returns>The equivalent enum.</returns>
  149. public static MaterialQuality FromIndex(int index) => (MaterialQuality)(1 << index);
  150. }
  151. }