TemplatesManager.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Collections.Concurrent;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text.RegularExpressions;
  9. using System.Threading.Tasks;
  10. using UnityEditor;
  11. using UnityEngine;
  12. namespace AmplifyShaderEditor
  13. {
  14. [Serializable]
  15. public class TemplateInputData
  16. {
  17. public string PortName;
  18. public WirePortDataType DataType;
  19. public MasterNodePortCategory PortCategory;
  20. public int PortUniqueId;
  21. public int OrderId;
  22. public int TagGlobalStartIdx;
  23. public int TagLocalStartIdx;
  24. public string TagId;
  25. public string DefaultValue;
  26. public string LinkId;
  27. public TemplateInputData( int tagLocalStartIdx, int tagGlobalStartIdx, string tagId, string portName, string defaultValue, WirePortDataType dataType, MasterNodePortCategory portCategory, int portUniqueId, int orderId, string linkId )
  28. {
  29. DefaultValue = defaultValue;
  30. PortName = portName;
  31. DataType = dataType;
  32. PortCategory = portCategory;
  33. PortUniqueId = portUniqueId;
  34. OrderId = orderId;
  35. TagId = tagId;
  36. TagGlobalStartIdx = tagGlobalStartIdx;
  37. TagLocalStartIdx = tagLocalStartIdx;
  38. LinkId = linkId;
  39. }
  40. public TemplateInputData( TemplateInputData other )
  41. {
  42. DefaultValue = other.DefaultValue;
  43. PortName = other.PortName;
  44. DataType = other.DataType;
  45. PortCategory = other.PortCategory;
  46. PortUniqueId = other.PortUniqueId;
  47. OrderId = other.OrderId;
  48. TagId = other.TagId;
  49. TagGlobalStartIdx = other.TagGlobalStartIdx;
  50. LinkId = other.LinkId;
  51. }
  52. }
  53. [Serializable]
  54. public class TemplatePropertyContainer
  55. {
  56. [SerializeField]
  57. private List<TemplateProperty> m_propertyList = new List<TemplateProperty>();
  58. private Dictionary<string, TemplateProperty> m_propertyDict = new Dictionary<string, TemplateProperty>();
  59. public void AddId( TemplateProperty templateProperty )
  60. {
  61. BuildInfo();
  62. m_propertyList.Add( templateProperty );
  63. m_propertyDict.Add( templateProperty.Id, templateProperty );
  64. }
  65. public void AddId( string body, string ID, bool searchIndentation = true )
  66. {
  67. AddId( body, ID, searchIndentation, string.Empty );
  68. }
  69. public void AddId( string body, string ID, bool searchIndentation, string customIndentation )
  70. {
  71. BuildInfo();
  72. int propertyIndex = body.IndexOf( ID );
  73. if( propertyIndex > -1 )
  74. {
  75. if( searchIndentation )
  76. {
  77. int identationIndex = -1;
  78. for( int i = propertyIndex; i >= 0; i-- )
  79. {
  80. if( body[ i ] == TemplatesManager.TemplateNewLine )
  81. {
  82. identationIndex = i + 1;
  83. break;
  84. }
  85. if( i == 0 )
  86. {
  87. identationIndex = 0;
  88. }
  89. }
  90. if( identationIndex > -1 )
  91. {
  92. int length = propertyIndex - identationIndex;
  93. string indentation = ( length > 0 ) ? body.Substring( identationIndex, length ) : string.Empty;
  94. TemplateProperty templateProperty = new TemplateProperty( ID, indentation, false );
  95. m_propertyList.Add( templateProperty );
  96. m_propertyDict.Add( templateProperty.Id, templateProperty );
  97. }
  98. else
  99. {
  100. TemplateProperty templateProperty = new TemplateProperty( ID, string.Empty, false );
  101. m_propertyList.Add( templateProperty );
  102. m_propertyDict.Add( templateProperty.Id, templateProperty );
  103. }
  104. }
  105. else
  106. {
  107. TemplateProperty templateProperty = new TemplateProperty( ID, customIndentation, true );
  108. m_propertyList.Add( templateProperty );
  109. m_propertyDict.Add( templateProperty.Id, templateProperty );
  110. }
  111. }
  112. }
  113. public void AddId( string body, string ID, int propertyIndex, bool searchIndentation )
  114. {
  115. AddId( body, ID, propertyIndex, searchIndentation, string.Empty );
  116. }
  117. public void AddId( string body, string ID, int propertyIndex, bool searchIndentation, string customIndentation )
  118. {
  119. if( body == null || string.IsNullOrEmpty( body ) )
  120. return;
  121. BuildInfo();
  122. if( searchIndentation && propertyIndex > -1 && propertyIndex < body.Length )
  123. {
  124. int indentationIndex = -1;
  125. for( int i = propertyIndex; i > 0; i-- )
  126. {
  127. if( body[ i ] == TemplatesManager.TemplateNewLine )
  128. {
  129. indentationIndex = i + 1;
  130. break;
  131. }
  132. }
  133. if( indentationIndex > -1 )
  134. {
  135. int length = propertyIndex - indentationIndex;
  136. string indentation = ( length > 0 ) ? body.Substring( indentationIndex, length ) : string.Empty;
  137. TemplateProperty templateProperty = new TemplateProperty( ID, indentation, false );
  138. m_propertyList.Add( templateProperty );
  139. m_propertyDict.Add( templateProperty.Id, templateProperty );
  140. }
  141. }
  142. else
  143. {
  144. TemplateProperty templateProperty = new TemplateProperty( ID, customIndentation, true );
  145. m_propertyList.Add( templateProperty );
  146. m_propertyDict.Add( templateProperty.Id, templateProperty );
  147. }
  148. }
  149. public void BuildInfo()
  150. {
  151. if( m_propertyDict == null )
  152. {
  153. m_propertyDict = new Dictionary<string, TemplateProperty>();
  154. }
  155. if( m_propertyList.Count != m_propertyDict.Count )
  156. {
  157. m_propertyDict.Clear();
  158. for( int i = 0; i < m_propertyList.Count; i++ )
  159. {
  160. m_propertyDict.Add( m_propertyList[ i ].Id, m_propertyList[ i ] );
  161. }
  162. }
  163. }
  164. public void ResetTemplateUsageData()
  165. {
  166. BuildInfo();
  167. for( int i = 0; i < m_propertyList.Count; i++ )
  168. {
  169. m_propertyList[ i ].Used = false;
  170. }
  171. }
  172. public void Reset()
  173. {
  174. m_propertyList.Clear();
  175. m_propertyDict.Clear();
  176. }
  177. public void Destroy()
  178. {
  179. m_propertyList.Clear();
  180. m_propertyList = null;
  181. m_propertyDict.Clear();
  182. m_propertyDict = null;
  183. }
  184. public Dictionary<string, TemplateProperty> PropertyDict
  185. {
  186. get
  187. {
  188. BuildInfo();
  189. return m_propertyDict;
  190. }
  191. }
  192. public List<TemplateProperty> PropertyList { get { return m_propertyList; } }
  193. }
  194. [Serializable]
  195. public class TemplateProperty
  196. {
  197. public bool UseIndentationAtStart = false;
  198. public string Indentation;
  199. public bool UseCustomIndentation;
  200. public string Id;
  201. public bool AutoLineFeed;
  202. public bool Used;
  203. public TemplateProperty( string id, string indentation, bool useCustomIndentation )
  204. {
  205. Id = id;
  206. Indentation = indentation;
  207. UseCustomIndentation = useCustomIndentation;
  208. AutoLineFeed = !string.IsNullOrEmpty( indentation );
  209. Used = false;
  210. }
  211. }
  212. [Serializable]
  213. public class TemplateTessVControlTag
  214. {
  215. public string Id;
  216. public int StartIdx;
  217. public TemplateTessVControlTag()
  218. {
  219. StartIdx = -1;
  220. }
  221. public bool IsValid { get { return StartIdx >= 0; } }
  222. }
  223. [Serializable]
  224. public class TemplateTessControlData
  225. {
  226. public string Id;
  227. public int StartIdx;
  228. public string InVarType;
  229. public string InVarName;
  230. public string OutVarType;
  231. public string OutVarName;
  232. public bool IsValid { get { return StartIdx >= 0; } }
  233. public TemplateTessControlData()
  234. {
  235. StartIdx = -1;
  236. }
  237. public TemplateTessControlData( int startIdx, string id, string inVarInfo, string outVarInfo )
  238. {
  239. StartIdx = startIdx;
  240. Id = id;
  241. string[] inVarInfoArr = inVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  242. if( inVarInfoArr.Length > 1 )
  243. {
  244. InVarType = inVarInfoArr[ 1 ];
  245. InVarName = inVarInfoArr[ 0 ];
  246. }
  247. string[] outVarInfoArr = outVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  248. if( outVarInfoArr.Length > 1 )
  249. {
  250. OutVarType = outVarInfoArr[ 1 ];
  251. OutVarName = outVarInfoArr[ 0 ];
  252. }
  253. }
  254. public string[] GenerateControl( Dictionary<TemplateSemantics, TemplateVertexData> vertexData, List<string> inputList )
  255. {
  256. List<string> value = new List<string>();
  257. if( vertexData != null && vertexData.Count > 0 )
  258. {
  259. foreach( var item in vertexData )
  260. {
  261. if( inputList.FindIndex( x => { return x.Contains( item.Value.VarName ); } ) > -1 )
  262. value.Add( string.Format( "{0}.{1} = {2}.{1};", OutVarName, item.Value.VarName, InVarName ) );
  263. }
  264. }
  265. return value.ToArray();
  266. }
  267. }
  268. [Serializable]
  269. public class TemplateTessDomainData
  270. {
  271. public string Id;
  272. public int StartIdx;
  273. public string InVarType;
  274. public string InVarName;
  275. public string OutVarType;
  276. public string OutVarName;
  277. public string BaryVarType;
  278. public string BaryVarName;
  279. public bool IsValid { get { return StartIdx >= 0; } }
  280. public TemplateTessDomainData()
  281. {
  282. StartIdx = -1;
  283. }
  284. public TemplateTessDomainData( int startIdx, string id, string inVarInfo, string outVarInfo, string baryVarInfo )
  285. {
  286. StartIdx = startIdx;
  287. Id = id;
  288. string[] inVarInfoArr = inVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  289. if( inVarInfoArr.Length > 1 )
  290. {
  291. InVarType = inVarInfoArr[ 1 ];
  292. InVarName = inVarInfoArr[ 0 ];
  293. }
  294. string[] outVarInfoArr = outVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  295. if( outVarInfoArr.Length > 1 )
  296. {
  297. OutVarType = outVarInfoArr[ 1 ];
  298. OutVarName = outVarInfoArr[ 0 ];
  299. }
  300. string[] baryVarInfoArr = baryVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  301. if( baryVarInfoArr.Length > 1 )
  302. {
  303. BaryVarType = baryVarInfoArr[ 1 ];
  304. BaryVarName = baryVarInfoArr[ 0 ];
  305. }
  306. }
  307. public string[] GenerateDomain( Dictionary<TemplateSemantics, TemplateVertexData> vertexData, List<string> inputList )
  308. {
  309. List<string> value = new List<string>();
  310. if( vertexData != null && vertexData.Count > 0 )
  311. {
  312. foreach( var item in vertexData )
  313. {
  314. //o.ase_normal = patch[0].ase_normal * bary.x + patch[1].ase_normal * bary.y + patch[2].ase_normal * bary.z;
  315. if( inputList.FindIndex( x => { return x.Contains( item.Value.VarName ); } ) > -1 )
  316. value.Add( string.Format( "{0}.{1} = {2}[0].{1} * {3}.x + {2}[1].{1} * {3}.y + {2}[2].{1} * {3}.z;", OutVarName, item.Value.VarName, InVarName, BaryVarName ) );
  317. }
  318. }
  319. return value.ToArray();
  320. }
  321. }
  322. [Serializable]
  323. public class TemplateFunctionData
  324. {
  325. public int MainBodyLocalIdx;
  326. public string MainBodyName;
  327. public string Id;
  328. public int Position;
  329. public string InVarType;
  330. public string InVarName;
  331. public string OutVarType;
  332. public string OutVarName;
  333. public MasterNodePortCategory Category;
  334. public TemplateFunctionData( int mainBodyLocalIdx, string mainBodyName, string id, int position, string inVarInfo, string outVarInfo, MasterNodePortCategory category )
  335. {
  336. MainBodyLocalIdx = mainBodyLocalIdx;
  337. MainBodyName = mainBodyName;
  338. Id = id;
  339. Position = position;
  340. {
  341. string[] inVarInfoArr = inVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  342. if( inVarInfoArr.Length > 1 )
  343. {
  344. InVarType = inVarInfoArr[ 1 ];
  345. InVarName = inVarInfoArr[ 0 ];
  346. }
  347. }
  348. {
  349. string[] outVarInfoArr = outVarInfo.Split( IOUtils.VALUE_SEPARATOR );
  350. if( outVarInfoArr.Length > 1 )
  351. {
  352. OutVarType = outVarInfoArr[ 1 ];
  353. OutVarName = outVarInfoArr[ 0 ];
  354. }
  355. }
  356. Category = category;
  357. }
  358. }
  359. [Serializable]
  360. public class TemplateTagData
  361. {
  362. public int StartIdx = -1;
  363. public string Id;
  364. public bool SearchIndentation;
  365. public string CustomIndentation;
  366. public TemplateTagData( int startIdx, string id, bool searchIndentation )
  367. {
  368. StartIdx = startIdx;
  369. Id = id;
  370. SearchIndentation = searchIndentation;
  371. CustomIndentation = string.Empty;
  372. }
  373. public TemplateTagData( string id, bool searchIndentation )
  374. {
  375. Id = id;
  376. SearchIndentation = searchIndentation;
  377. CustomIndentation = string.Empty;
  378. }
  379. public TemplateTagData( string id, bool searchIndentation, string customIndentation )
  380. {
  381. Id = id;
  382. SearchIndentation = searchIndentation;
  383. CustomIndentation = customIndentation;
  384. }
  385. public bool IsValid { get { return StartIdx >= 0; } }
  386. }
  387. public enum TemplatePortIds
  388. {
  389. Name = 0,
  390. DataType,
  391. UniqueId,
  392. OrderId,
  393. Link
  394. }
  395. public enum TemplateCommonTagId
  396. {
  397. Property = 0,
  398. Global = 1,
  399. Function = 2,
  400. Tag = 3,
  401. Pragmas = 4,
  402. Pass = 5,
  403. Params_Vert = 6,
  404. Params_Frag = 7
  405. //CullMode = 8,
  406. //BlendMode = 9,
  407. //BlendOp = 10,
  408. //ColorMask = 11,
  409. //StencilOp = 12
  410. }
  411. [Serializable]
  412. public class TemplatesManager : ScriptableObject
  413. {
  414. public static int MPShaderVersion = 14503;
  415. public static readonly string TemplateShaderNameBeginTag = "/*ase_name*/";
  416. public static readonly string TemplateStencilTag = "/*ase_stencil*/\n";
  417. public static readonly string TemplateRenderPlatformsTag = "/*ase_render_platforms*/";
  418. public static readonly string TemplateAllModulesTag = "/*ase_all_modules*/\n";
  419. public static readonly string TemplateMPSubShaderTag = "\\bSubShader\\b\\s*{";
  420. //public static readonly string TemplateMPPassTag = "^\\s*Pass\b\\s*{";//"\\bPass\\b\\s*{";
  421. public static readonly string TemplateMPPassTag = "\\bPass\\b\\s*{";
  422. public static readonly string TemplateLocalVarTag = "/*ase_local_var*/";
  423. public static readonly string TemplateDependenciesListTag = "/*ase_dependencies_list*/";
  424. public static readonly string TemplatePragmaBeforeTag = "/*ase_pragma_before*/";
  425. public static readonly string TemplatePragmaTag = "/*ase_pragma*/";
  426. public static readonly string TemplatePassTag = "/*ase_pass*/";
  427. public static readonly string TemplatePassesEndTag = "/*ase_pass_end*/";
  428. public static readonly string TemplateLODsTag = "/*ase_lod*/";
  429. //public static readonly string TemplatePassTagPattern = @"\s\/\*ase_pass\*\/";
  430. public static readonly string TemplatePassTagPattern = @"\s\/\*ase_pass[:\*]+";
  431. public static readonly string TemplatePropertyTag = "/*ase_props*/";
  432. public static readonly string TemplateGlobalsTag = "/*ase_globals*/";
  433. public static readonly string TemplateSRPBatcherTag = "/*ase_srp_batcher*/\n";
  434. public static readonly string TemplateInterpolatorBeginTag = "/*ase_interp(";
  435. public static readonly string TemplateVertexDataTag = "/*ase_vdata:";
  436. public static readonly string TemplateTessVControlTag = "/*ase_vcontrol*/";
  437. public static readonly string TemplateTessControlCodeArea = "/*ase_control_code:";
  438. public static readonly string TemplateTessDomainCodeArea = "/*ase_domain_code:";
  439. //public static readonly string TemplateExcludeFromGraphTag = "/*ase_hide_pass*/";
  440. public static readonly string TemplateMainPassTag = "/*ase_main_pass*/";
  441. public static readonly string TemplateFunctionsTag = "/*ase_funcs*/\n";
  442. //public static readonly string TemplateTagsTag = "/*ase_tags*/";
  443. //public static readonly string TemplateCullModeTag = "/*ase_cull_mode*/";
  444. //public static readonly string TemplateBlendModeTag = "/*ase_blend_mode*/";
  445. //public static readonly string TemplateBlendOpTag = "/*ase_blend_op*/";
  446. //public static readonly string TemplateColorMaskTag = "/*ase_color_mask*/";
  447. //public static readonly string TemplateStencilOpTag = "/*ase_stencil*/";
  448. public static readonly string TemplateCodeSnippetAttribBegin = "#CODE_SNIPPET_ATTRIBS_BEGIN#";
  449. public static readonly string TemplateCodeSnippetAttribEnd = "#CODE_SNIPPET_ATTRIBS_END#\n";
  450. public static readonly string TemplateCodeSnippetEnd = "#CODE_SNIPPET_END#\n";
  451. public static readonly char TemplateNewLine = '\n';
  452. // INPUTS AREA
  453. public static readonly string TemplateInputsVertBeginTag = "/*ase_vert_out:";
  454. public static readonly string TemplateInputsFragBeginTag = "/*ase_frag_out:";
  455. public static readonly string TemplateInputsVertParamsTag = "/*ase_vert_input*/";
  456. public static readonly string TemplateInputsFragParamsTag = "/*ase_frag_input*/";
  457. // CODE AREA
  458. public static readonly string TemplateVertexCodeBeginArea = "/*ase_vert_code:";
  459. public static readonly string TemplateFragmentCodeBeginArea = "/*ase_frag_code:";
  460. public static readonly string TemplateEndOfLine = "*/\n";
  461. public static readonly string TemplateEndSectionTag = "*/";
  462. public static readonly string TemplateFullEndTag = "/*end*/";
  463. public static readonly string NameFormatter = "\"{0}\"";
  464. public static readonly TemplateTagData[] CommonTags = { new TemplateTagData( TemplatePropertyTag,true),
  465. new TemplateTagData( TemplateGlobalsTag,true),
  466. new TemplateTagData( TemplateSRPBatcherTag,true),
  467. new TemplateTagData( TemplateFunctionsTag,true),
  468. //new TemplateTagData( TemplateTagsTag,false," "),
  469. new TemplateTagData( TemplatePragmaBeforeTag,true),
  470. new TemplateTagData( TemplatePragmaTag,true),
  471. new TemplateTagData( TemplatePassTag,true),
  472. new TemplateTagData( TemplateInputsVertParamsTag,false),
  473. new TemplateTagData( TemplateInputsFragParamsTag,false),
  474. new TemplateTagData( TemplateLODsTag,true)
  475. //new TemplateTagData( TemplateCullModeTag,false),
  476. //new TemplateTagData( TemplateBlendModeTag,false),
  477. //new TemplateTagData( TemplateBlendOpTag,false),
  478. //new TemplateTagData( TemplateColorMaskTag,false),
  479. //new TemplateTagData( TemplateStencilOpTag,true),
  480. };
  481. public static string URPLitGUID = "94348b07e5e8bab40bd6c8a1e3df54cd";
  482. public static string URPUnlitGUID = "2992e84f91cbeb14eab234972e07ea9d";
  483. public static string HDRPLitGUID = "53b46d85872c5b24c8f4f0a1c3fe4c87";
  484. public static string HDRPUnlitGUID = "7f5cb9c3ea6481f469fdd856555439ef";
  485. public static Dictionary<string, string> DeprecatedTemplates = new Dictionary<string, string>()
  486. {
  487. };
  488. public static Dictionary<string, string> OfficialTemplates = new Dictionary<string, string>()
  489. {
  490. { "6ce779933eb99f049b78d6163735e06f","Custom Render Texture/Initialize"},
  491. { "32120270d1b3a8746af2aca8bc749736","Custom Render Texture/Update"},
  492. { "5056123faa0c79b47ab6ad7e8bf059a4","UI/Default" },
  493. { "ed95fe726fd7b4644bb42f4d1ddd2bcd","Legacy/Lit"},
  494. { "0770190933193b94aaa3065e307002fa","Legacy/Unlit"},
  495. { "899e609c083c74c4ca567477c39edef0","Legacy/Unlit Lightmap" },
  496. { "e1de45c0d41f68c41b2cc20c8b9c05ef","Legacy/Multi Pass Unlit" },
  497. { "32139be9c1eb75640a847f011acf3bcf","Legacy/Post-Processing Stack"},
  498. { "c71b220b631b6344493ea3cf87110c93","Legacy/Image Effect" },
  499. { "0f8ba0101102bb14ebf021ddadce9b49","Legacy/Default Sprites" },
  500. { "0b6a9f8b4f707c74ca64c0be8e590de0","Legacy/Particles Alpha Blended" },
  501. { URPLitGUID,"Universal/Lit"},
  502. { URPUnlitGUID,"Universal/Unlit"},
  503. { HDRPLitGUID,"HDRP/Lit"},
  504. { HDRPUnlitGUID,"HDRP/Unlit"},
  505. };
  506. public static readonly string TemplateMenuItemsFileGUID = "da0b931bd234a1e43b65f684d4b59bfb";
  507. private Dictionary<string, TemplateDataParent> m_availableTemplates = new Dictionary<string, TemplateDataParent>();
  508. [SerializeField]
  509. private List<TemplateDataParent> m_sortedTemplates = new List<TemplateDataParent>();
  510. [SerializeField]
  511. public string[] AvailableTemplateNames;
  512. [SerializeField]
  513. public bool Initialized = false;
  514. private Dictionary<string, bool> m_optionsInitialSetup = new Dictionary<string, bool>();
  515. public static string CurrTemplateGUIDLoaded = string.Empty;
  516. public static bool IsTestTemplate { get { return CurrTemplateGUIDLoaded.Equals( "a95a019bbc760714bb8228af04c291d1" ); } }
  517. public static bool ShowDebugMessages = false;
  518. public void RefreshAvailableTemplates()
  519. {
  520. if( m_availableTemplates.Count != m_sortedTemplates.Count )
  521. {
  522. m_availableTemplates.Clear();
  523. int count = m_sortedTemplates.Count;
  524. for( int i = 0; i < count; i++ )
  525. {
  526. m_availableTemplates.Add( m_sortedTemplates[ i ].GUID, m_sortedTemplates[ i ] );
  527. }
  528. }
  529. }
  530. struct TemplateDescriptor
  531. {
  532. public TemplateDataParent template;
  533. public string name;
  534. public string guid;
  535. public string path;
  536. public bool isCommunity;
  537. }
  538. public void Init()
  539. {
  540. if( !Initialized )
  541. {
  542. if( ShowDebugMessages )
  543. Debug.Log( "Initialize" );
  544. string templateMenuItems = IOUtils.LoadTextFileFromDisk( AssetDatabase.GUIDToAssetPath( TemplateMenuItemsFileGUID ) );
  545. bool refreshTemplateMenuItems = false;
  546. string[] allShaders = AssetDatabase.FindAssets( "t:shader" );
  547. var templates = new Dictionary<string,TemplateDescriptor>();
  548. // Add official templates first
  549. foreach ( KeyValuePair<string, string> kvp in OfficialTemplates )
  550. {
  551. string guid = kvp.Key;
  552. string path = AssetDatabase.GUIDToAssetPath( guid );
  553. if ( !string.IsNullOrEmpty( path ) && !templates.ContainsKey( guid ) )
  554. {
  555. var desc = new TemplateDescriptor();
  556. desc.template = ScriptableObject.CreateInstance<TemplateMultiPass>();
  557. desc.name = kvp.Value;
  558. desc.guid = guid;
  559. desc.path = path;
  560. desc.isCommunity = false;
  561. templates.Add( desc.guid, desc );
  562. }
  563. }
  564. // Search for other possible templates on the project
  565. var candidates = new List<KeyValuePair<string, string>>( allShaders.Length );
  566. var candidateBag = new ConcurrentBag<string>();
  567. for ( int i = 0; i < allShaders.Length; i++ )
  568. {
  569. if ( !templates.ContainsKey( allShaders[ i ] ) )
  570. {
  571. candidates.Add( new KeyValuePair<string, string>( allShaders[ i ], AssetDatabase.GUIDToAssetPath( allShaders[ i ] ) ) );
  572. }
  573. }
  574. Parallel.For( 0, candidates.Count, i =>
  575. {
  576. string body = File.ReadAllText( candidates[ i ].Value ); ;
  577. if ( body.IndexOf( TemplatesManager.TemplateShaderNameBeginTag ) > -1 )
  578. {
  579. candidateBag.Add( candidates[ i ].Key );
  580. }
  581. } );
  582. foreach ( var guid in candidateBag )
  583. {
  584. TemplateDataParent template = GetTemplate( guid );
  585. if ( template == null && !templates.ContainsKey( guid ) )
  586. {
  587. var desc = new TemplateDescriptor();
  588. desc.template = ScriptableObject.CreateInstance<TemplateMultiPass>();
  589. desc.name = string.Empty;
  590. desc.guid = guid;
  591. desc.path = AssetDatabase.GUIDToAssetPath( guid );
  592. desc.isCommunity = true;
  593. templates.Add( desc.guid, desc );
  594. }
  595. }
  596. var templateList = templates.Values.ToArray();
  597. Parallel.For( 0, templateList.Length, i =>
  598. {
  599. TemplateDescriptor desc = templateList[ i ];
  600. desc.template.Init( desc.name, desc.guid, desc.path, desc.isCommunity );
  601. } );
  602. foreach ( var pair in templates )
  603. {
  604. TemplateDescriptor desc = pair.Value;
  605. if ( desc.template.IsValid )
  606. {
  607. AddTemplate( desc.template );
  608. }
  609. if ( !desc.isCommunity && !refreshTemplateMenuItems && templateMenuItems.IndexOf( name ) < 0 )
  610. {
  611. refreshTemplateMenuItems = true;
  612. }
  613. }
  614. AvailableTemplateNames = new string[ m_sortedTemplates.Count + 1 ];
  615. AvailableTemplateNames[ 0 ] = "Custom";
  616. for( int i = 0; i < m_sortedTemplates.Count; i++ )
  617. {
  618. m_sortedTemplates[ i ].OrderId = i;
  619. AvailableTemplateNames[ i + 1 ] = m_sortedTemplates[ i ].Name;
  620. }
  621. if( refreshTemplateMenuItems )
  622. CreateTemplateMenuItems();
  623. Initialized = true;
  624. }
  625. }
  626. //[MenuItem( "Window/Amplify Shader Editor/Create Menu Items", false, 1000 )]
  627. //public static void ForceCreateTemplateMenuItems()
  628. //{
  629. // UIUtils.CurrentWindow.TemplatesManagerInstance.CreateTemplateMenuItems();
  630. //}
  631. public void CreateTemplateMenuItems()
  632. {
  633. if( m_sortedTemplates == null || m_sortedTemplates.Count == 0 )
  634. return;
  635. // change names for duplicates
  636. for( int i = 0; i < m_sortedTemplates.Count; i++ )
  637. {
  638. for( int j = 0; j < i; j++ )
  639. {
  640. if( m_sortedTemplates[ i ].Name == m_sortedTemplates[ j ].Name )
  641. {
  642. var match = Regex.Match( m_sortedTemplates[ i ].Name, @"^.*?(\d+(?:[.,]\d+)?)\s*$" );
  643. if( match.Success )
  644. {
  645. string strNumber = match.Groups[ 1 ].Value;
  646. int number = int.Parse( strNumber ) + 1;
  647. string firstPart = m_sortedTemplates[ i ].Name.Substring( 0, match.Groups[ 1 ].Index );
  648. string secondPart = m_sortedTemplates[ i ].Name.Substring( match.Groups[ 1 ].Index + strNumber.Length );
  649. m_sortedTemplates[ i ].Name = firstPart + number + secondPart;
  650. }
  651. else
  652. {
  653. m_sortedTemplates[ i ].Name += " 1";
  654. }
  655. }
  656. }
  657. }
  658. // Sort templates by name
  659. var sorted = new SortedDictionary<string, string>();
  660. for ( int i = 0; i < m_sortedTemplates.Count; i++ )
  661. {
  662. sorted.Add( m_sortedTemplates[ i ].Name, m_sortedTemplates[ i ].GUID );
  663. }
  664. System.Text.StringBuilder fileContents = new System.Text.StringBuilder();
  665. fileContents.Append( "// Amplify Shader Editor - Visual Shader Editing Tool\n" );
  666. fileContents.Append( "// Copyright (c) Amplify Creations, Lda <info@amplify.pt>\n" );
  667. fileContents.Append( "using UnityEditor;\n" );
  668. fileContents.Append( "\n" );
  669. fileContents.Append( "namespace AmplifyShaderEditor\n" );
  670. fileContents.Append( "{\n" );
  671. fileContents.Append( "\tpublic class TemplateMenuItems\n" );
  672. fileContents.Append( "\t{\n" );
  673. int fixedPriority = 85;
  674. foreach ( var pair in sorted )
  675. {
  676. fileContents.AppendFormat( "\t\t[MenuItem( \"Assets/Create/Amplify Shader/{0}\", false, {1} )]\n", pair.Key, fixedPriority );
  677. string itemName = UIUtils.RemoveInvalidCharacters( pair.Key );
  678. fileContents.AppendFormat( "\t\tpublic static void ApplyTemplate{0}()\n", itemName/*i*/ );
  679. fileContents.Append( "\t\t{\n" );
  680. //fileContents.AppendFormat( "\t\t\tAmplifyShaderEditorWindow.CreateNewTemplateShader( \"{0}\" );\n", m_sortedTemplates[ i ].GUID );
  681. fileContents.AppendFormat( "\t\t\tAmplifyShaderEditorWindow.CreateConfirmationTemplateShader( \"{0}\" );\n", pair.Value );
  682. fileContents.Append( "\t\t}\n" );
  683. }
  684. fileContents.Append( "\t}\n" );
  685. fileContents.Append( "}\n" );
  686. string filePath = AssetDatabase.GUIDToAssetPath( TemplateMenuItemsFileGUID );
  687. IOUtils.SaveTextfileToDisk( fileContents.ToString(), filePath, false );
  688. m_filepath = filePath;
  689. //AssetDatabase.ImportAsset( filePath );
  690. }
  691. string m_filepath = string.Empty;
  692. public void ReimportMenuItems()
  693. {
  694. if( !string.IsNullOrEmpty( m_filepath ) )
  695. {
  696. AssetDatabase.ImportAsset( m_filepath );
  697. m_filepath = string.Empty;
  698. }
  699. }
  700. public int GetIdForTemplate( TemplateData templateData )
  701. {
  702. if( templateData == null )
  703. return -1;
  704. for( int i = 0; i < m_sortedTemplates.Count; i++ )
  705. {
  706. if( m_sortedTemplates[ i ].GUID.Equals( templateData.GUID ) )
  707. return m_sortedTemplates[ i ].OrderId;
  708. }
  709. return -1;
  710. }
  711. public void AddTemplate( TemplateDataParent templateData )
  712. {
  713. if( templateData == null || !templateData.IsValid )
  714. return;
  715. RefreshAvailableTemplates();
  716. if( !m_availableTemplates.ContainsKey( templateData.GUID ) )
  717. {
  718. m_sortedTemplates.Add( templateData );
  719. m_availableTemplates.Add( templateData.GUID, templateData );
  720. }
  721. }
  722. public void RemoveTemplate( string guid )
  723. {
  724. TemplateDataParent templateData = GetTemplate( guid );
  725. if( templateData != null )
  726. {
  727. RemoveTemplate( templateData );
  728. }
  729. }
  730. public void RemoveTemplate( TemplateDataParent templateData )
  731. {
  732. RefreshAvailableTemplates();
  733. if( m_availableTemplates != null )
  734. m_availableTemplates.Remove( templateData.GUID );
  735. m_sortedTemplates.Remove( templateData );
  736. templateData.Destroy();
  737. }
  738. public void Destroy()
  739. {
  740. if( TemplatesManager.ShowDebugMessages )
  741. Debug.Log( "Destroy Manager" );
  742. if( m_availableTemplates != null )
  743. {
  744. foreach( KeyValuePair<string, TemplateDataParent> kvp in m_availableTemplates )
  745. {
  746. kvp.Value.Destroy();
  747. }
  748. m_availableTemplates.Clear();
  749. m_availableTemplates = null;
  750. }
  751. int count = m_sortedTemplates.Count;
  752. for( int i = 0; i < count; i++ )
  753. {
  754. ScriptableObject.DestroyImmediate( m_sortedTemplates[ i ] );
  755. }
  756. m_sortedTemplates.Clear();
  757. m_sortedTemplates = null;
  758. AvailableTemplateNames = null;
  759. Initialized = false;
  760. }
  761. public TemplateDataParent GetTemplate( int id )
  762. {
  763. if( id < m_sortedTemplates.Count )
  764. return m_sortedTemplates[ id ];
  765. return null;
  766. }
  767. public TemplateDataParent GetTemplate( string guid )
  768. {
  769. RefreshAvailableTemplates();
  770. if( m_availableTemplates == null && m_sortedTemplates != null )
  771. {
  772. m_availableTemplates = new Dictionary<string, TemplateDataParent>();
  773. for( int i = 0; i < m_sortedTemplates.Count; i++ )
  774. {
  775. m_availableTemplates.Add( m_sortedTemplates[ i ].GUID, m_sortedTemplates[ i ] );
  776. }
  777. }
  778. if( m_availableTemplates.ContainsKey( guid ) )
  779. return m_availableTemplates[ guid ];
  780. return null;
  781. }
  782. public TemplateDataParent GetTemplateByName( string name )
  783. {
  784. RefreshAvailableTemplates();
  785. if( m_availableTemplates == null && m_sortedTemplates != null )
  786. {
  787. m_availableTemplates = new Dictionary<string, TemplateDataParent>();
  788. for( int i = 0; i < m_sortedTemplates.Count; i++ )
  789. {
  790. m_availableTemplates.Add( m_sortedTemplates[ i ].GUID, m_sortedTemplates[ i ] );
  791. }
  792. }
  793. foreach( KeyValuePair<string, TemplateDataParent> kvp in m_availableTemplates )
  794. {
  795. if( kvp.Value.DefaultShaderName.Equals( name ) )
  796. {
  797. return kvp.Value;
  798. }
  799. }
  800. return null;
  801. }
  802. public TemplateDataParent CheckAndLoadTemplate( string guid )
  803. {
  804. TemplateDataParent templateData = GetTemplate( guid );
  805. if( templateData == null )
  806. {
  807. string datapath = AssetDatabase.GUIDToAssetPath( guid );
  808. string body = IOUtils.LoadTextFileFromDisk( datapath );
  809. if( body.IndexOf( TemplatesManager.TemplateShaderNameBeginTag ) > -1 )
  810. {
  811. templateData = ScriptableObject.CreateInstance<TemplateMultiPass>();
  812. templateData.Init( string.Empty, guid, datapath, true );
  813. if( templateData.IsValid )
  814. {
  815. AddTemplate( templateData );
  816. return templateData;
  817. }
  818. }
  819. }
  820. return null;
  821. }
  822. private void OnEnable()
  823. {
  824. if( !Initialized )
  825. {
  826. Init();
  827. }
  828. else
  829. {
  830. RefreshAvailableTemplates();
  831. }
  832. hideFlags = HideFlags.HideAndDontSave;
  833. if( ShowDebugMessages )
  834. Debug.Log( "On Enable Manager: " + this.GetInstanceID() );
  835. }
  836. public void ResetOptionsSetupData()
  837. {
  838. if( ShowDebugMessages )
  839. Debug.Log( "Reseting options setup data" );
  840. m_optionsInitialSetup.Clear();
  841. }
  842. public bool SetOptionsValue( string optionId, bool value )
  843. {
  844. if( m_optionsInitialSetup.ContainsKey( optionId ) )
  845. {
  846. m_optionsInitialSetup[ optionId ] = m_optionsInitialSetup[ optionId ] || value;
  847. }
  848. else
  849. {
  850. m_optionsInitialSetup.Add( optionId, value );
  851. }
  852. return m_optionsInitialSetup[ optionId ];
  853. }
  854. public bool CheckIfDeprecated( string guid , out string newGUID )
  855. {
  856. if( DeprecatedTemplates.ContainsKey( guid ) )
  857. {
  858. UIUtils.ShowMessage( "Shader using deprecated template which no longer exists on ASE. Pointing to new correct one, options and connections to master node were reset." );
  859. newGUID = DeprecatedTemplates[ guid ];
  860. return true;
  861. }
  862. newGUID = string.Empty;
  863. return false;
  864. }
  865. public int TemplateCount { get { return m_sortedTemplates.Count; } }
  866. }
  867. }