You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2102 lines
67 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Text.RegularExpressions;
  5. using UnityEngine;
  6. using UnityEditor;
  7. using System.Collections.Generic;
  8. namespace AmplifyShaderEditor
  9. {
  10. public enum TemplateSemantics
  11. {
  12. NONE,
  13. POSITION,
  14. SV_POSITION,
  15. COLOR,
  16. COLOR0,
  17. COLOR1,
  18. TEXCOORD0,
  19. TEXCOORD1,
  20. TEXCOORD2,
  21. TEXCOORD3,
  22. TEXCOORD4,
  23. TEXCOORD5,
  24. TEXCOORD6,
  25. TEXCOORD7,
  26. TEXCOORD8,
  27. TEXCOORD9,
  28. TEXCOORD10,
  29. TEXCOORD11,
  30. TEXCOORD12,
  31. TEXCOORD13,
  32. TEXCOORD14,
  33. TEXCOORD15,
  34. NORMAL,
  35. TANGENT,
  36. VFACE,
  37. SV_VertexID,
  38. SV_PrimitiveID
  39. }
  40. public enum TemplateInfoOnSematics
  41. {
  42. NONE,
  43. POSITION,
  44. SCREEN_POSITION,
  45. COLOR,
  46. TEXTURE_COORDINATES0,
  47. TEXTURE_COORDINATES1,
  48. TEXTURE_COORDINATES2,
  49. TEXTURE_COORDINATES3,
  50. TEXTURE_COORDINATES4,
  51. TEXTURE_COORDINATES5,
  52. TEXTURE_COORDINATES6,
  53. TEXTURE_COORDINATES7,
  54. NORMAL,
  55. TANGENT,
  56. WORLD_NORMAL,
  57. WORLD_TANGENT,
  58. WORLD_BITANGENT,
  59. WORLD_VIEW_DIR,
  60. WORLD_POSITION,
  61. RELATIVE_WORLD_POS,
  62. OTHER
  63. }
  64. public enum TemplateShaderPropertiesIdx
  65. {
  66. Name = 2,
  67. InspectorName,
  68. Type
  69. }
  70. public enum TemplateShaderGlobalsIdx
  71. {
  72. Type = 1,
  73. Name = 2
  74. }
  75. public enum TemplateDataCheck
  76. {
  77. Valid,
  78. Invalid
  79. }
  80. public enum InvisibleOptionsEnum
  81. {
  82. SyncProperties = 1 << 0
  83. }
  84. public enum TemplateSpecialTags
  85. {
  86. RenderType,
  87. Queue,
  88. None
  89. }
  90. public class TemplateReplaceHelper
  91. {
  92. public TemplateMultiPassMasterNode MasterNode = null;
  93. public bool Used = false;
  94. public TemplateReplaceHelper( TemplateMultiPassMasterNode masterNode ) { MasterNode = masterNode; }
  95. }
  96. [Serializable]
  97. public class TemplatesTagData
  98. {
  99. public string Name;
  100. public string Value;
  101. public TemplatesTagData( string name, string value )
  102. {
  103. Name = name;
  104. Value = value;
  105. }
  106. }
  107. [Serializable]
  108. public class TemplateModuleData
  109. {
  110. public bool IndependentModule = true;
  111. public TemplateDataCheck DataCheck = TemplateDataCheck.Invalid;
  112. public string InlineData = string.Empty;
  113. public int StartIdx;
  114. public bool IsValid { get { return DataCheck == TemplateDataCheck.Valid; } }
  115. public virtual void SetAllModulesDefault() { IndependentModule = false; DataCheck = TemplateDataCheck.Valid; }
  116. }
  117. [Serializable]
  118. public sealed class TemplateTagsModuleData : TemplateModuleData
  119. {
  120. public string TagsId;
  121. public List<TemplatesTagData> Tags = new List<TemplatesTagData>();
  122. public void Destroy()
  123. {
  124. Tags.Clear();
  125. Tags = null;
  126. }
  127. public void Reset()
  128. {
  129. Tags.Clear();
  130. }
  131. public void Dump()
  132. {
  133. string dump = string.Empty;
  134. for( int i = 0; i < Tags.Count; i++ )
  135. {
  136. dump += string.Format( "[{0}] Name: {1} Value: {2}\n", i, Tags[ i ].Name, Tags[ i ].Value );
  137. }
  138. Debug.Log( dump );
  139. }
  140. }
  141. [Serializable]
  142. public class TemplateShaderModelData : TemplateModuleData
  143. {
  144. public string Id = string.Empty;
  145. public string Value = "2.5";
  146. public int InterpolatorAmount = 8;
  147. public bool Encapsulate = false;
  148. public override void SetAllModulesDefault()
  149. {
  150. base.SetAllModulesDefault();
  151. Id = string.Empty;
  152. Value = "3.0";
  153. InterpolatorAmount = 10;
  154. Encapsulate = true;
  155. }
  156. }
  157. [Serializable]
  158. public sealed class TemplateDepthData : TemplateModuleData
  159. {
  160. public bool ValidZWrite;
  161. public string ZWriteModeId;
  162. public ZWriteMode ZWriteModeValue;
  163. public int ZWriteStartIndex;
  164. public string ZWriteInlineValue;
  165. public bool ValidZTest;
  166. public string ZTestModeId;
  167. public ZTestMode ZTestModeValue;
  168. public int ZTestStartIndex;
  169. public string ZTestInlineValue;
  170. public bool ValidOffset;
  171. public string OffsetId;
  172. public float OffsetFactor;
  173. public float OffsetUnits;
  174. public int OffsetStartIndex;
  175. public string OffsetFactorInlineValue;
  176. public string OffsetUnitsInlineValue;
  177. public override void SetAllModulesDefault()
  178. {
  179. base.SetAllModulesDefault();
  180. ValidZWrite = true;
  181. ZWriteModeId = string.Empty;
  182. ZWriteModeValue = ZWriteMode.On;
  183. ZWriteStartIndex = -1;
  184. ZWriteInlineValue = string.Empty;
  185. ValidZTest = true;
  186. ZTestModeId = string.Empty;
  187. ZTestModeValue = ZTestMode.LEqual;
  188. ZTestStartIndex = -1;
  189. ZTestInlineValue = string.Empty;
  190. ValidOffset = true;
  191. OffsetId = string.Empty;
  192. OffsetFactor = 0;
  193. OffsetUnits = 0;
  194. OffsetStartIndex = -1;
  195. OffsetFactorInlineValue = string.Empty;
  196. OffsetUnitsInlineValue = string.Empty;
  197. }
  198. }
  199. [Serializable]
  200. public sealed class TemplateStencilData : TemplateModuleData
  201. {
  202. public string StencilBufferId;
  203. public bool Active = true;
  204. public int Reference;
  205. public string ReferenceInline;
  206. public int ReadMask = 255;
  207. public string ReadMaskInline;
  208. public int WriteMask = 255;
  209. public string WriteMaskInline;
  210. public string ComparisonFront;
  211. public string ComparisonFrontInline;
  212. public string PassFront;
  213. public string PassFrontInline;
  214. public string FailFront;
  215. public string FailFrontInline;
  216. public string ZFailFront;
  217. public string ZFailFrontInline;
  218. public string ComparisonBack;
  219. public string ComparisonBackInline;
  220. public string PassBack;
  221. public string PassBackInline;
  222. public string FailBack;
  223. public string FailBackInline;
  224. public string ZFailBack;
  225. public string ZFailBackInline;
  226. public void SetDefaultValues()
  227. {
  228. Active = false;
  229. StencilBufferId = string.Empty;
  230. Reference = 255;
  231. ReferenceInline = string.Empty;
  232. ReadMask = 255;
  233. ReadMaskInline = string.Empty;
  234. WriteMask = 255;
  235. WriteMaskInline = string.Empty;
  236. ComparisonFront = "always";
  237. ComparisonFrontInline = string.Empty;
  238. PassFront = "keep";
  239. PassFrontInline = string.Empty;
  240. FailFront = "keep";
  241. FailFrontInline = string.Empty;
  242. ZFailFront = "keep";
  243. ZFailFrontInline = string.Empty;
  244. ComparisonBack = "always";
  245. ComparisonBackInline = string.Empty;
  246. PassBack = "keep";
  247. PassBackInline = string.Empty;
  248. FailBack = "keep";
  249. FailBackInline = string.Empty;
  250. ZFailBack = "keep";
  251. ZFailBackInline = string.Empty;
  252. }
  253. public void SetIndependentDefault()
  254. {
  255. IndependentModule = true;
  256. DataCheck = TemplateDataCheck.Valid;
  257. SetDefaultValues();
  258. }
  259. public override void SetAllModulesDefault()
  260. {
  261. base.SetAllModulesDefault();
  262. SetDefaultValues();
  263. }
  264. }
  265. [Serializable]
  266. public sealed class TemplateBlendData : TemplateModuleData
  267. {
  268. public bool ValidBlendMode = false;
  269. public bool BlendModeOff = true;
  270. public string BlendModeId;
  271. public bool SeparateBlendFactors = false;
  272. public AvailableBlendFactor SourceFactorRGB = AvailableBlendFactor.One;
  273. public string SourceFactorRGBInline;
  274. public AvailableBlendFactor DestFactorRGB = AvailableBlendFactor.Zero;
  275. public string DestFactorRGBInline;
  276. public int BlendModeStartIndex;
  277. public AvailableBlendFactor SourceFactorAlpha = AvailableBlendFactor.One;
  278. public string SourceFactorAlphaInline;
  279. public AvailableBlendFactor DestFactorAlpha = AvailableBlendFactor.Zero;
  280. public string DestFactorAlphaInline;
  281. public bool ValidBlendOp = false;
  282. public string BlendOpId;
  283. public bool SeparateBlendOps = false;
  284. public AvailableBlendOps BlendOpRGB = AvailableBlendOps.OFF;
  285. public string BlendOpRGBInline;
  286. public AvailableBlendOps BlendOpAlpha = AvailableBlendOps.OFF;
  287. public string BlendOpAlphaInline;
  288. public int BlendOpStartIndex;
  289. public bool IndependentAlphaToMask = false;
  290. public bool ValidAlphaToMask = false;
  291. public bool AlphaToMaskValue = false;
  292. public string AlphaToMaskId;
  293. public override void SetAllModulesDefault()
  294. {
  295. base.SetAllModulesDefault();
  296. if( !ValidAlphaToMask )
  297. {
  298. ValidAlphaToMask = true;
  299. AlphaToMaskValue = false;
  300. AlphaToMaskId = string.Empty;
  301. }
  302. if( !ValidBlendMode )
  303. {
  304. ValidBlendMode = true;
  305. BlendModeOff = true;
  306. BlendModeId = string.Empty;
  307. SeparateBlendFactors = false;
  308. SourceFactorRGB = AvailableBlendFactor.One;
  309. SourceFactorRGBInline = string.Empty;
  310. DestFactorRGB = AvailableBlendFactor.Zero;
  311. DestFactorRGBInline = string.Empty;
  312. BlendModeStartIndex = -1;
  313. SourceFactorAlpha = AvailableBlendFactor.One;
  314. SourceFactorAlphaInline = string.Empty;
  315. DestFactorAlpha = AvailableBlendFactor.Zero;
  316. DestFactorAlphaInline = string.Empty;
  317. }
  318. if( !ValidBlendOp )
  319. {
  320. ValidBlendOp = true;
  321. BlendOpId = string.Empty;
  322. SeparateBlendOps = false;
  323. BlendOpRGB = AvailableBlendOps.OFF;
  324. BlendOpRGBInline = string.Empty;
  325. BlendOpAlpha = AvailableBlendOps.OFF;
  326. BlendOpAlphaInline = string.Empty;
  327. BlendOpStartIndex = -1;
  328. }
  329. DataCheck = TemplateDataCheck.Valid;
  330. }
  331. }
  332. [Serializable]
  333. public sealed class TemplateCullModeData : TemplateModuleData
  334. {
  335. public string CullModeId;
  336. public CullMode CullModeData = CullMode.Back;
  337. public override void SetAllModulesDefault()
  338. {
  339. base.SetAllModulesDefault();
  340. CullModeId = string.Empty;
  341. CullModeData = CullMode.Back;
  342. }
  343. }
  344. [Serializable]
  345. public sealed class TemplateColorMaskData : TemplateModuleData
  346. {
  347. public string ColorMaskId;
  348. public bool[] ColorMaskData = { true, true, true, true };
  349. public override void SetAllModulesDefault()
  350. {
  351. base.SetAllModulesDefault();
  352. ColorMaskId = string.Empty;
  353. for( int i = 0; i < ColorMaskData.Length; i++ )
  354. {
  355. ColorMaskData[ i ] = true;
  356. }
  357. }
  358. }
  359. public static class TemplateHelperFunctions
  360. {
  361. /*
  362. struct DirectionalLightData
  363. {
  364. uint lightLayers;
  365. float3 positionRWS;
  366. float3 color;
  367. int cookieIndex;
  368. float volumetricDimmer;
  369. float3 right;
  370. float3 up;
  371. float3 forward;
  372. int tileCookie;
  373. int shadowIndex;
  374. int contactShadowIndex;
  375. float4 shadowMaskSelector;
  376. int nonLightmappedOnly;
  377. float diffuseScale;
  378. float specularScale;
  379. };
  380. */
  381. public static string HDLightInfoFormat = "_DirectionalLightDatas[{0}].{1}";
  382. public static string[] VectorSwizzle = { "x", "y", "z", "w" };
  383. public static string[] ColorSwizzle = { "r", "g", "b", "a" };
  384. public static readonly Dictionary<string, InvisibleOptionsEnum> InvisibleOptions = new Dictionary<string, InvisibleOptionsEnum>()
  385. {
  386. { "SyncP", InvisibleOptionsEnum.SyncProperties }
  387. };
  388. public static readonly Dictionary<string, TemplateSpecialTags> StringToReservedTags = new Dictionary<string, TemplateSpecialTags>()
  389. {
  390. { TemplateSpecialTags.RenderType.ToString(), TemplateSpecialTags.RenderType},
  391. { TemplateSpecialTags.Queue.ToString(), TemplateSpecialTags.Queue},
  392. };
  393. public static readonly Dictionary<string, RenderType> StringToRenderType = new Dictionary<string, RenderType>
  394. {
  395. {"Opaque",RenderType.Opaque},
  396. {"Transparent",RenderType.Transparent},
  397. {"TransparentCutout",RenderType.TransparentCutout},
  398. {"Background",RenderType.Background},
  399. {"Overlay",RenderType.Overlay},
  400. {"TreeOpaque",RenderType.TreeOpaque},
  401. {"TreeTransparentCutout",RenderType.TreeTransparentCutout},
  402. {"TreeBillboard",RenderType.TreeBillboard},
  403. {"Grass",RenderType.Grass},
  404. {"GrassBillboard",RenderType.GrassBillboard}
  405. };
  406. public static readonly Dictionary<string, RenderQueue> StringToRenderQueue = new Dictionary<string, RenderQueue>
  407. {
  408. {"Background",RenderQueue.Background },
  409. {"Geometry",RenderQueue.Geometry },
  410. {"AlphaTest",RenderQueue.AlphaTest },
  411. {"Transparent",RenderQueue.Transparent },
  412. {"Overlay",RenderQueue.Overlay }
  413. };
  414. public static readonly Dictionary<string, WirePortDataType> PropertyToWireType = new Dictionary<string, WirePortDataType>
  415. {
  416. {"Float",WirePortDataType.FLOAT},
  417. {"Range",WirePortDataType.FLOAT},
  418. {"Int",WirePortDataType.INT},
  419. {"Color",WirePortDataType.COLOR},
  420. {"Vector",WirePortDataType.FLOAT4},
  421. {"2D",WirePortDataType.SAMPLER2D},
  422. {"3D",WirePortDataType.SAMPLER3D},
  423. {"Cube",WirePortDataType.SAMPLERCUBE}
  424. };
  425. public static readonly Dictionary<WirePortDataType, int> DataTypeChannelUsage = new Dictionary<WirePortDataType, int>
  426. {
  427. {WirePortDataType.OBJECT,0 },
  428. {WirePortDataType.FLOAT,1 },
  429. {WirePortDataType.FLOAT2,2 },
  430. {WirePortDataType.FLOAT3,3 },
  431. {WirePortDataType.FLOAT4,4 },
  432. {WirePortDataType.FLOAT3x3,0 },
  433. {WirePortDataType.FLOAT4x4,0 },
  434. {WirePortDataType.COLOR,4 },
  435. {WirePortDataType.INT,1 },
  436. {WirePortDataType.SAMPLER1D,0 },
  437. {WirePortDataType.SAMPLER2D,0 },
  438. {WirePortDataType.SAMPLER3D,0 },
  439. {WirePortDataType.SAMPLERCUBE,0 }
  440. };
  441. public static readonly Dictionary<int, WirePortDataType> ChannelToDataType = new Dictionary<int, WirePortDataType>
  442. {
  443. {1,WirePortDataType.FLOAT},
  444. {2,WirePortDataType.FLOAT2},
  445. {3,WirePortDataType.FLOAT3},
  446. {4,WirePortDataType.FLOAT4}
  447. };
  448. public static readonly Dictionary<TemplateSemantics, string> SemanticsDefaultName = new Dictionary<TemplateSemantics, string>
  449. {
  450. {TemplateSemantics.COLOR ,"ase_color"},
  451. {TemplateSemantics.NORMAL ,"ase_normal"},
  452. {TemplateSemantics.POSITION ,"ase_position"},
  453. {TemplateSemantics.SV_POSITION ,"ase_sv_position"},
  454. {TemplateSemantics.TANGENT ,"ase_tangent"},
  455. {TemplateSemantics.VFACE ,"ase_vface"},
  456. {TemplateSemantics.SV_VertexID ,"ase_vertexId"},
  457. {TemplateSemantics.SV_PrimitiveID ,"ase_primitiveId"},
  458. {TemplateSemantics.TEXCOORD0 ,"ase_tex_coord0"},
  459. {TemplateSemantics.TEXCOORD1 ,"ase_tex_coord1"},
  460. {TemplateSemantics.TEXCOORD2 ,"ase_tex_coord2"},
  461. {TemplateSemantics.TEXCOORD3 ,"ase_tex_coord3"},
  462. {TemplateSemantics.TEXCOORD4 ,"ase_tex_coord4"},
  463. {TemplateSemantics.TEXCOORD5 ,"ase_tex_coord5"},
  464. {TemplateSemantics.TEXCOORD6 ,"ase_tex_coord6"},
  465. {TemplateSemantics.TEXCOORD7 ,"ase_tex_coord7"},
  466. {TemplateSemantics.TEXCOORD8 ,"ase_tex_coord8"},
  467. {TemplateSemantics.TEXCOORD9 ,"ase_tex_coord9"},
  468. {TemplateSemantics.TEXCOORD10 ,"ase_tex_coord10"},
  469. {TemplateSemantics.TEXCOORD11 ,"ase_tex_coord11"},
  470. {TemplateSemantics.TEXCOORD12 ,"ase_tex_coord12"},
  471. {TemplateSemantics.TEXCOORD13 ,"ase_tex_coord13"},
  472. {TemplateSemantics.TEXCOORD14 ,"ase_tex_coord14"},
  473. {TemplateSemantics.TEXCOORD15 ,"ase_tex_coord15"},
  474. };
  475. public static readonly Dictionary<int, TemplateInfoOnSematics> IntToInfo = new Dictionary<int, TemplateInfoOnSematics>
  476. {
  477. {0,TemplateInfoOnSematics.TEXTURE_COORDINATES0 },
  478. {1,TemplateInfoOnSematics.TEXTURE_COORDINATES1 },
  479. {2,TemplateInfoOnSematics.TEXTURE_COORDINATES2 },
  480. {3,TemplateInfoOnSematics.TEXTURE_COORDINATES3 },
  481. {4,TemplateInfoOnSematics.TEXTURE_COORDINATES4 },
  482. {5,TemplateInfoOnSematics.TEXTURE_COORDINATES5 },
  483. {6,TemplateInfoOnSematics.TEXTURE_COORDINATES6 },
  484. {7,TemplateInfoOnSematics.TEXTURE_COORDINATES7 },
  485. };
  486. public static readonly Dictionary<string, TemplateInfoOnSematics> ShortcutToInfo = new Dictionary<string, TemplateInfoOnSematics>
  487. {
  488. {"p" ,TemplateInfoOnSematics.POSITION },
  489. {"sp" ,TemplateInfoOnSematics.SCREEN_POSITION },
  490. {"c" ,TemplateInfoOnSematics.COLOR },
  491. {"uv0" ,TemplateInfoOnSematics.TEXTURE_COORDINATES0 },
  492. {"uv1" ,TemplateInfoOnSematics.TEXTURE_COORDINATES1 },
  493. {"uv2" ,TemplateInfoOnSematics.TEXTURE_COORDINATES2 },
  494. {"uv3" ,TemplateInfoOnSematics.TEXTURE_COORDINATES3 },
  495. {"n" ,TemplateInfoOnSematics.NORMAL },
  496. {"t" ,TemplateInfoOnSematics.TANGENT },
  497. {"wn" ,TemplateInfoOnSematics.WORLD_NORMAL},
  498. {"wt" ,TemplateInfoOnSematics.WORLD_TANGENT},
  499. {"wbt" ,TemplateInfoOnSematics.WORLD_BITANGENT},
  500. {"wvd" ,TemplateInfoOnSematics.WORLD_VIEW_DIR},
  501. {"wp" ,TemplateInfoOnSematics.WORLD_POSITION},
  502. {"rwp" ,TemplateInfoOnSematics.RELATIVE_WORLD_POS}
  503. };
  504. public static readonly Dictionary<TemplateInfoOnSematics, string> InfoToLocalVar = new Dictionary<TemplateInfoOnSematics, string>
  505. {
  506. {TemplateInfoOnSematics.POSITION,GeneratorUtils.VertexPosition4Str },
  507. {TemplateInfoOnSematics.SCREEN_POSITION,GeneratorUtils.ScreenPositionStr },
  508. {TemplateInfoOnSematics.COLOR, "ase_color" },
  509. {TemplateInfoOnSematics.TEXTURE_COORDINATES0, "ase_uv0" },
  510. {TemplateInfoOnSematics.TEXTURE_COORDINATES1, "ase_uv1" },
  511. {TemplateInfoOnSematics.TEXTURE_COORDINATES2, "ase_uv2" },
  512. {TemplateInfoOnSematics.TEXTURE_COORDINATES3, "ase_uv3" },
  513. {TemplateInfoOnSematics.NORMAL, GeneratorUtils.VertexNormalStr },
  514. {TemplateInfoOnSematics.TANGENT, GeneratorUtils.VertexTangentStr },
  515. {TemplateInfoOnSematics.WORLD_NORMAL, GeneratorUtils.WorldNormalStr},
  516. {TemplateInfoOnSematics.WORLD_TANGENT, GeneratorUtils.WorldTangentStr},
  517. {TemplateInfoOnSematics.WORLD_BITANGENT, GeneratorUtils.WorldBitangentStr},
  518. {TemplateInfoOnSematics.WORLD_VIEW_DIR, GeneratorUtils.WorldViewDirectionStr},
  519. {TemplateInfoOnSematics.WORLD_POSITION, GeneratorUtils.WorldPositionStr},
  520. {TemplateInfoOnSematics.RELATIVE_WORLD_POS, GeneratorUtils.RelativeWorldPositionStr}
  521. };
  522. public static readonly Dictionary<TemplateInfoOnSematics, WirePortDataType> InfoToWirePortType = new Dictionary<TemplateInfoOnSematics, WirePortDataType>
  523. {
  524. {TemplateInfoOnSematics.POSITION,WirePortDataType.FLOAT4 },
  525. {TemplateInfoOnSematics.SCREEN_POSITION,WirePortDataType.FLOAT4 },
  526. {TemplateInfoOnSematics.COLOR, WirePortDataType.COLOR },
  527. {TemplateInfoOnSematics.TEXTURE_COORDINATES0, WirePortDataType.FLOAT4 },
  528. {TemplateInfoOnSematics.TEXTURE_COORDINATES1, WirePortDataType.FLOAT4 },
  529. {TemplateInfoOnSematics.TEXTURE_COORDINATES2, WirePortDataType.FLOAT4 },
  530. {TemplateInfoOnSematics.TEXTURE_COORDINATES3, WirePortDataType.FLOAT4 },
  531. {TemplateInfoOnSematics.NORMAL, WirePortDataType.FLOAT3 },
  532. {TemplateInfoOnSematics.TANGENT, WirePortDataType.FLOAT4 },
  533. {TemplateInfoOnSematics.WORLD_NORMAL, WirePortDataType.FLOAT3},
  534. {TemplateInfoOnSematics.WORLD_TANGENT, WirePortDataType.FLOAT3},
  535. {TemplateInfoOnSematics.WORLD_BITANGENT, WirePortDataType.FLOAT3},
  536. {TemplateInfoOnSematics.WORLD_VIEW_DIR, WirePortDataType.FLOAT3},
  537. {TemplateInfoOnSematics.WORLD_POSITION, WirePortDataType.FLOAT3},
  538. {TemplateInfoOnSematics.RELATIVE_WORLD_POS, WirePortDataType.FLOAT3},
  539. };
  540. public static readonly Dictionary<int, TemplateInfoOnSematics> IntToUVChannelInfo = new Dictionary<int, TemplateInfoOnSematics>
  541. {
  542. {0,TemplateInfoOnSematics.TEXTURE_COORDINATES0 },
  543. {1,TemplateInfoOnSematics.TEXTURE_COORDINATES1 },
  544. {2,TemplateInfoOnSematics.TEXTURE_COORDINATES2 },
  545. {3,TemplateInfoOnSematics.TEXTURE_COORDINATES3 },
  546. {4,TemplateInfoOnSematics.TEXTURE_COORDINATES4 },
  547. {5,TemplateInfoOnSematics.TEXTURE_COORDINATES5 },
  548. {6,TemplateInfoOnSematics.TEXTURE_COORDINATES6 },
  549. {7,TemplateInfoOnSematics.TEXTURE_COORDINATES7 }
  550. };
  551. public static readonly Dictionary<int, TemplateSemantics> IntToSemantic = new Dictionary<int, TemplateSemantics>
  552. {
  553. { 0,TemplateSemantics.TEXCOORD0 },
  554. { 1,TemplateSemantics.TEXCOORD1 },
  555. { 2,TemplateSemantics.TEXCOORD2 },
  556. { 3,TemplateSemantics.TEXCOORD3 },
  557. { 4,TemplateSemantics.TEXCOORD4 },
  558. { 5,TemplateSemantics.TEXCOORD5 },
  559. { 6,TemplateSemantics.TEXCOORD6 },
  560. { 7,TemplateSemantics.TEXCOORD7 },
  561. { 8,TemplateSemantics.TEXCOORD8 },
  562. { 9,TemplateSemantics.TEXCOORD9 },
  563. { 10,TemplateSemantics.TEXCOORD10 },
  564. { 11,TemplateSemantics.TEXCOORD11 },
  565. { 12,TemplateSemantics.TEXCOORD12 },
  566. { 13,TemplateSemantics.TEXCOORD13 },
  567. { 14,TemplateSemantics.TEXCOORD14 },
  568. { 15,TemplateSemantics.TEXCOORD15 }
  569. };
  570. public static readonly Dictionary<TemplateSemantics, int> SemanticToInt = new Dictionary<TemplateSemantics, int>
  571. {
  572. { TemplateSemantics.TEXCOORD0,0 },
  573. { TemplateSemantics.TEXCOORD1,1 },
  574. { TemplateSemantics.TEXCOORD2,2 },
  575. { TemplateSemantics.TEXCOORD3,3 },
  576. { TemplateSemantics.TEXCOORD4,4 },
  577. { TemplateSemantics.TEXCOORD5,5 },
  578. { TemplateSemantics.TEXCOORD6,6 },
  579. { TemplateSemantics.TEXCOORD7,7 },
  580. { TemplateSemantics.TEXCOORD8,8 },
  581. { TemplateSemantics.TEXCOORD9,9 },
  582. { TemplateSemantics.TEXCOORD10,10 },
  583. { TemplateSemantics.TEXCOORD11,11 },
  584. { TemplateSemantics.TEXCOORD12,12 },
  585. { TemplateSemantics.TEXCOORD13,13 },
  586. { TemplateSemantics.TEXCOORD14,14 },
  587. { TemplateSemantics.TEXCOORD15,15 },
  588. };
  589. public static readonly Dictionary<string, TemplateSemantics> ShortcutToSemantic = new Dictionary<string, TemplateSemantics>
  590. {
  591. { "p" ,TemplateSemantics.POSITION },
  592. { "sp" ,TemplateSemantics.SV_POSITION },
  593. { "c" ,TemplateSemantics.COLOR },
  594. { "n" ,TemplateSemantics.NORMAL },
  595. { "t" ,TemplateSemantics.TANGENT },
  596. { "tc0" ,TemplateSemantics.TEXCOORD0 },
  597. { "tc1" ,TemplateSemantics.TEXCOORD1 },
  598. { "tc2" ,TemplateSemantics.TEXCOORD2 },
  599. { "tc3" ,TemplateSemantics.TEXCOORD3 },
  600. { "tc4" ,TemplateSemantics.TEXCOORD4 },
  601. { "tc5" ,TemplateSemantics.TEXCOORD5 },
  602. { "tc6" ,TemplateSemantics.TEXCOORD6 },
  603. { "tc7" ,TemplateSemantics.TEXCOORD7 },
  604. { "tc8" ,TemplateSemantics.TEXCOORD8 },
  605. { "tc9" ,TemplateSemantics.TEXCOORD9 },
  606. { "tc10" ,TemplateSemantics.TEXCOORD10 },
  607. { "tc11" ,TemplateSemantics.TEXCOORD11 },
  608. { "tc12" ,TemplateSemantics.TEXCOORD12 },
  609. { "tc13" ,TemplateSemantics.TEXCOORD13 },
  610. { "tc14" ,TemplateSemantics.TEXCOORD14 },
  611. { "tc15" ,TemplateSemantics.TEXCOORD15 }
  612. };
  613. public static readonly Dictionary<string, WirePortDataType> CgToWirePortType = new Dictionary<string, WirePortDataType>()
  614. {
  615. {"float" ,WirePortDataType.FLOAT},
  616. {"float2" ,WirePortDataType.FLOAT2},
  617. {"float3" ,WirePortDataType.FLOAT3},
  618. {"float4" ,WirePortDataType.FLOAT4},
  619. {"float3x3" ,WirePortDataType.FLOAT3x3},
  620. {"float4x4" ,WirePortDataType.FLOAT4x4},
  621. {"half" ,WirePortDataType.FLOAT},
  622. {"half2" ,WirePortDataType.FLOAT2},
  623. {"half3" ,WirePortDataType.FLOAT3},
  624. {"half4" ,WirePortDataType.FLOAT4},
  625. {"half3x3" ,WirePortDataType.FLOAT3x3},
  626. {"half4x4" ,WirePortDataType.FLOAT4x4},
  627. {"fixed" ,WirePortDataType.FLOAT},
  628. {"fixed2" ,WirePortDataType.FLOAT2},
  629. {"fixed3" ,WirePortDataType.FLOAT3},
  630. {"fixed4" ,WirePortDataType.FLOAT4},
  631. {"fixed3x3" ,WirePortDataType.FLOAT3x3},
  632. {"fixed4x4" ,WirePortDataType.FLOAT4x4},
  633. {"int" ,WirePortDataType.INT},
  634. {"uint" ,WirePortDataType.INT},
  635. {"sampler1D" ,WirePortDataType.SAMPLER1D},
  636. {"sampler2D" ,WirePortDataType.SAMPLER2D},
  637. {"sampler2D_float" ,WirePortDataType.SAMPLER2D},
  638. {"sampler3D" ,WirePortDataType.SAMPLER3D},
  639. {"samplerCUBE" ,WirePortDataType.SAMPLERCUBE}
  640. };
  641. public static readonly Dictionary<string, int> AvailableInterpolators = new Dictionary<string, int>()
  642. {
  643. {"2.0",8 },
  644. {"2.5",8 },
  645. {"3.0",10},
  646. {"3.5",10},
  647. {"4.0",16},
  648. {"4.5",16},
  649. {"4.6",16},
  650. {"5.0",16}
  651. };
  652. public static readonly string[] AvailableShaderModels =
  653. { "2.0", "2.5", "3.0", "3.5", "4.0", "4.5", "4.6", "5.0" };
  654. public static readonly Dictionary<string, int> ShaderModelToArrayIdx = new Dictionary<string, int>()
  655. {
  656. {"2.0",0},
  657. {"2.5",1},
  658. {"3.0",2},
  659. {"3.5",3},
  660. {"4.0",4},
  661. {"4.5",5},
  662. {"4.6",6},
  663. {"5.0",7}
  664. };
  665. public static readonly string HDPBRTag = "UNITY_MATERIAL_LIT";
  666. public static readonly Dictionary<string, TemplateSRPType> TagToRenderPipeline = new Dictionary<string, TemplateSRPType>()
  667. {
  668. { "LightweightPipeline",TemplateSRPType.Lightweight },
  669. { "HDRenderPipeline",TemplateSRPType.HD }
  670. };
  671. #if UNITY_2018_3_OR_NEWER
  672. public static string CoreColorLib = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl";
  673. public static string CoreCommonLib = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl";
  674. #else
  675. public static string CoreCommonLib = "CoreRP/ShaderLibrary/Common.hlsl";
  676. public static string CoreColorLib = "CoreRP/ShaderLibrary/Color.hlsl";
  677. #endif
  678. public static string HidePassPattern = @"\/\*ase_hide_pass[:]*([a-zA-Z:]*)\*\/";
  679. public static string BlendWholeWordPattern = @"\bBlend\b";
  680. public static string BlendOpWholeWordPattern = @"\bBlendOp\b";
  681. public static string ALphaToMaskPattern = @"\bAlphaToMask (\w*)";
  682. public static string CullWholeWordPattern = @"\bCull\b";
  683. public static string ColorMaskWholeWordPattern = @"\bColorMask\b";
  684. public static string StencilWholeWordPattern = @"\bStencil\b";
  685. public static string ZWriteWholeWordPattern = @"\bZWrite\b";
  686. public static string ZTestWholeWordPattern = @"\bZTest\b";
  687. public static string ZOffsetWholeWordPattern = @"\bOffset\b";
  688. public static string TagsWholeWordPattern = @"\bTags\b";
  689. public static string CustomInspectorPattern = "^\\s*CustomEditor\\s+\\\"(\\w*)\\\"";
  690. public static string FallbackPattern = "^\\s*Fallback\\s+\\\"(\\w*)\\\"";
  691. public static string DefinesPattern = @"^\s*#define\s+([\w .]*)";
  692. public static string PragmasPattern = @"^\s*#pragma\s+([\w .]*)";
  693. public static string IncludesPattern = "^\\s*#include\\s+\"([\\w.\\/]*)\"";
  694. public static string GlobalDirectivesPattern = "[#]+(define|pragma|include)\\s+([\\w .\\/\\\"]*)";
  695. public static string VertexPragmaPattern = @"#pragma vertex\s+(\w+)";
  696. public static string FragmentPragmaPattern = @"#pragma fragment\s+(\w+)";
  697. public static string FunctionBodyStartPattern = @"\s+{0}\s*\(";
  698. public static string ShaderModelPattern = @"#pragma\s+target\s+([0-9]*[.]*[0-9]*)";
  699. public static readonly string LocalVarPattern = @"\/\*ase_local_var[:]*(\w*)\*\/\s*(\w*)\s+(\w*)";
  700. public static readonly string SubShaderLODPattern = @"LOD\s+(\w+)";
  701. public static readonly string PassNamePattern = "Name\\s+\\\"([\\w\\+\\-\\*\\/\\(\\) ]*)\\\"";
  702. public static readonly string TagsPattern = "\"(\\w+)\"\\s*=\\s*\"(\\w+\\+*\\w*)\"";
  703. public static readonly string ZTestPattern = @"\s*ZTest\s+(\[*\w+\]*)";
  704. public static readonly string ZWritePattern = @"\s*ZWrite\s+(\[*\w+\]*)";
  705. //public static readonly string ZOffsetPattern = @"\s*Offset\s+([-+]?[0-9]*\.?[0-9]+)\s*,\s*([-+]?[0-9]*\.?[0-9]+)";
  706. public static readonly string ZOffsetPattern = @"\s*Offset\s+([-+]?[0-9]*\.?[0-9]+|\[*\w+\]*)\s*,\s*([-+]?[0-9]*\.?[0-9]+|\[*\w+\]*)\s*";
  707. public static readonly string VertexDataPattern = @"(\w+)\s*(\w+)\s*:\s*([A-Z0-9_]+);";
  708. public static readonly string InterpRangePattern = @"ase_interp\((\d\.{0,1}\w{0,4}),(\d*)\)";
  709. //public static readonly string PropertiesPatternB = "(\\w*)\\s*\\(\\s*\"([\\w ]*)\"\\s*\\,\\s*(\\w*)\\s*.*\\)";
  710. //public static readonly string PropertiesPatternC = "^\\s*(\\w*)\\s*\\(\\s*\"([\\w\\(\\)\\+\\-\\\\* ]*)\"\\s*\\,\\s*(\\w*)\\s*.*\\)";
  711. public static readonly string PropertiesPatternD = "(\\/\\/\\s*)*(\\w*)\\s*\\(\\s*\"([\\w\\(\\)\\+\\-\\\\* ]*)\"\\s*\\,\\s*(\\w*)\\s*.*\\)";
  712. public static readonly string CullModePattern = @"\s*Cull\s+(\[*\w+\]*)";
  713. public static readonly string ColorMaskPattern = @"\s*ColorMask\s+(\[*\w+\]*)";
  714. //public static readonly string BlendModePattern = @"\s*Blend\s+(\w+)\s+(\w+)(?:[\s,]+(\w+)\s+(\w+)|)";
  715. //public static readonly string BlendModePattern = @"\s*Blend\s+(\[*\w+\]*)\s+(\[*\w+\]*)(?:[\s,]+(\[*\w+\]*)\s+(\[*\w+\]*)|)";
  716. public static readonly string BlendModePattern = @"\s*Blend\s+(?:(?=\d)|(\[*\w+\]*)\s+(\[*\w+\]*)(?:[\s,]+(\[*\w+\]*)\s+(\[*\w+\]*)|))";
  717. //public static readonly string BlendOpPattern = @"\s*BlendOp\s+(\w+)[\s,]*(?:(\w+)|)";
  718. //public static readonly string BlendOpPattern = @"\s*BlendOp\s+(\[*\w+\]*)[\s,]*(?:(\[*\w+\]*)|)";
  719. public static readonly string BlendOpPattern = @"\s*BlendOp\s+(?:(?=\d)|(\[*\w+\]*)[\s,]*(?:(\[*\w+\]*)|))";
  720. public static readonly string StencilOpGlobalPattern = @"Stencil\s*{([\w\W\s]*)}";
  721. public static readonly string StencilOpLinePattern = @"(\w+)\s*(\[*\w+\]*)";
  722. public static readonly string ShaderGlobalsOverallPattern = "(?:\\/\\*ase_pragma\\*\\/|[\\}\\#])[\\w\\s\\;\\/\\*\\.\\\"]*\\/\\*ase_globals\\*\\/";
  723. public static readonly string ShaderGlobalsMultilinePattern = @"^\s*(?:uniform\s*)*(\w*)\s*(\w*);$";
  724. public static readonly string TexSemantic = "float4 {0} : TEXCOORD{1};";
  725. public static readonly string TexFullSemantic = "float4 {0} : {1};";
  726. public static readonly string InterpFullSemantic = "{0} {1} : {2};";
  727. public static readonly string BaseInterpolatorName = "ase_texcoord";
  728. public static readonly string TexUVFullSemantic = "float4 ase_texcoord{0} : TEXCOORD{0};";
  729. public static readonly string InterpMacro = "{0}({1})";
  730. public static readonly string InterpolatorDecl = Constants.VertexShaderOutputStr + ".{0} = " + Constants.VertexShaderInputStr + ".{0};";
  731. public static readonly string TemplateVariableDecl = "{0} = {1};";
  732. public static readonly string TemplateVarFormat = "{0}.{1}";
  733. public static string ReplaceAt( this string body, string oldStr, string newStr, int startIndex )
  734. {
  735. return body.Remove( startIndex, oldStr.Length ).Insert( startIndex, newStr );
  736. }
  737. public static bool FetchInvisibleInfo( string input, ref int optionsArr, ref string id, ref int idIndex )
  738. {
  739. Match match = Regex.Match( input, HidePassPattern );
  740. if( match.Success )
  741. {
  742. id = match.Value;
  743. idIndex = match.Index;
  744. if( match.Groups.Count > 1 )
  745. {
  746. string[] properties = match.Groups[ 1 ].Value.Split( ':' );
  747. for( int i = 0; i < properties.Length; i++ )
  748. {
  749. if( InvisibleOptions.ContainsKey( properties[ i ] ) )
  750. {
  751. optionsArr |= (int)InvisibleOptions[ properties[ i ] ];
  752. }
  753. }
  754. }
  755. }
  756. return match.Success;
  757. }
  758. static public string GenerateTextureSemantic( ref MasterNodeDataCollector dataCollector, int uv )
  759. {
  760. string texCoordName = BaseInterpolatorName;
  761. if( uv > 0 )
  762. {
  763. texCoordName += uv.ToString();
  764. }
  765. string texCoordData = string.Format( TexSemantic, texCoordName, uv );
  766. dataCollector.AddToVertexInput( texCoordData );
  767. dataCollector.AddToInterpolators( texCoordData );
  768. dataCollector.AddToVertexInterpolatorsDecl( string.Format( InterpolatorDecl, texCoordName ) );
  769. return texCoordName;
  770. }
  771. public static void CreatePragmaIncludeList( string data, TemplateIncludePragmaContainter includePragmaContainer )
  772. {
  773. foreach( Match match in Regex.Matches( data, GlobalDirectivesPattern, RegexOptions.Multiline ) )
  774. {
  775. if( match.Success )
  776. {
  777. includePragmaContainer.AddNativeDirective( match.Groups[ 0 ].Value );
  778. }
  779. }
  780. foreach( Match match in Regex.Matches( data, PragmasPattern, RegexOptions.Multiline ) )
  781. {
  782. if( match.Groups.Count == 2 )
  783. {
  784. includePragmaContainer.AddPragma( match.Groups[ 1 ].Value );
  785. }
  786. }
  787. foreach( Match match in Regex.Matches( data, DefinesPattern, RegexOptions.Multiline ) )
  788. {
  789. if( match.Groups.Count == 2 )
  790. {
  791. includePragmaContainer.AddDefine( match.Groups[ 1 ].Value );
  792. }
  793. }
  794. foreach( Match match in Regex.Matches( data, IncludesPattern, RegexOptions.Multiline ) )
  795. {
  796. if( match.Groups.Count == 2 )
  797. {
  798. includePragmaContainer.AddInclude( match.Groups[ 1 ].Value );
  799. }
  800. }
  801. }
  802. public static void CreateShaderPropertiesList( string propertyData, ref List<TemplateShaderPropertyData> propertiesList, ref Dictionary<string, TemplateShaderPropertyData> duplicatesHelper )
  803. {
  804. int nameIdx = (int)TemplateShaderPropertiesIdx.Name;
  805. int typeIdx = (int)TemplateShaderPropertiesIdx.Type;
  806. int inspectorNameIdx = (int)TemplateShaderPropertiesIdx.InspectorName;
  807. foreach( Match match in Regex.Matches( propertyData, PropertiesPatternD ) )
  808. {
  809. if( match.Groups.Count > 1 )
  810. {
  811. if( !match.Groups[ 1 ].Value.Contains( "//" ) )
  812. {
  813. if( !duplicatesHelper.ContainsKey( match.Groups[ nameIdx ].Value ) && PropertyToWireType.ContainsKey( match.Groups[ typeIdx ].Value ) )
  814. {
  815. TemplateShaderPropertyData newData = new TemplateShaderPropertyData( match.Groups[ inspectorNameIdx ].Value,
  816. match.Groups[ nameIdx ].Value,
  817. PropertyToWireType[ match.Groups[ typeIdx ].Value ],
  818. PropertyType.Property );
  819. propertiesList.Add( newData );
  820. duplicatesHelper.Add( newData.PropertyName, newData );
  821. }
  822. }
  823. }
  824. }
  825. }
  826. public static void CreateShaderGlobalsList( string propertyData, ref List<TemplateShaderPropertyData> propertiesList, ref Dictionary<string, TemplateShaderPropertyData> duplicatesHelper )
  827. {
  828. int typeIdx = (int)TemplateShaderGlobalsIdx.Type;
  829. int nameIdx = (int)TemplateShaderGlobalsIdx.Name;
  830. MatchCollection matchCollection = Regex.Matches( propertyData, ShaderGlobalsOverallPattern );
  831. string value = ( matchCollection.Count > 0 ) ? matchCollection[ 0 ].Groups[ 0 ].Value : propertyData;
  832. foreach( Match lineMatch in Regex.Matches( value, ShaderGlobalsMultilinePattern, RegexOptions.Multiline ) )
  833. {
  834. if( lineMatch.Groups.Count > 1 )
  835. {
  836. if( !duplicatesHelper.ContainsKey( lineMatch.Groups[ nameIdx ].Value ) && CgToWirePortType.ContainsKey( lineMatch.Groups[ typeIdx ].Value ) )
  837. {
  838. TemplateShaderPropertyData newData = new TemplateShaderPropertyData( string.Empty, lineMatch.Groups[ nameIdx ].Value,
  839. CgToWirePortType[ lineMatch.Groups[ typeIdx ].Value ],
  840. PropertyType.Global );
  841. duplicatesHelper.Add( newData.PropertyName, newData );
  842. propertiesList.Add( newData );
  843. }
  844. }
  845. }
  846. }
  847. public static void CreateStencilOps( string stencilData, ref TemplateStencilData stencilDataObj )
  848. {
  849. stencilDataObj.DataCheck = TemplateDataCheck.Invalid;
  850. MatchCollection overallGlobalMatch = Regex.Matches( stencilData, StencilOpGlobalPattern );
  851. if( overallGlobalMatch.Count == 1 && overallGlobalMatch[ 0 ].Groups.Count == 2 )
  852. {
  853. string property = string.Empty;
  854. string value = overallGlobalMatch[ 0 ].Groups[ 1 ].Value;
  855. foreach( Match match in Regex.Matches( value, StencilOpLinePattern ) )
  856. {
  857. stencilDataObj.DataCheck = TemplateDataCheck.Valid;
  858. if( match.Groups.Count == 3 )
  859. {
  860. switch( match.Groups[ 1 ].Value )
  861. {
  862. default:
  863. {
  864. stencilDataObj.DataCheck = TemplateDataCheck.Invalid;
  865. return;
  866. }
  867. case "Ref":
  868. {
  869. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  870. {
  871. stencilDataObj.ReferenceInline = property;
  872. }
  873. else
  874. {
  875. try
  876. {
  877. stencilDataObj.Reference = Convert.ToInt32( match.Groups[ 2 ].Value );
  878. }
  879. catch( Exception e )
  880. {
  881. Debug.LogException( e );
  882. stencilDataObj.DataCheck = TemplateDataCheck.Invalid;
  883. return;
  884. }
  885. }
  886. }
  887. break;
  888. case "ReadMask":
  889. {
  890. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  891. {
  892. stencilDataObj.ReadMaskInline = property;
  893. }
  894. else
  895. {
  896. try
  897. {
  898. stencilDataObj.ReadMask = Convert.ToInt32( match.Groups[ 2 ].Value );
  899. }
  900. catch( Exception e )
  901. {
  902. Debug.LogException( e );
  903. stencilDataObj.DataCheck = TemplateDataCheck.Invalid;
  904. return;
  905. }
  906. }
  907. }
  908. break;
  909. case "WriteMask":
  910. {
  911. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  912. {
  913. stencilDataObj.WriteMaskInline = property;
  914. }
  915. else
  916. {
  917. try
  918. {
  919. stencilDataObj.WriteMask = Convert.ToInt32( match.Groups[ 2 ].Value );
  920. }
  921. catch( Exception e )
  922. {
  923. Debug.LogException( e );
  924. stencilDataObj.DataCheck = TemplateDataCheck.Invalid;
  925. return;
  926. }
  927. }
  928. }
  929. break;
  930. case "CompFront":
  931. case "Comp":
  932. {
  933. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  934. {
  935. stencilDataObj.ComparisonFrontInline = property;
  936. }
  937. else
  938. {
  939. stencilDataObj.ComparisonFront = match.Groups[ 2 ].Value;
  940. }
  941. }
  942. break;
  943. case "PassFront":
  944. case "Pass":
  945. {
  946. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  947. {
  948. stencilDataObj.PassFrontInline = property;
  949. }
  950. else
  951. {
  952. stencilDataObj.PassFront = match.Groups[ 2 ].Value;
  953. }
  954. }
  955. break;
  956. case "FailFront":
  957. case "Fail":
  958. {
  959. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  960. {
  961. stencilDataObj.FailFrontInline = property;
  962. }
  963. else
  964. {
  965. stencilDataObj.FailFront = match.Groups[ 2 ].Value;
  966. }
  967. }
  968. break;
  969. case "ZFail":
  970. case "ZFailFront":
  971. {
  972. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  973. {
  974. stencilDataObj.ZFailFrontInline = property;
  975. }
  976. else
  977. {
  978. stencilDataObj.ZFailFront = match.Groups[ 2 ].Value;
  979. }
  980. }
  981. break;
  982. case "CompBack":
  983. {
  984. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  985. {
  986. stencilDataObj.ComparisonBackInline = property;
  987. }
  988. else
  989. {
  990. stencilDataObj.ComparisonBack = match.Groups[ 2 ].Value;
  991. }
  992. }
  993. break;
  994. case "PassBack":
  995. {
  996. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  997. {
  998. stencilDataObj.PassBackInline = property;
  999. }
  1000. else
  1001. {
  1002. stencilDataObj.PassBack = match.Groups[ 2 ].Value;
  1003. }
  1004. }
  1005. break;
  1006. case "FailBack":
  1007. {
  1008. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  1009. {
  1010. stencilDataObj.FailBackInline = property;
  1011. }
  1012. else
  1013. {
  1014. stencilDataObj.FailBack = match.Groups[ 2 ].Value;
  1015. }
  1016. }
  1017. break;
  1018. case "ZFailBack":
  1019. {
  1020. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  1021. {
  1022. stencilDataObj.ZFailBackInline = property;
  1023. }
  1024. else
  1025. {
  1026. stencilDataObj.ZFailBack = match.Groups[ 2 ].Value;
  1027. }
  1028. }
  1029. break;
  1030. }
  1031. }
  1032. }
  1033. }
  1034. }
  1035. public static void CreateColorMask( string colorMaskData, ref TemplateColorMaskData colorMaskObj )
  1036. {
  1037. colorMaskObj.DataCheck = TemplateDataCheck.Invalid;
  1038. Match match = Regex.Match( colorMaskData, ColorMaskPattern );
  1039. if( match.Groups.Count == 2 )
  1040. {
  1041. string property = string.Empty;
  1042. if( match.Groups[ 1 ].Success && IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1043. {
  1044. colorMaskObj.InlineData = property;
  1045. colorMaskObj.DataCheck = TemplateDataCheck.Valid;
  1046. }
  1047. else
  1048. {
  1049. for( int i = 0; i < 4; i++ )
  1050. {
  1051. colorMaskObj.ColorMaskData[ i ] = false;
  1052. }
  1053. colorMaskObj.DataCheck = TemplateDataCheck.Valid;
  1054. try
  1055. {
  1056. for( int i = 0; i < match.Groups[ 1 ].Value.Length; i++ )
  1057. {
  1058. switch( Char.ToLower( match.Groups[ 1 ].Value[ i ] ) )
  1059. {
  1060. case 'r': colorMaskObj.ColorMaskData[ 0 ] = true; break;
  1061. case 'g': colorMaskObj.ColorMaskData[ 1 ] = true; break;
  1062. case 'b': colorMaskObj.ColorMaskData[ 2 ] = true; break;
  1063. case 'a': colorMaskObj.ColorMaskData[ 3 ] = true; break;
  1064. case '0':
  1065. {
  1066. for( int j = 0; j < 4; j++ )
  1067. {
  1068. colorMaskObj.ColorMaskData[ j ] = false;
  1069. }
  1070. return;
  1071. }
  1072. default:
  1073. {
  1074. colorMaskObj.DataCheck = TemplateDataCheck.Invalid;
  1075. return;
  1076. }
  1077. }
  1078. }
  1079. }
  1080. catch( Exception e )
  1081. {
  1082. Debug.LogException( e );
  1083. colorMaskObj.DataCheck = TemplateDataCheck.Invalid;
  1084. return;
  1085. }
  1086. }
  1087. }
  1088. }
  1089. public static void CreateCullMode( string cullModeData, ref TemplateCullModeData cullDataObj )
  1090. {
  1091. cullDataObj.DataCheck = TemplateDataCheck.Invalid;
  1092. Match match = Regex.Match( cullModeData, CullModePattern );
  1093. if( match.Groups.Count == 2 )
  1094. {
  1095. string property = string.Empty;
  1096. if( match.Groups[ 1 ].Success && IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1097. {
  1098. cullDataObj.InlineData = property;
  1099. cullDataObj.DataCheck = TemplateDataCheck.Valid;
  1100. }
  1101. else
  1102. {
  1103. try
  1104. {
  1105. cullDataObj.CullModeData = (CullMode)Enum.Parse( typeof( CullMode ), match.Groups[ 1 ].Value );
  1106. cullDataObj.DataCheck = TemplateDataCheck.Valid;
  1107. }
  1108. catch( Exception e )
  1109. {
  1110. cullDataObj.DataCheck = TemplateDataCheck.Invalid;
  1111. Debug.LogException( e );
  1112. return;
  1113. }
  1114. }
  1115. }
  1116. }
  1117. public static void CreateBlendMode( string blendModeData, ref TemplateBlendData blendDataObj )
  1118. {
  1119. blendDataObj.ValidBlendMode = true;
  1120. string property = string.Empty;
  1121. bool noMatches = true;
  1122. // TODO: OPTIMIZE REGEX EXPRESSIONS TO NOT CATCH EMPTY GROUPS
  1123. foreach( Match match in Regex.Matches( blendModeData, BlendModePattern ) )
  1124. {
  1125. if( match.Groups.Count == 3 )
  1126. {
  1127. if( match.Groups[ 0 ].Success &&
  1128. match.Groups[ 1 ].Success )
  1129. {
  1130. try
  1131. {
  1132. if( IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1133. {
  1134. blendDataObj.SourceFactorRGBInline = property;
  1135. }
  1136. else
  1137. {
  1138. AvailableBlendFactor sourceAll = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), match.Groups[ 1 ].Value );
  1139. blendDataObj.SourceFactorRGB = sourceAll;
  1140. }
  1141. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  1142. {
  1143. blendDataObj.DestFactorRGBInline = property;
  1144. }
  1145. else
  1146. {
  1147. AvailableBlendFactor destAll = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), match.Groups[ 2 ].Value );
  1148. blendDataObj.DestFactorRGB = destAll;
  1149. }
  1150. blendDataObj.SeparateBlendFactors = false;
  1151. blendDataObj.BlendModeOff = false;
  1152. noMatches = false;
  1153. }
  1154. catch( Exception e )
  1155. {
  1156. Debug.LogException( e );
  1157. blendDataObj.DataCheck = TemplateDataCheck.Invalid;
  1158. blendDataObj.ValidBlendMode = false;
  1159. return;
  1160. }
  1161. break;
  1162. }
  1163. }
  1164. else if( match.Groups.Count == 5 )
  1165. {
  1166. if( match.Groups[ 0 ].Success &&
  1167. match.Groups[ 1 ].Success )
  1168. {
  1169. try
  1170. {
  1171. if( IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1172. {
  1173. blendDataObj.SourceFactorRGBInline = property;
  1174. }
  1175. else
  1176. {
  1177. AvailableBlendFactor sourceRGB = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), match.Groups[ 1 ].Value );
  1178. blendDataObj.SourceFactorRGB = sourceRGB;
  1179. }
  1180. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  1181. {
  1182. blendDataObj.DestFactorRGBInline = property;
  1183. }
  1184. else
  1185. {
  1186. AvailableBlendFactor destRGB = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), match.Groups[ 2 ].Value );
  1187. blendDataObj.DestFactorRGB = destRGB;
  1188. }
  1189. if( match.Groups[ 3 ].Success && match.Groups[ 4 ].Success )
  1190. {
  1191. if( IsInlineProperty( match.Groups[ 3 ].Value, ref property ) )
  1192. {
  1193. blendDataObj.SourceFactorAlphaInline = property;
  1194. }
  1195. else
  1196. {
  1197. AvailableBlendFactor sourceA = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), match.Groups[ 3 ].Value );
  1198. blendDataObj.SourceFactorAlpha = sourceA;
  1199. }
  1200. if( IsInlineProperty( match.Groups[ 4 ].Value, ref property ) )
  1201. {
  1202. blendDataObj.DestFactorAlphaInline = property;
  1203. }
  1204. else
  1205. {
  1206. AvailableBlendFactor destA = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), match.Groups[ 4 ].Value );
  1207. blendDataObj.DestFactorAlpha = destA;
  1208. }
  1209. blendDataObj.SeparateBlendFactors = true;
  1210. }
  1211. else
  1212. {
  1213. blendDataObj.SeparateBlendFactors = false;
  1214. }
  1215. blendDataObj.BlendModeOff = false;
  1216. noMatches = false;
  1217. }
  1218. catch( Exception e )
  1219. {
  1220. Debug.LogException( e );
  1221. blendDataObj.DataCheck = TemplateDataCheck.Invalid;
  1222. blendDataObj.ValidBlendMode = false;
  1223. return;
  1224. }
  1225. break;
  1226. }
  1227. }
  1228. }
  1229. if( noMatches )
  1230. blendDataObj.ValidBlendMode = false;
  1231. }
  1232. public static void CreateBlendOp( string blendOpData, ref TemplateBlendData blendDataObj )
  1233. {
  1234. bool noMatches = true;
  1235. blendDataObj.ValidBlendOp = true;
  1236. string property = string.Empty;
  1237. // TODO: OPTIMIZE REGEX EXPRESSIONS TO NOT CATCH EMPTY GROUPS
  1238. foreach( Match match in Regex.Matches( blendOpData, BlendOpPattern, RegexOptions.None ) )
  1239. {
  1240. if( match.Groups.Count == 2 )
  1241. {
  1242. if( match.Groups[ 0 ].Success &&
  1243. match.Groups[ 1 ].Success )
  1244. {
  1245. try
  1246. {
  1247. if( IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1248. {
  1249. blendDataObj.BlendOpRGBInline = property;
  1250. }
  1251. else
  1252. {
  1253. AvailableBlendOps blendOpsAll = (AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), match.Groups[ 1 ].Value );
  1254. blendDataObj.BlendOpRGB = blendOpsAll;
  1255. }
  1256. blendDataObj.SeparateBlendOps = false;
  1257. noMatches = false;
  1258. }
  1259. catch( Exception e )
  1260. {
  1261. Debug.LogException( e );
  1262. blendDataObj.DataCheck = TemplateDataCheck.Invalid;
  1263. blendDataObj.ValidBlendOp = false;
  1264. return;
  1265. }
  1266. break;
  1267. }
  1268. }
  1269. else if( match.Groups.Count == 3 )
  1270. {
  1271. if( match.Groups[ 0 ].Success &&
  1272. match.Groups[ 1 ].Success )
  1273. {
  1274. try
  1275. {
  1276. if( IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1277. {
  1278. blendDataObj.BlendOpRGBInline = property;
  1279. }
  1280. else
  1281. {
  1282. AvailableBlendOps blendOpsRGB = (AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), match.Groups[ 1 ].Value );
  1283. blendDataObj.BlendOpRGB = blendOpsRGB;
  1284. }
  1285. if( match.Groups[ 2 ].Success )
  1286. {
  1287. if( IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  1288. {
  1289. blendDataObj.BlendOpAlphaInline = property;
  1290. }
  1291. else
  1292. {
  1293. AvailableBlendOps blendOpsA = (AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), match.Groups[ 2 ].Value );
  1294. blendDataObj.BlendOpAlpha = blendOpsA;
  1295. }
  1296. blendDataObj.SeparateBlendOps = true;
  1297. }
  1298. else
  1299. {
  1300. blendDataObj.SeparateBlendOps = false;
  1301. }
  1302. noMatches = false;
  1303. }
  1304. catch( Exception e )
  1305. {
  1306. Debug.LogException( e );
  1307. blendDataObj.DataCheck = TemplateDataCheck.Invalid;
  1308. blendDataObj.ValidBlendOp = false;
  1309. return;
  1310. }
  1311. break;
  1312. }
  1313. }
  1314. }
  1315. if( noMatches )
  1316. blendDataObj.ValidBlendOp = false;
  1317. }
  1318. public static void FetchLocalVars( string body, ref List<TemplateLocalVarData> localVarList, TemplateFunctionData vertexFunction, TemplateFunctionData fragFunction )
  1319. {
  1320. foreach( Match match in Regex.Matches( body, LocalVarPattern ) )
  1321. {
  1322. if( match.Groups.Count == 4 )
  1323. {
  1324. if( CgToWirePortType.ContainsKey( match.Groups[ 2 ].Value ) )
  1325. {
  1326. MasterNodePortCategory category;
  1327. if( fragFunction.MainBodyLocalIdx > vertexFunction.MainBodyLocalIdx )
  1328. {
  1329. if( match.Index < fragFunction.MainBodyLocalIdx )
  1330. {
  1331. category = MasterNodePortCategory.Vertex;
  1332. }
  1333. else
  1334. {
  1335. category = MasterNodePortCategory.Fragment;
  1336. }
  1337. }
  1338. else
  1339. {
  1340. if( match.Index < vertexFunction.MainBodyLocalIdx )
  1341. {
  1342. category = MasterNodePortCategory.Fragment;
  1343. }
  1344. else
  1345. {
  1346. category = MasterNodePortCategory.Vertex;
  1347. }
  1348. }
  1349. if( !string.IsNullOrEmpty( match.Groups[ 1 ].Value ) && ShortcutToInfo.ContainsKey( match.Groups[ 1 ].Value ) )
  1350. {
  1351. string id = match.Groups[ 0 ].Value.Substring( 0, match.Groups[ 0 ].Value.IndexOf( "*/" ) + 2 );
  1352. TemplateLocalVarData data = new TemplateLocalVarData( ShortcutToInfo[ match.Groups[ 1 ].Value ], id, CgToWirePortType[ match.Groups[ 2 ].Value ], category, match.Groups[ 3 ].Value, match.Index );
  1353. localVarList.Add( data );
  1354. }
  1355. else
  1356. {
  1357. TemplateLocalVarData data = new TemplateLocalVarData( CgToWirePortType[ match.Groups[ 2 ].Value ], category, match.Groups[ 3 ].Value, match.Index );
  1358. localVarList.Add( data );
  1359. }
  1360. }
  1361. }
  1362. }
  1363. }
  1364. public static TemplateSRPType CreateTags( ref TemplateTagsModuleData tagsObj, bool isSubShader )
  1365. {
  1366. TemplateSRPType srpType = TemplateSRPType.BuiltIn;
  1367. MatchCollection matchColl = Regex.Matches( tagsObj.TagsId, TagsPattern, RegexOptions.IgnorePatternWhitespace );
  1368. int count = matchColl.Count;
  1369. if( count > 0 )
  1370. {
  1371. for( int i = 0; i < count; i++ )
  1372. {
  1373. if( matchColl[ i ].Groups.Count == 3 )
  1374. {
  1375. if( isSubShader && matchColl[ i ].Groups[ 1 ].Value.Equals( "RenderPipeline" ) )
  1376. {
  1377. if( TagToRenderPipeline.ContainsKey( matchColl[ i ].Groups[ 2 ].Value ) )
  1378. srpType = TagToRenderPipeline[ matchColl[ i ].Groups[ 2 ].Value ];
  1379. }
  1380. tagsObj.Tags.Add( new TemplatesTagData( matchColl[ i ].Groups[ 1 ].Value, matchColl[ i ].Groups[ 2 ].Value ) );
  1381. }
  1382. }
  1383. }
  1384. return srpType;
  1385. }
  1386. public static void CreateZWriteMode( string zWriteData, ref TemplateDepthData depthDataObj )
  1387. {
  1388. depthDataObj.DataCheck = TemplateDataCheck.Invalid;
  1389. Match match = Regex.Match( zWriteData, ZWritePattern );
  1390. if( match.Groups.Count == 2 )
  1391. {
  1392. string property = string.Empty;
  1393. if( match.Groups[ 1 ].Success && IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1394. {
  1395. depthDataObj.ZWriteInlineValue = property;
  1396. depthDataObj.DataCheck = TemplateDataCheck.Valid;
  1397. depthDataObj.ValidZWrite = true;
  1398. }
  1399. else
  1400. {
  1401. try
  1402. {
  1403. depthDataObj.ZWriteModeValue = (ZWriteMode)Enum.Parse( typeof( ZWriteMode ), match.Groups[ 1 ].Value );
  1404. depthDataObj.DataCheck = TemplateDataCheck.Valid;
  1405. depthDataObj.ValidZWrite = true;
  1406. }
  1407. catch
  1408. {
  1409. depthDataObj.DataCheck = TemplateDataCheck.Invalid;
  1410. }
  1411. }
  1412. }
  1413. }
  1414. public static void CreateZTestMode( string zTestData, ref TemplateDepthData depthDataObj )
  1415. {
  1416. depthDataObj.DataCheck = TemplateDataCheck.Invalid;
  1417. Match match = Regex.Match( zTestData, ZTestPattern );
  1418. if( match.Groups.Count == 2 )
  1419. {
  1420. string property = string.Empty;
  1421. if( match.Groups[ 1 ].Success && IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1422. {
  1423. depthDataObj.ZTestInlineValue = property;
  1424. depthDataObj.DataCheck = TemplateDataCheck.Valid;
  1425. depthDataObj.ValidZTest = true;
  1426. }
  1427. else
  1428. {
  1429. try
  1430. {
  1431. depthDataObj.ZTestModeValue = (ZTestMode)Enum.Parse( typeof( ZTestMode ), match.Groups[ 1 ].Value );
  1432. depthDataObj.DataCheck = TemplateDataCheck.Valid;
  1433. depthDataObj.ValidZTest = true;
  1434. }
  1435. catch
  1436. {
  1437. depthDataObj.DataCheck = TemplateDataCheck.Invalid;
  1438. }
  1439. }
  1440. }
  1441. }
  1442. public static void CreateZOffsetMode( string zOffsetData, ref TemplateDepthData depthDataObj )
  1443. {
  1444. depthDataObj.DataCheck = TemplateDataCheck.Invalid;
  1445. Match match = Regex.Match( zOffsetData, ZOffsetPattern );
  1446. if( match.Groups.Count == 3 )
  1447. {
  1448. try
  1449. {
  1450. string property = string.Empty;
  1451. if( match.Groups[ 1 ].Success && IsInlineProperty( match.Groups[ 1 ].Value, ref property ) )
  1452. {
  1453. depthDataObj.OffsetFactorInlineValue = property;
  1454. }
  1455. else
  1456. {
  1457. depthDataObj.OffsetFactor = Convert.ToSingle( match.Groups[ 1 ].Value );
  1458. }
  1459. if( match.Groups[ 2 ].Success && IsInlineProperty( match.Groups[ 2 ].Value, ref property ) )
  1460. {
  1461. depthDataObj.OffsetUnitsInlineValue = property;
  1462. }
  1463. else
  1464. {
  1465. depthDataObj.OffsetUnits = Convert.ToSingle( match.Groups[ 2 ].Value );
  1466. }
  1467. depthDataObj.ValidOffset = true;
  1468. depthDataObj.DataCheck = TemplateDataCheck.Valid;
  1469. }
  1470. catch
  1471. {
  1472. depthDataObj.DataCheck = TemplateDataCheck.Invalid;
  1473. }
  1474. }
  1475. }
  1476. public static List<TemplateVertexData> CreateVertexDataList( string vertexData, string parametersBody )
  1477. {
  1478. List<TemplateVertexData> vertexDataList = null;
  1479. Dictionary<TemplateSemantics, TemplateVertexData> vertexDataDict = null;
  1480. foreach( Match match in Regex.Matches( vertexData, VertexDataPattern ) )
  1481. {
  1482. if( match.Groups.Count > 1 )
  1483. {
  1484. if( vertexDataList == null )
  1485. {
  1486. vertexDataList = new List<TemplateVertexData>();
  1487. vertexDataDict = new Dictionary<TemplateSemantics, TemplateVertexData>();
  1488. }
  1489. WirePortDataType dataType = CgToWirePortType[ match.Groups[ 1 ].Value ];
  1490. string varName = match.Groups[ 2 ].Value;
  1491. TemplateSemantics semantics = (TemplateSemantics)Enum.Parse( typeof( TemplateSemantics ), match.Groups[ 3 ].Value );
  1492. TemplateVertexData templateVertexData = new TemplateVertexData( semantics, dataType, varName );
  1493. vertexDataList.Add( templateVertexData );
  1494. vertexDataDict.Add( semantics, templateVertexData );
  1495. }
  1496. }
  1497. if( !string.IsNullOrEmpty( parametersBody ) )
  1498. {
  1499. string[] paramsArray = parametersBody.Split( IOUtils.FIELD_SEPARATOR );
  1500. if( paramsArray.Length > 0 )
  1501. {
  1502. for( int i = 0; i < paramsArray.Length; i++ )
  1503. {
  1504. string[] paramDataArr = paramsArray[ i ].Split( IOUtils.VALUE_SEPARATOR );
  1505. if( paramDataArr.Length == 2 )
  1506. {
  1507. string[] swizzleInfoArr = paramDataArr[ 1 ].Split( IOUtils.FLOAT_SEPARATOR );
  1508. TemplateSemantics semantic = ShortcutToSemantic[ swizzleInfoArr[ 0 ] ];
  1509. if( vertexDataDict.ContainsKey( semantic ) )
  1510. {
  1511. TemplateVertexData templateVertexData = vertexDataDict[ semantic ];
  1512. if( templateVertexData != null )
  1513. {
  1514. if( swizzleInfoArr.Length > 1 )
  1515. {
  1516. templateVertexData.DataSwizzle = "." + swizzleInfoArr[ 1 ];
  1517. }
  1518. templateVertexData.DataInfo = ShortcutToInfo[ paramDataArr[ 0 ] ];
  1519. templateVertexData.Available = true;
  1520. }
  1521. }
  1522. }
  1523. }
  1524. }
  1525. }
  1526. if( vertexDataDict != null )
  1527. {
  1528. vertexDataDict.Clear();
  1529. vertexDataDict = null;
  1530. }
  1531. return vertexDataList;
  1532. }
  1533. public static TemplateInterpData CreateInterpDataList( string interpData, string fullLine, int maxInterpolators )
  1534. {
  1535. TemplateInterpData interpDataObj = null;
  1536. List<TemplateVertexData> interpDataList = null;
  1537. Dictionary<TemplateSemantics, TemplateVertexData> interpDataDict = null;
  1538. Match rangeMatch = Regex.Match( fullLine, InterpRangePattern );
  1539. if( rangeMatch.Groups.Count > 0 )
  1540. {
  1541. interpDataObj = new TemplateInterpData();
  1542. // Get range of available interpolators
  1543. int minVal = 0;
  1544. int maxVal = 0;
  1545. try
  1546. {
  1547. string[] minValArgs = rangeMatch.Groups[ 1 ].Value.Split( IOUtils.FLOAT_SEPARATOR );
  1548. minVal = Convert.ToInt32( minValArgs[ 0 ] );
  1549. if( string.IsNullOrEmpty( rangeMatch.Groups[ 2 ].Value ) )
  1550. {
  1551. maxVal = maxInterpolators - 1;
  1552. interpDataObj.DynamicMax = true;
  1553. }
  1554. else
  1555. {
  1556. maxVal = Convert.ToInt32( rangeMatch.Groups[ 2 ].Value );
  1557. }
  1558. if( minVal > maxVal )
  1559. {
  1560. int aux = minVal;
  1561. minVal = maxVal;
  1562. maxVal = aux;
  1563. }
  1564. for( int i = minVal; i <= maxVal; i++ )
  1565. {
  1566. interpDataObj.AvailableInterpolators.Add( new TemplateInterpElement( IntToSemantic[ i ] ) );
  1567. }
  1568. if( minValArgs.Length > 1 )
  1569. {
  1570. interpDataObj.AvailableInterpolators[ 0 ].SetAvailableChannelsFromString( minValArgs[ 1 ] );
  1571. }
  1572. }
  1573. catch( Exception e )
  1574. {
  1575. Debug.LogException( e );
  1576. }
  1577. interpDataList = new List<TemplateVertexData>();
  1578. interpDataDict = new Dictionary<TemplateSemantics, TemplateVertexData>();
  1579. //Get Current interpolators
  1580. int parametersBeginIdx = fullLine.IndexOf( ":" ) + 1;
  1581. int parametersEnd = fullLine.IndexOf( TemplatesManager.TemplateEndOfLine );
  1582. string parametersBody = fullLine.Substring( parametersBeginIdx, parametersEnd - parametersBeginIdx );
  1583. foreach( Match match in Regex.Matches( interpData, VertexDataPattern ) )
  1584. {
  1585. if( match.Groups.Count > 1 )
  1586. {
  1587. WirePortDataType dataType = CgToWirePortType[ match.Groups[ 1 ].Value ];
  1588. string varName = match.Groups[ 2 ].Value;
  1589. TemplateSemantics semantics = (TemplateSemantics)Enum.Parse( typeof( TemplateSemantics ), match.Groups[ 3 ].Value );
  1590. TemplateVertexData templateVertexData = new TemplateVertexData( semantics, dataType, varName );
  1591. //interpDataList.Add( templateVertexData );
  1592. interpDataDict.Add( semantics, templateVertexData );
  1593. interpDataObj.RawInterpolators.Add( templateVertexData );
  1594. //Check if they are also on the free channels list and update their names
  1595. interpDataObj.ReplaceNameOnInterpolator( semantics, varName );
  1596. }
  1597. }
  1598. Dictionary<string, TemplateVertexData> auxDict = new Dictionary<string, TemplateVertexData>();
  1599. // Get info for available interpolators
  1600. string[] paramsArray = parametersBody.Split( IOUtils.FIELD_SEPARATOR );
  1601. if( paramsArray.Length > 0 )
  1602. {
  1603. for( int i = 0; i < paramsArray.Length; i++ )
  1604. {
  1605. string[] paramDataArr = paramsArray[ i ].Split( IOUtils.VALUE_SEPARATOR );
  1606. if( paramDataArr.Length == 2 )
  1607. {
  1608. string[] swizzleInfoArr = paramDataArr[ 1 ].Split( IOUtils.FLOAT_SEPARATOR );
  1609. TemplateSemantics semantic = ShortcutToSemantic[ swizzleInfoArr[ 0 ] ];
  1610. if( interpDataDict.ContainsKey( semantic ) )
  1611. {
  1612. if( interpDataDict[ semantic ] != null )
  1613. {
  1614. string[] multiComponent = paramDataArr[ 0 ].Split( IOUtils.FLOAT_SEPARATOR );
  1615. if( multiComponent.Length > 1 )
  1616. {
  1617. TemplateVertexData templateInterpData = null;
  1618. if( auxDict.ContainsKey( multiComponent[ 0 ] ) )
  1619. {
  1620. templateInterpData = auxDict[ multiComponent[ 0 ] ];
  1621. }
  1622. else
  1623. {
  1624. templateInterpData = new TemplateVertexData( interpDataDict[ semantic ] );
  1625. //if( swizzleInfoArr.Length > 1 )
  1626. //{
  1627. // templateInterpData.DataSwizzle = "." + swizzleInfoArr[ 1 ];
  1628. //}
  1629. templateInterpData.DataInfo = ShortcutToInfo[ multiComponent[ 0 ] ];
  1630. templateInterpData.Available = true;
  1631. interpDataList.Add( templateInterpData );
  1632. auxDict.Add( multiComponent[ 0 ], templateInterpData );
  1633. }
  1634. if( swizzleInfoArr[ 1 ].Length == multiComponent[ 1 ].Length )
  1635. {
  1636. for( int channelIdx = 0; channelIdx < swizzleInfoArr[ 1 ].Length; channelIdx++ )
  1637. {
  1638. templateInterpData.RegisterComponent( multiComponent[ 1 ][ channelIdx ], interpDataDict[ semantic ].VarName + "." + swizzleInfoArr[ 1 ][ channelIdx ] );
  1639. }
  1640. }
  1641. }
  1642. else
  1643. {
  1644. TemplateVertexData templateInterpData = new TemplateVertexData( interpDataDict[ semantic ] );
  1645. if( swizzleInfoArr.Length > 1 )
  1646. {
  1647. templateInterpData.DataSwizzle = "." + swizzleInfoArr[ 1 ];
  1648. }
  1649. templateInterpData.DataInfo = ShortcutToInfo[ paramDataArr[ 0 ] ];
  1650. templateInterpData.Available = true;
  1651. interpDataList.Add( templateInterpData );
  1652. }
  1653. }
  1654. }
  1655. }
  1656. }
  1657. }
  1658. /*TODO:
  1659. 1) Remove interpDataList.Add( templateVertexData ); from initial foreach
  1660. 2) When looping though each foreach array element, create a new TemplateVertexData
  1661. from the one containted on the interpDataDict and add it to interpDataList
  1662. */
  1663. for( int i = 0; i < interpDataList.Count; i++ )
  1664. {
  1665. interpDataList[ i ].BuildVar();
  1666. }
  1667. auxDict.Clear();
  1668. auxDict = null;
  1669. interpDataObj.Interpolators = interpDataList;
  1670. interpDataDict.Clear();
  1671. interpDataDict = null;
  1672. }
  1673. return interpDataObj;
  1674. }
  1675. public static void FetchDependencies( TemplateInfoContainer dependencies, ref string body )
  1676. {
  1677. int index = body.IndexOf( TemplatesManager.TemplateDependenciesListTag );
  1678. if( index > 0 )
  1679. {
  1680. dependencies.Index = index;
  1681. dependencies.Id = TemplatesManager.TemplateDependenciesListTag;
  1682. dependencies.Data = TemplatesManager.TemplateDependenciesListTag;
  1683. }
  1684. else
  1685. {
  1686. int lastIndex = body.LastIndexOf( '}' );
  1687. if( lastIndex > 0 )
  1688. {
  1689. body = body.Insert( lastIndex, "\t" + TemplatesManager.TemplateDependenciesListTag + "\n" );
  1690. FetchDependencies( dependencies, ref body );
  1691. }
  1692. }
  1693. }
  1694. public static void FetchCustomInspector( TemplateInfoContainer inspectorContainer, ref string body )
  1695. {
  1696. Match match = Regex.Match( body, CustomInspectorPattern, RegexOptions.Multiline );
  1697. if( match != null && match.Groups.Count > 1 )
  1698. {
  1699. inspectorContainer.Index = match.Index;
  1700. inspectorContainer.Id = match.Groups[ 0 ].Value;
  1701. inspectorContainer.Data = match.Groups[ 1 ].Value;
  1702. }
  1703. else
  1704. {
  1705. int index = body.LastIndexOf( '}' );
  1706. if( index > 0 )
  1707. {
  1708. body = body.Insert( index, string.Format( "\tCustomEditor \"{0}\"\n", Constants.DefaultCustomInspector ) );
  1709. FetchCustomInspector( inspectorContainer, ref body );
  1710. }
  1711. }
  1712. }
  1713. public static void FetchFallback( TemplateInfoContainer fallbackContainer, ref string body )
  1714. {
  1715. Match match = Regex.Match( body, FallbackPattern, RegexOptions.Multiline );
  1716. if( match != null && match.Groups.Count > 1 )
  1717. {
  1718. fallbackContainer.Index = match.Index;
  1719. fallbackContainer.Id = match.Groups[ 0 ].Value;
  1720. fallbackContainer.Data = match.Groups[ 1 ].Value;
  1721. }
  1722. else
  1723. {
  1724. int index = body.LastIndexOf( '}' );
  1725. if( index > 0 )
  1726. {
  1727. body = body.Insert( index, "\tFallback \"\"\n" );
  1728. FetchFallback( fallbackContainer, ref body );
  1729. }
  1730. }
  1731. }
  1732. public static string AutoSwizzleData( string dataVar, WirePortDataType from, WirePortDataType to )
  1733. {
  1734. switch( from )
  1735. {
  1736. case WirePortDataType.COLOR:
  1737. case WirePortDataType.FLOAT4:
  1738. {
  1739. switch( to )
  1740. {
  1741. case WirePortDataType.FLOAT3: dataVar += ".xyz"; break;
  1742. case WirePortDataType.FLOAT2: dataVar += ".xy"; break;
  1743. case WirePortDataType.INT:
  1744. case WirePortDataType.FLOAT: dataVar += ".x"; break;
  1745. }
  1746. }
  1747. break;
  1748. case WirePortDataType.FLOAT3:
  1749. {
  1750. switch( to )
  1751. {
  1752. case WirePortDataType.FLOAT4: dataVar = string.Format( "float4({0},0)", dataVar ); break;
  1753. case WirePortDataType.FLOAT2: dataVar += ".xy"; break;
  1754. case WirePortDataType.INT:
  1755. case WirePortDataType.FLOAT: dataVar += ".x"; break;
  1756. }
  1757. }
  1758. break;
  1759. case WirePortDataType.FLOAT2:
  1760. {
  1761. switch( to )
  1762. {
  1763. case WirePortDataType.FLOAT4: dataVar = string.Format( "float4({0},0,0)", dataVar ); break;
  1764. case WirePortDataType.FLOAT3: dataVar = string.Format( "float3({0},0)", dataVar ); break;
  1765. case WirePortDataType.INT:
  1766. case WirePortDataType.FLOAT: dataVar += ".x"; break;
  1767. }
  1768. }
  1769. break;
  1770. case WirePortDataType.FLOAT:
  1771. {
  1772. switch( to )
  1773. {
  1774. case WirePortDataType.FLOAT4: dataVar = string.Format( "float4({0},0,0,0)", dataVar ); break;
  1775. case WirePortDataType.FLOAT3: dataVar = string.Format( "float3({0},0,0)", dataVar ); break;
  1776. case WirePortDataType.FLOAT2: dataVar = string.Format( "float2({0},0)", dataVar ); break;
  1777. }
  1778. }
  1779. break;
  1780. }
  1781. return dataVar;
  1782. }
  1783. public static bool CheckIfTemplate( string assetPath )
  1784. {
  1785. Shader shader = AssetDatabase.LoadAssetAtPath<Shader>( assetPath );
  1786. if( shader != null )
  1787. {
  1788. string body = IOUtils.LoadTextFileFromDisk( assetPath );
  1789. return ( body.IndexOf( TemplatesManager.TemplateShaderNameBeginTag ) > -1 );
  1790. }
  1791. return false;
  1792. }
  1793. public static bool CheckIfCompatibles( WirePortDataType first, WirePortDataType second )
  1794. {
  1795. switch( first )
  1796. {
  1797. case WirePortDataType.OBJECT:
  1798. return true;
  1799. case WirePortDataType.FLOAT:
  1800. case WirePortDataType.FLOAT2:
  1801. case WirePortDataType.FLOAT3:
  1802. case WirePortDataType.FLOAT4:
  1803. case WirePortDataType.COLOR:
  1804. case WirePortDataType.INT:
  1805. {
  1806. switch( second )
  1807. {
  1808. case WirePortDataType.FLOAT3x3:
  1809. case WirePortDataType.FLOAT4x4:
  1810. case WirePortDataType.SAMPLER1D:
  1811. case WirePortDataType.SAMPLER2D:
  1812. case WirePortDataType.SAMPLER3D:
  1813. case WirePortDataType.SAMPLERCUBE:
  1814. return false;
  1815. }
  1816. }
  1817. break;
  1818. case WirePortDataType.FLOAT3x3:
  1819. case WirePortDataType.FLOAT4x4:
  1820. {
  1821. switch( second )
  1822. {
  1823. case WirePortDataType.FLOAT:
  1824. case WirePortDataType.FLOAT2:
  1825. case WirePortDataType.FLOAT3:
  1826. case WirePortDataType.FLOAT4:
  1827. case WirePortDataType.COLOR:
  1828. case WirePortDataType.INT:
  1829. case WirePortDataType.SAMPLER1D:
  1830. case WirePortDataType.SAMPLER2D:
  1831. case WirePortDataType.SAMPLER3D:
  1832. case WirePortDataType.SAMPLERCUBE:
  1833. return false;
  1834. }
  1835. }
  1836. break;
  1837. case WirePortDataType.SAMPLER1D:
  1838. case WirePortDataType.SAMPLER2D:
  1839. case WirePortDataType.SAMPLER3D:
  1840. case WirePortDataType.SAMPLERCUBE:
  1841. {
  1842. switch( second )
  1843. {
  1844. case WirePortDataType.FLOAT:
  1845. case WirePortDataType.FLOAT2:
  1846. case WirePortDataType.FLOAT3:
  1847. case WirePortDataType.FLOAT4:
  1848. case WirePortDataType.FLOAT3x3:
  1849. case WirePortDataType.FLOAT4x4:
  1850. case WirePortDataType.COLOR:
  1851. case WirePortDataType.INT:
  1852. return false;
  1853. }
  1854. }
  1855. break;
  1856. }
  1857. return true;
  1858. }
  1859. // Lightweight <-> Default functions
  1860. public static string WorldSpaceViewDir( MasterNodeDataCollector dataCollector, string worldPosVec3, bool normalize )
  1861. {
  1862. string value = string.Empty;
  1863. if( dataCollector.IsTemplate && dataCollector.IsSRP )
  1864. {
  1865. value = string.Format( "_WorldSpaceCameraPos.xyz - {0}", worldPosVec3 );
  1866. }
  1867. else
  1868. {
  1869. value = string.Format( "UnityWorldSpaceViewDir( {0} )", worldPosVec3 );
  1870. }
  1871. if( normalize )
  1872. {
  1873. value = SafeNormalize( dataCollector, value );
  1874. }
  1875. return value;
  1876. }
  1877. public static string SafeNormalize( MasterNodeDataCollector dataCollector, string value )
  1878. {
  1879. if( dataCollector.IsTemplate && dataCollector.IsSRP )
  1880. {
  1881. value = string.Format( "SafeNormalize( {0} )", value );
  1882. }
  1883. else
  1884. {
  1885. dataCollector.AddToIncludes( -1, Constants.UnityBRDFLib );
  1886. value = string.Format( "Unity_SafeNormalize( {0} )", value );
  1887. }
  1888. return value;
  1889. }
  1890. public static string CreateUnpackNormalStr( MasterNodeDataCollector dataCollector, bool applyScale, string scale )
  1891. {
  1892. string funcName;
  1893. if( dataCollector.IsTemplate && dataCollector.IsSRP )
  1894. {
  1895. funcName = "UnpackNormalmapRGorAG( {0}, " + scale + " )";
  1896. }
  1897. else
  1898. {
  1899. funcName = applyScale ? "UnpackScaleNormal( {0}, " + scale + " )" : "UnpackNormal( {0} )";
  1900. }
  1901. return funcName;
  1902. }
  1903. public static bool IsInlineProperty( string data, ref string property )
  1904. {
  1905. if( data.Length > 0 && data[ 0 ] == '[' && data[ data.Length - 1 ] == ']' )
  1906. {
  1907. property = data.Substring( 1, data.Length - 2 );
  1908. return true;
  1909. }
  1910. return false;
  1911. }
  1912. public static readonly string FetchDefaultDepthFormat = "UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture,UNITY_PROJ_COORD( {0} )))";
  1913. public static readonly string FetchLWDepthFormat = "tex2Dproj( _CameraDepthTexture, {0} ).r";
  1914. #if UNITY_2018_3_OR_NEWER
  1915. public static readonly string FetchHDDepthFormat = " SampleCameraDepth( {0}.xy/{0}.w ).r";
  1916. #else
  1917. public static readonly string FetchHDDepthFormat = " SAMPLE_TEXTURE2D( _CameraDepthTexture, s_point_clamp_sampler,{0}.xy/{0}.w ).r";
  1918. #endif
  1919. public static string CreateDepthFetch( MasterNodeDataCollector dataCollector, string screenPos )
  1920. {
  1921. string screenDepthInstruction = string.Empty;
  1922. if( dataCollector.IsTemplate && dataCollector.IsSRP )
  1923. {
  1924. if( dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.Lightweight )
  1925. screenDepthInstruction = string.Format( FetchLWDepthFormat, screenPos );
  1926. else if( dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD )
  1927. screenDepthInstruction = string.Format( FetchHDDepthFormat, screenPos );
  1928. }
  1929. else
  1930. {
  1931. screenDepthInstruction = string.Format( FetchDefaultDepthFormat, screenPos );
  1932. }
  1933. return screenDepthInstruction;
  1934. }
  1935. }
  1936. }