SerializedPass.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace EPOOutline
  6. {
  7. public class SerializedPassInfoAttribute : Attribute
  8. {
  9. public readonly string Title;
  10. public readonly string ShadersFolder;
  11. public SerializedPassInfoAttribute(string title, string shadersFolder)
  12. {
  13. Title = title;
  14. ShadersFolder = shadersFolder;
  15. }
  16. }
  17. [System.Serializable]
  18. public class SerializedPass : ISerializationCallbackReceiver
  19. {
  20. public enum PropertyType
  21. {
  22. Color = 0,
  23. Vector = 1,
  24. Float = 2,
  25. Range = 3,
  26. TexEnv = 4
  27. }
  28. [System.Serializable]
  29. private class SerializedPropertyKeyValuePair
  30. {
  31. [SerializeField]
  32. public string PropertyName;
  33. [SerializeField]
  34. public SerializedPassProperty Property;
  35. }
  36. [System.Serializable]
  37. private class SerializedPassProperty
  38. {
  39. #pragma warning disable CS0649
  40. [SerializeField]
  41. public Color ColorValue;
  42. [SerializeField]
  43. public float FloatValue;
  44. [SerializeField]
  45. public Vector4 VectorValue;
  46. [SerializeField]
  47. public PropertyType PropertyType;
  48. #pragma warning restore CS0649
  49. }
  50. [SerializeField]
  51. private Shader shader;
  52. public Shader Shader
  53. {
  54. get
  55. {
  56. return shader;
  57. }
  58. set
  59. {
  60. propertiesIsDirty = true;
  61. shader = value;
  62. }
  63. }
  64. [SerializeField]
  65. private List<SerializedPropertyKeyValuePair> serializedProperties = new List<SerializedPropertyKeyValuePair>();
  66. private Dictionary<int, SerializedPassProperty> propertiesById = new Dictionary<int, SerializedPassProperty>();
  67. private Dictionary<string, SerializedPassProperty> propertiesByName = new Dictionary<string, SerializedPassProperty>();
  68. private Material material;
  69. private bool propertiesIsDirty = false;
  70. public Material Material
  71. {
  72. get
  73. {
  74. if (shader == null)
  75. return null;
  76. if (material == null || material.shader != shader)
  77. {
  78. if (material != null)
  79. GameObject.DestroyImmediate(material);
  80. material = new Material(shader);
  81. }
  82. if (!propertiesIsDirty)
  83. return material;
  84. foreach (var property in propertiesById)
  85. {
  86. switch (property.Value.PropertyType)
  87. {
  88. case PropertyType.Color:
  89. material.SetColor(property.Key, property.Value.ColorValue);
  90. break;
  91. case PropertyType.Vector:
  92. material.SetVector(property.Key, property.Value.VectorValue);
  93. break;
  94. case PropertyType.Float:
  95. material.SetFloat(property.Key, property.Value.FloatValue);
  96. break;
  97. case PropertyType.Range:
  98. material.SetFloat(property.Key, property.Value.FloatValue);
  99. break;
  100. case PropertyType.TexEnv:
  101. break;
  102. }
  103. }
  104. propertiesIsDirty = false;
  105. return material;
  106. }
  107. }
  108. public bool HasProperty(string name)
  109. {
  110. return propertiesByName.ContainsKey(name);
  111. }
  112. public bool HasProperty(int hash)
  113. {
  114. return propertiesById.ContainsKey(hash);
  115. }
  116. public Vector4 GetVector(string name)
  117. {
  118. SerializedPassProperty result = null;
  119. if (!propertiesByName.TryGetValue(name, out result))
  120. {
  121. Debug.LogError("The property " + name + " doesn't exist");
  122. return Vector4.zero;
  123. }
  124. if (result.PropertyType == PropertyType.Vector)
  125. return result.VectorValue;
  126. else
  127. {
  128. Debug.LogError("The property " + name + " is not a vector property");
  129. return Vector4.zero;
  130. }
  131. }
  132. public Vector4 GetVector(int hash)
  133. {
  134. SerializedPassProperty result = null;
  135. if (!propertiesById.TryGetValue(hash, out result))
  136. {
  137. Debug.LogError("The property " + hash + " doesn't exist");
  138. return Vector4.zero;
  139. }
  140. if (result.PropertyType == PropertyType.Vector)
  141. return result.VectorValue;
  142. else
  143. {
  144. Debug.LogError("The property " + hash + " is not a vector property");
  145. return Vector4.zero;
  146. }
  147. }
  148. public void SetVector(string name, Vector4 value)
  149. {
  150. propertiesIsDirty = true;
  151. SerializedPassProperty result = null;
  152. if (!propertiesByName.TryGetValue(name, out result))
  153. {
  154. result = new SerializedPassProperty();
  155. result.PropertyType = PropertyType.Vector;
  156. propertiesByName.Add(name, result);
  157. propertiesById.Add(Shader.PropertyToID(name), result);
  158. }
  159. if (result.PropertyType != PropertyType.Vector)
  160. {
  161. Debug.LogError("The property " + name + " is not a vector property");
  162. return;
  163. }
  164. result.VectorValue = value;
  165. }
  166. public void SetVector(int hash, Vector4 value)
  167. {
  168. propertiesIsDirty = true;
  169. SerializedPassProperty result = null;
  170. if (!propertiesById.TryGetValue(hash, out result))
  171. {
  172. Debug.LogWarning("The property " + hash + " doesn't exist. Use string overload to create one.");
  173. return;
  174. }
  175. if (result.PropertyType != PropertyType.Vector)
  176. {
  177. Debug.LogError("The property " + hash + " is not a vector property");
  178. return;
  179. }
  180. result.VectorValue = value;
  181. }
  182. public float GetFloat(string name)
  183. {
  184. SerializedPassProperty result = null;
  185. if (!propertiesByName.TryGetValue(name, out result))
  186. {
  187. Debug.LogError("The property " + name + " doesn't exist");
  188. return 0.0f;
  189. }
  190. if (result.PropertyType == PropertyType.Float || result.PropertyType == PropertyType.Range)
  191. return result.FloatValue;
  192. else
  193. {
  194. Debug.LogError("The property " + name + " is not a float property");
  195. return 0.0f;
  196. }
  197. }
  198. public float GetFloat(int hash)
  199. {
  200. SerializedPassProperty result = null;
  201. if (!propertiesById.TryGetValue(hash, out result))
  202. {
  203. Debug.LogError("The property " + hash + " is doesn't exist");
  204. return 0.0f;
  205. }
  206. if (result.PropertyType == PropertyType.Float || result.PropertyType == PropertyType.Range)
  207. return result.FloatValue;
  208. else
  209. {
  210. Debug.LogError("The property " + hash + " is not a float property");
  211. return 0.0f;
  212. }
  213. }
  214. public void SetFloat(string name, float value)
  215. {
  216. propertiesIsDirty = true;
  217. SerializedPassProperty result = null;
  218. if (!propertiesByName.TryGetValue(name, out result))
  219. {
  220. result = new SerializedPassProperty();
  221. result.PropertyType = PropertyType.Float;
  222. propertiesByName.Add(name, result);
  223. propertiesById.Add(Shader.PropertyToID(name), result);
  224. }
  225. if (result.PropertyType != PropertyType.Float && result.PropertyType != PropertyType.Range)
  226. {
  227. Debug.LogError("The property " + name + " is not a float property");
  228. return;
  229. }
  230. result.FloatValue = value;
  231. }
  232. public void SetFloat(int hash, float value)
  233. {
  234. propertiesIsDirty = true;
  235. SerializedPassProperty result = null;
  236. if (!propertiesById.TryGetValue(hash, out result))
  237. {
  238. Debug.LogError("The property " + hash + " doesn't exist. Use string overload to create one.");
  239. return;
  240. }
  241. if (result.PropertyType != PropertyType.Float)
  242. {
  243. Debug.LogError("The property " + hash + " is not a float property");
  244. return;
  245. }
  246. result.FloatValue = value;
  247. }
  248. public Color GetColor(string name)
  249. {
  250. SerializedPassProperty result = null;
  251. if (!propertiesByName.TryGetValue(name, out result))
  252. {
  253. Debug.LogError("The property " + name + " doesn't exist");
  254. return Color.black;
  255. }
  256. if (result.PropertyType == PropertyType.Color)
  257. return result.ColorValue;
  258. else
  259. {
  260. Debug.LogError("The property " + name + " is not a color property");
  261. return Color.black;
  262. }
  263. }
  264. public Color GetColor(int hash)
  265. {
  266. SerializedPassProperty result = null;
  267. if (!propertiesById.TryGetValue(hash, out result))
  268. {
  269. Debug.LogError("The property " + hash + " doesn't exist");
  270. return Color.black;
  271. }
  272. if (result.PropertyType == PropertyType.Color)
  273. return result.ColorValue;
  274. else
  275. return Color.black;
  276. }
  277. public void SetColor(string name, Color value)
  278. {
  279. propertiesIsDirty = true;
  280. SerializedPassProperty result = null;
  281. if (!propertiesByName.TryGetValue(name, out result))
  282. {
  283. result = new SerializedPassProperty();
  284. result.PropertyType = PropertyType.Color;
  285. propertiesByName.Add(name, result);
  286. propertiesById.Add(Shader.PropertyToID(name), result);
  287. }
  288. if (result.PropertyType != PropertyType.Color)
  289. {
  290. Debug.LogError("The property " + name + " is not a color property.");
  291. return;
  292. }
  293. result.ColorValue = value;
  294. }
  295. public void SetColor(int hash, Color value)
  296. {
  297. propertiesIsDirty = true;
  298. SerializedPassProperty result = null;
  299. if (!propertiesById.TryGetValue(hash, out result))
  300. {
  301. Debug.LogError("The property " + hash + " doesn't exist. Use string overload to create one.");
  302. return;
  303. }
  304. if (result.PropertyType != PropertyType.Color)
  305. {
  306. Debug.LogError("The property " + hash + " is not a color property");
  307. return;
  308. }
  309. result.ColorValue = value;
  310. }
  311. public void OnBeforeSerialize()
  312. {
  313. serializedProperties.Clear();
  314. foreach (var property in propertiesByName)
  315. {
  316. var pair = new SerializedPropertyKeyValuePair();
  317. pair.Property = property.Value;
  318. pair.PropertyName = property.Key;
  319. serializedProperties.Add(pair);
  320. }
  321. }
  322. public void OnAfterDeserialize()
  323. {
  324. propertiesIsDirty = true;
  325. propertiesById.Clear();
  326. propertiesByName.Clear();
  327. foreach (var serialized in serializedProperties)
  328. {
  329. if (propertiesByName.ContainsKey(serialized.PropertyName))
  330. continue;
  331. propertiesById.Add(Shader.PropertyToID(serialized.PropertyName), serialized.Property);
  332. propertiesByName.Add(serialized.PropertyName, serialized.Property);
  333. }
  334. }
  335. }
  336. }