VolumetricFogShaderOptions.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.IO;
  4. using System.Text;
  5. namespace VolumetricFogAndMist2 {
  6. public class VolumetricFogShaderOptions {
  7. const string SHADER_NAME = "VolumetricFog2/VolumetricFog2DURP";
  8. const string OPTIONS_SHADER_FILENAME = "CommonsURP.hlsl";
  9. const string OPTIONS_VOID_MANAGER_FILENAME = "VolumetricFogManager.cs";
  10. const string OPTIONS_FOG_SCRIPT_FILENAME = "VolumetricFog.cs";
  11. const string OPTIONS_FOG_EDITOR_SCRIPT_FILENAME = "VolumetricFogProfileEditor.cs";
  12. public bool pendingChanges;
  13. public ShaderAdvancedOption[] options;
  14. public void ReadOptions() {
  15. pendingChanges = false;
  16. // Populate known options
  17. options = new ShaderAdvancedOption[]
  18. {
  19. new ShaderAdvancedOption
  20. {
  21. id = "ORTHO_SUPPORT", name = "Orthographic Mode", description = "Enables support for orthographic camera projection."
  22. },
  23. new ShaderAdvancedOption
  24. {
  25. id = "USE_ALTERNATE_RECONSTRUCT_API",
  26. name = "Alternate WS Reconstruction",
  27. description = "Uses an alternate world space position reconstruction in XR."
  28. },
  29. new ShaderAdvancedOption
  30. {
  31. id = "FOG_BLUE_NOISE",
  32. name = "Blue Noise",
  33. description = "Uses blue noise based dithering/jittering."
  34. },
  35. new ShaderAdvancedOption
  36. {
  37. id = "USE_WORLD_SPACE_NOISE",
  38. name = "World Space Noise",
  39. description = "Uses world-space aligned noise (noise will change when fog volume position changes)."
  40. },
  41. new ShaderAdvancedOption
  42. {
  43. id = "WEBGL_COMPATIBILITY_MODE",
  44. name = "WebGL Compatibilty Mode",
  45. description = "Enable this option only if you're building for WebGL and notice rendering issues."
  46. },
  47. new ShaderAdvancedOption
  48. {
  49. id = "FOG_VOID_ROTATION",
  50. name = "Voids Rotation",
  51. description = "Enable this option to allow rotation of fog voids using the transform."
  52. },
  53. new ShaderAdvancedOption
  54. {
  55. id = "FOG_ROTATION",
  56. name = "Volume Rotation",
  57. description = "Enable this option to allow rotation of fog volumes using the transform."
  58. },
  59. new ShaderAdvancedOption
  60. {
  61. id = "FOG_BORDER",
  62. name = "Volume Border Option",
  63. description = "Enables the 'border' option in the profile which adds a falloff to the edges of the volume."
  64. },
  65. new ShaderAdvancedOption
  66. {
  67. id = "FOG_MAX_DISTANCE_XZ",
  68. name = "Max Distance on X/Z",
  69. description = "Ignores Y-axis when applying the max distance option."
  70. },
  71. new ShaderAdvancedOption
  72. {
  73. id = "FOG_SHADOW_CANCELLATION",
  74. name = "Shadow Fog Cancellation Option",
  75. description = "Enables the 'shadow cancellation' option in the profile which reduces the fog density or makes it invisible when in shadows."
  76. },
  77. new ShaderAdvancedOption
  78. {
  79. id = "V2F_LIGHT_COOKIE_CANCELLATION",
  80. name = "Cookie Fog Cancellation",
  81. description = "Changes fog transparency depending on the cookie color which acts as an alpha mask."
  82. },
  83. new ShaderAdvancedOption
  84. {
  85. id = "FOG_FORWARD_PLUS_IGNORE_CLUSTERING",
  86. name = "Ignore clustering in Forward+",
  87. description = "Parses all lights per pixel in Forward+, ignoring clustering (only available in Unity 2022/URP 14). In forward+, lights are grouped in clusters (screen partitions) to reduce the amount of lights computed per pixel. However, if there're few lights visible (less than 8), it may be faster to disable clustering by enabling this option."
  88. },
  89. new ShaderAdvancedOption
  90. {
  91. id = "FOG_FORWARD_PLUS_ADDITIONAL_DIRECTIONAL_LIGHTS",
  92. name = "Additional Directional Lights in Forward+",
  93. description = "Supports extra directional lights in Forward+. By default, this option is disabled to improve performance."
  94. },
  95. new ShaderAdvancedOption
  96. {
  97. id = "MAX_ITERATIONS",
  98. name = "",
  99. description = "",
  100. hasValue = true
  101. }
  102. };
  103. Shader shader = Shader.Find(SHADER_NAME);
  104. if (shader != null) {
  105. string path = AssetDatabase.GetAssetPath(shader);
  106. string file = Path.GetDirectoryName(path) + "/" + OPTIONS_SHADER_FILENAME;
  107. string[] lines = File.ReadAllLines(file, Encoding.UTF8);
  108. for (int k = 0; k < lines.Length; k++) {
  109. for (int o = 0; o < options.Length; o++) {
  110. if (lines[k].Contains("#define " + options[o].id)) {
  111. options[o].enabled = !lines[k].StartsWith("//");
  112. if (options[o].hasValue) {
  113. string[] tokens = lines[k].Split(null);
  114. if (tokens.Length > 2) {
  115. int.TryParse(tokens[2], out options[o].value);
  116. }
  117. }
  118. break;
  119. }
  120. }
  121. }
  122. }
  123. }
  124. public bool GetAdvancedOptionState(string optionId) {
  125. if (options == null)
  126. return false;
  127. for (int k = 0; k < options.Length; k++) {
  128. if (options[k].id.Equals(optionId)) {
  129. return options[k].enabled;
  130. }
  131. }
  132. return false;
  133. }
  134. public void UpdateAdvancedOptionsFile() {
  135. // Reloads the file and updates it accordingly
  136. Shader shader = Shader.Find(SHADER_NAME);
  137. if (shader != null) {
  138. string path = AssetDatabase.GetAssetPath(shader);
  139. // update shader options
  140. string file = Path.GetDirectoryName(path) + "/" + OPTIONS_SHADER_FILENAME;
  141. UpdateOptionsFile(file);
  142. // update void manager options
  143. file = Path.GetDirectoryName(path) + "/../../Scripts/Managers/" + OPTIONS_VOID_MANAGER_FILENAME;
  144. UpdateOptionsFile(file);
  145. // update main fog script options
  146. file = Path.GetDirectoryName(path) + "/../../Scripts/" + OPTIONS_FOG_SCRIPT_FILENAME;
  147. UpdateOptionsFile(file);
  148. // update editor script options
  149. file = Path.GetDirectoryName(path) + "/../../Editor/" + OPTIONS_FOG_EDITOR_SCRIPT_FILENAME;
  150. UpdateOptionsFile(file);
  151. }
  152. pendingChanges = false;
  153. AssetDatabase.Refresh();
  154. }
  155. void UpdateOptionsFile(string file) {
  156. string[] lines = File.ReadAllLines(file, Encoding.UTF8);
  157. for (int k = 0; k < lines.Length; k++) {
  158. for (int o = 0; o < options.Length; o++) {
  159. string token = "#define " + options[o].id;
  160. if (lines[k].Contains(token)) {
  161. if (options[o].hasValue) {
  162. lines[k] = token + " " + options[o].value;
  163. } else {
  164. if (options[o].enabled) {
  165. lines[k] = token;
  166. } else {
  167. lines[k] = "//#define " + options[o].id;
  168. }
  169. }
  170. break;
  171. }
  172. }
  173. }
  174. File.WriteAllLines(file, lines, Encoding.UTF8);
  175. }
  176. public int GetOptionValue(string id) {
  177. for (int k = 0; k < options.Length; k++) {
  178. if (options[k].hasValue && options[k].id.Equals(id)) {
  179. return options[k].value;
  180. }
  181. }
  182. return 0;
  183. }
  184. public void SetOptionValue(string id, int value) {
  185. for (int k = 0; k < options.Length; k++) {
  186. if (options[k].hasValue && options[k].id.Equals(id)) {
  187. options[k].value = value;
  188. }
  189. }
  190. }
  191. }
  192. public struct ShaderAdvancedOption {
  193. public string id;
  194. public string name;
  195. public string description;
  196. public bool enabled;
  197. public bool hasValue;
  198. public int value;
  199. }
  200. }