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