A game about forced loneliness, made by TACStudios
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}