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.

459 lines
17 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. namespace AmplifyShaderEditor
  7. {
  8. public enum TemplateModuleDataType
  9. {
  10. ModuleShaderModel,
  11. ModuleBlendMode,
  12. ModuleBlendOp,
  13. ModuleAlphaToMask,
  14. ModuleCullMode,
  15. ModuleColorMask,
  16. ModuleStencil,
  17. ModuleZwrite,
  18. ModuleZTest,
  19. ModuleZOffset,
  20. ModuleTag,
  21. ModuleGlobals,
  22. ModuleFunctions,
  23. ModulePragma,
  24. ModulePass,
  25. ModuleInputVert,
  26. ModuleInputFrag,
  27. PassVertexFunction,
  28. PassFragmentFunction,
  29. PassVertexData,
  30. PassInterpolatorData,
  31. PassNameData,
  32. AllModules
  33. //EndPass
  34. }
  35. public enum TemplateSRPType
  36. {
  37. BuiltIn,
  38. HD,
  39. Lightweight
  40. }
  41. [Serializable]
  42. public class TemplateModulesData
  43. {
  44. [SerializeField]
  45. private TemplateBlendData m_blendData = new TemplateBlendData();
  46. [SerializeField]
  47. private TemplateCullModeData m_cullModeData = new TemplateCullModeData();
  48. [SerializeField]
  49. private TemplateColorMaskData m_colorMaskData = new TemplateColorMaskData();
  50. [SerializeField]
  51. private TemplateStencilData m_stencilData = new TemplateStencilData();
  52. [SerializeField]
  53. private TemplateDepthData m_depthData = new TemplateDepthData();
  54. [SerializeField]
  55. private TemplateTagsModuleData m_tagData = new TemplateTagsModuleData();
  56. [SerializeField]
  57. private TemplateTagData m_globalsTag = new TemplateTagData( TemplatesManager.TemplateGlobalsTag, true );
  58. [SerializeField]
  59. private TemplateTagData m_allModulesTag = new TemplateTagData( TemplatesManager.TemplateAllModulesTag, true );
  60. [SerializeField]
  61. private TemplateTagData m_functionsTag = new TemplateTagData( TemplatesManager.TemplateFunctionsTag, true );
  62. [SerializeField]
  63. private TemplateTagData m_pragmaTag = new TemplateTagData( TemplatesManager.TemplatePragmaTag, true );
  64. [SerializeField]
  65. private TemplateTagData m_passTag = new TemplateTagData( TemplatesManager.TemplatePassTag, true );
  66. [SerializeField]
  67. private TemplateTagData m_inputsVertTag = new TemplateTagData( TemplatesManager.TemplateInputsVertParamsTag, false );
  68. [SerializeField]
  69. private TemplateTagData m_inputsFragTag = new TemplateTagData( TemplatesManager.TemplateInputsFragParamsTag, false );
  70. [SerializeField]
  71. private TemplateShaderModelData m_shaderModel = new TemplateShaderModelData();
  72. [SerializeField]
  73. private TemplateSRPType m_srpType = TemplateSRPType.BuiltIn;
  74. [SerializeField]
  75. private bool m_srpIsPBR = false;
  76. [SerializeField]
  77. private string m_uniquePrefix;
  78. [SerializeField]
  79. private TemplateIncludePragmaContainter m_includePragmaContainer = new TemplateIncludePragmaContainter();
  80. [SerializeField]
  81. private bool m_allModulesMode = false;
  82. public void Destroy()
  83. {
  84. m_blendData = null;
  85. m_cullModeData = null;
  86. m_colorMaskData = null;
  87. m_stencilData = null;
  88. m_depthData = null;
  89. m_tagData.Destroy();
  90. m_tagData = null;
  91. m_globalsTag = null;
  92. m_allModulesTag = null;
  93. m_functionsTag = null;
  94. m_pragmaTag = null;
  95. m_passTag = null;
  96. m_inputsVertTag = null;
  97. m_inputsFragTag = null;
  98. m_includePragmaContainer.Destroy();
  99. m_includePragmaContainer = null;
  100. }
  101. public void ConfigureCommonTag( TemplateTagData tagData, TemplatePropertyContainer propertyContainer, TemplateIdManager idManager, string uniquePrefix, int offsetIdx, string subBody )
  102. {
  103. int id = subBody.IndexOf( tagData.Id );
  104. if ( id >= 0 )
  105. {
  106. tagData.StartIdx = offsetIdx + id;
  107. idManager.RegisterId( tagData.StartIdx, uniquePrefix + tagData.Id, tagData.Id );
  108. propertyContainer.AddId( subBody, tagData.Id, tagData.SearchIndentation );
  109. }
  110. }
  111. public TemplateModulesData( TemplateIdManager idManager, TemplatePropertyContainer propertyContainer, string uniquePrefix, int offsetIdx, string subBody, bool isSubShader )
  112. {
  113. if ( string.IsNullOrEmpty( subBody ) )
  114. return;
  115. m_uniquePrefix = uniquePrefix;
  116. //PRAGMAS AND INCLUDES
  117. TemplateHelperFunctions.CreatePragmaIncludeList( subBody, m_includePragmaContainer );
  118. //COMMON TAGS
  119. ConfigureCommonTag( m_globalsTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  120. ConfigureCommonTag( m_functionsTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  121. ConfigureCommonTag( m_pragmaTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  122. ConfigureCommonTag( m_passTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  123. ConfigureCommonTag( m_inputsVertTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  124. ConfigureCommonTag( m_inputsFragTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  125. //BlEND MODE
  126. {
  127. Match blendModeMatch = Regex.Match( subBody, TemplateHelperFunctions.BlendWholeWordPattern );
  128. if( blendModeMatch.Success )
  129. {
  130. int blendModeIdx = blendModeMatch.Index;
  131. int end = subBody.IndexOf( TemplatesManager.TemplateNewLine, blendModeIdx );
  132. string blendParams = subBody.Substring( blendModeIdx, end - blendModeIdx );
  133. m_blendData.BlendModeId = blendParams;
  134. m_blendData.BlendModeStartIndex = offsetIdx + blendModeIdx;
  135. idManager.RegisterId( m_blendData.BlendModeStartIndex, uniquePrefix + m_blendData.BlendModeId, m_blendData.BlendModeId );
  136. TemplateHelperFunctions.CreateBlendMode( blendParams, ref m_blendData );
  137. if( m_blendData.ValidBlendMode )
  138. {
  139. propertyContainer.AddId( subBody, blendParams, false );
  140. }
  141. }
  142. }
  143. //BLEND OP
  144. {
  145. Match blendOpMatch = Regex.Match( subBody, TemplateHelperFunctions.BlendOpWholeWordPattern );
  146. if( blendOpMatch.Success )
  147. {
  148. int blendOpIdx = blendOpMatch.Index;
  149. int end = subBody.IndexOf( TemplatesManager.TemplateNewLine, blendOpIdx );
  150. string blendOpParams = subBody.Substring( blendOpIdx, end - blendOpIdx );
  151. m_blendData.BlendOpId = blendOpParams;
  152. BlendData.BlendOpStartIndex = offsetIdx + blendOpIdx;
  153. idManager.RegisterId( m_blendData.BlendOpStartIndex, uniquePrefix + m_blendData.BlendOpId, m_blendData.BlendOpId );
  154. TemplateHelperFunctions.CreateBlendOp( blendOpParams, ref m_blendData );
  155. if( m_blendData.ValidBlendOp )
  156. {
  157. propertyContainer.AddId( subBody, blendOpParams, false );
  158. }
  159. }
  160. }
  161. //ALPHA TO MASK
  162. {
  163. Match alphaToMaskMatch = Regex.Match( subBody, TemplateHelperFunctions.ALphaToMaskPattern );
  164. if( alphaToMaskMatch.Success )
  165. {
  166. m_blendData.ValidAlphaToMask = true;
  167. m_blendData.AlphaToMaskId = alphaToMaskMatch.Groups[ 0 ].Value;
  168. if( alphaToMaskMatch.Groups.Count > 1 )
  169. m_blendData.AlphaToMaskValue = alphaToMaskMatch.Groups[ 1 ].Value.Equals( "On" ) ? true : false;
  170. m_blendData.IndependentAlphaToMask = true;
  171. idManager.RegisterId( offsetIdx + alphaToMaskMatch.Index, uniquePrefix + m_blendData.AlphaToMaskId, m_blendData.AlphaToMaskId );
  172. propertyContainer.AddId( subBody, m_blendData.AlphaToMaskId, false );
  173. }
  174. m_blendData.DataCheck = ( m_blendData.ValidBlendMode || m_blendData.ValidBlendOp || m_blendData.ValidAlphaToMask ) ? TemplateDataCheck.Valid : TemplateDataCheck.Invalid;
  175. }
  176. //CULL MODE
  177. {
  178. Match cullMatch = Regex.Match( subBody, TemplateHelperFunctions.CullWholeWordPattern );
  179. if( cullMatch.Success )
  180. {
  181. int cullIdx = cullMatch.Index;
  182. int end = subBody.IndexOf( TemplatesManager.TemplateNewLine, cullIdx );
  183. string cullParams = subBody.Substring( cullIdx, end - cullIdx );
  184. m_cullModeData.CullModeId = cullParams;
  185. m_cullModeData.StartIdx = offsetIdx + cullIdx;
  186. idManager.RegisterId( m_cullModeData.StartIdx, uniquePrefix + m_cullModeData.CullModeId, m_cullModeData.CullModeId );
  187. TemplateHelperFunctions.CreateCullMode( cullParams, ref m_cullModeData );
  188. if( m_cullModeData.DataCheck == TemplateDataCheck.Valid )
  189. propertyContainer.AddId( subBody, cullParams, false, string.Empty );
  190. }
  191. }
  192. //COLOR MASK
  193. {
  194. Match colorMaskMatch = Regex.Match( subBody, TemplateHelperFunctions.ColorMaskWholeWordPattern );
  195. if( colorMaskMatch.Success )
  196. {
  197. int colorMaskIdx = colorMaskMatch.Index;
  198. int end = subBody.IndexOf( TemplatesManager.TemplateNewLine, colorMaskIdx );
  199. string colorMaskParams = subBody.Substring( colorMaskIdx, end - colorMaskIdx );
  200. m_colorMaskData.ColorMaskId = colorMaskParams;
  201. m_colorMaskData.StartIdx = offsetIdx + colorMaskIdx;
  202. idManager.RegisterId( m_colorMaskData.StartIdx, uniquePrefix + m_colorMaskData.ColorMaskId, m_colorMaskData.ColorMaskId );
  203. TemplateHelperFunctions.CreateColorMask( colorMaskParams, ref m_colorMaskData );
  204. if( m_colorMaskData.DataCheck == TemplateDataCheck.Valid )
  205. propertyContainer.AddId( subBody, colorMaskParams, false );
  206. }
  207. }
  208. //STENCIL
  209. {
  210. Match stencilMatch = Regex.Match( subBody, TemplateHelperFunctions.StencilWholeWordPattern );
  211. if( stencilMatch.Success )
  212. {
  213. int stencilIdx = stencilMatch.Index;
  214. int stencilEndIdx = subBody.IndexOf( "}", stencilIdx );
  215. if( stencilEndIdx > 0 )
  216. {
  217. string stencilParams = subBody.Substring( stencilIdx, stencilEndIdx + 1 - stencilIdx );
  218. m_stencilData.StencilBufferId = stencilParams;
  219. m_stencilData.StartIdx = offsetIdx + stencilIdx;
  220. idManager.RegisterId( m_stencilData.StartIdx, uniquePrefix + m_stencilData.StencilBufferId, m_stencilData.StencilBufferId );
  221. TemplateHelperFunctions.CreateStencilOps( stencilParams, ref m_stencilData );
  222. if( m_stencilData.DataCheck == TemplateDataCheck.Valid )
  223. {
  224. propertyContainer.AddId( subBody, stencilParams, true );
  225. }
  226. }
  227. }
  228. else
  229. {
  230. int stencilTagIdx = subBody.IndexOf( TemplatesManager.TemplateStencilTag );
  231. if( stencilTagIdx > -1 )
  232. {
  233. m_stencilData.SetIndependentDefault();
  234. m_stencilData.StencilBufferId = TemplatesManager.TemplateStencilTag;
  235. m_stencilData.StartIdx = offsetIdx + stencilTagIdx;
  236. idManager.RegisterId( m_stencilData.StartIdx, uniquePrefix + m_stencilData.StencilBufferId, m_stencilData.StencilBufferId );
  237. propertyContainer.AddId( subBody, m_stencilData.StencilBufferId, true );
  238. }
  239. }
  240. }
  241. //ZWRITE
  242. {
  243. Match zWriteMatch = Regex.Match( subBody, TemplateHelperFunctions.ZWriteWholeWordPattern );
  244. if( zWriteMatch.Success )
  245. {
  246. int zWriteOpIdx = zWriteMatch.Index;
  247. int zWriteEndIdx = subBody.IndexOf( TemplatesManager.TemplateNewLine, zWriteOpIdx );
  248. if( zWriteEndIdx > 0 )
  249. {
  250. m_depthData.ZWriteModeId = subBody.Substring( zWriteOpIdx, zWriteEndIdx + 1 - zWriteOpIdx );
  251. m_depthData.ZWriteStartIndex = offsetIdx + zWriteOpIdx;
  252. idManager.RegisterId( m_depthData.ZWriteStartIndex, uniquePrefix + m_depthData.ZWriteModeId, m_depthData.ZWriteModeId );
  253. TemplateHelperFunctions.CreateZWriteMode( m_depthData.ZWriteModeId, ref m_depthData );
  254. if( m_depthData.DataCheck == TemplateDataCheck.Valid )
  255. {
  256. propertyContainer.AddId( subBody, m_depthData.ZWriteModeId, true );
  257. }
  258. }
  259. }
  260. }
  261. //ZTEST
  262. {
  263. Match zTestMatch = Regex.Match( subBody, TemplateHelperFunctions.ZTestWholeWordPattern );
  264. if( zTestMatch.Success )
  265. {
  266. int zTestOpIdx = zTestMatch.Index;
  267. int zTestEndIdx = subBody.IndexOf( TemplatesManager.TemplateNewLine, zTestOpIdx );
  268. if( zTestEndIdx > 0 )
  269. {
  270. m_depthData.ZTestModeId = subBody.Substring( zTestOpIdx, zTestEndIdx + 1 - zTestOpIdx );
  271. m_depthData.ZTestStartIndex = offsetIdx + zTestOpIdx;
  272. idManager.RegisterId( m_depthData.ZTestStartIndex, uniquePrefix + m_depthData.ZTestModeId, m_depthData.ZTestModeId );
  273. TemplateHelperFunctions.CreateZTestMode( m_depthData.ZTestModeId, ref m_depthData );
  274. if( m_depthData.DataCheck == TemplateDataCheck.Valid )
  275. {
  276. propertyContainer.AddId( subBody, m_depthData.ZTestModeId, true );
  277. }
  278. }
  279. }
  280. }
  281. //ZOFFSET
  282. {
  283. Match zOffsetMatch = Regex.Match( subBody, TemplateHelperFunctions.ZOffsetWholeWordPattern );
  284. if( zOffsetMatch.Success )
  285. {
  286. int zOffsetIdx = zOffsetMatch.Index;
  287. int zOffsetEndIdx = subBody.IndexOf( TemplatesManager.TemplateNewLine, zOffsetIdx );
  288. if( zOffsetEndIdx > 0 )
  289. {
  290. m_depthData.OffsetId = subBody.Substring( zOffsetIdx, zOffsetEndIdx + 1 - zOffsetIdx );
  291. m_depthData.OffsetStartIndex = offsetIdx + zOffsetIdx;
  292. idManager.RegisterId( m_depthData.OffsetStartIndex, uniquePrefix + m_depthData.OffsetId, m_depthData.OffsetId );
  293. TemplateHelperFunctions.CreateZOffsetMode( m_depthData.OffsetId, ref m_depthData );
  294. if( m_depthData.DataCheck == TemplateDataCheck.Valid )
  295. {
  296. propertyContainer.AddId( subBody, m_depthData.OffsetId, true );
  297. }
  298. }
  299. }
  300. }
  301. //TAGS
  302. {
  303. Match tagsMatch = Regex.Match( subBody, TemplateHelperFunctions.TagsWholeWordPattern );
  304. if ( tagsMatch.Success )
  305. {
  306. int tagsIdx = tagsMatch.Index;
  307. int tagsEndIdx = subBody.IndexOf( "}", tagsIdx );
  308. if ( tagsEndIdx > -1 )
  309. {
  310. m_tagData.Reset();
  311. m_tagData.TagsId = subBody.Substring( tagsIdx, tagsEndIdx + 1 - tagsIdx );
  312. m_tagData.StartIdx = offsetIdx + tagsIdx;
  313. idManager.RegisterId( m_tagData.StartIdx, uniquePrefix + m_tagData.TagsId, m_tagData.TagsId );
  314. m_srpType = TemplateHelperFunctions.CreateTags( ref m_tagData, isSubShader );
  315. propertyContainer.AddId( subBody, m_tagData.TagsId, false );
  316. m_tagData.DataCheck = TemplateDataCheck.Valid;
  317. }
  318. else
  319. {
  320. m_tagData.DataCheck = TemplateDataCheck.Invalid;
  321. }
  322. }
  323. else
  324. {
  325. m_tagData.DataCheck = TemplateDataCheck.Invalid;
  326. }
  327. }
  328. //SHADER MODEL
  329. {
  330. Match match = Regex.Match( subBody, TemplateHelperFunctions.ShaderModelPattern );
  331. if ( match != null && match.Groups.Count > 1 )
  332. {
  333. if ( TemplateHelperFunctions.AvailableInterpolators.ContainsKey( match.Groups[ 1 ].Value ) )
  334. {
  335. m_shaderModel.Id = match.Groups[ 0 ].Value;
  336. m_shaderModel.StartIdx = offsetIdx + match.Index;
  337. m_shaderModel.Value = match.Groups[ 1 ].Value;
  338. m_shaderModel.InterpolatorAmount = TemplateHelperFunctions.AvailableInterpolators[ match.Groups[ 1 ].Value ];
  339. m_shaderModel.DataCheck = TemplateDataCheck.Valid;
  340. idManager.RegisterId( m_shaderModel.StartIdx, uniquePrefix + m_shaderModel.Id, m_shaderModel.Id );
  341. }
  342. else
  343. {
  344. m_shaderModel.DataCheck = TemplateDataCheck.Invalid;
  345. }
  346. }
  347. }
  348. // ALL MODULES
  349. int allModulesIndex = subBody.IndexOf( TemplatesManager.TemplateAllModulesTag );
  350. if( allModulesIndex > 0 )
  351. {
  352. //ONLY REGISTER MISSING TAGS
  353. ConfigureCommonTag( m_allModulesTag, propertyContainer, idManager, uniquePrefix, offsetIdx, subBody );
  354. m_allModulesMode = true;
  355. m_blendData.SetAllModulesDefault();
  356. if( !m_cullModeData.IsValid )
  357. m_cullModeData.SetAllModulesDefault();
  358. if( !m_colorMaskData.IsValid )
  359. m_colorMaskData.SetAllModulesDefault();
  360. if( !m_stencilData.IsValid )
  361. m_stencilData.SetAllModulesDefault();
  362. if( !m_depthData.IsValid )
  363. m_depthData.SetAllModulesDefault();
  364. if( !m_shaderModel.IsValid )
  365. m_shaderModel.SetAllModulesDefault();
  366. }
  367. }
  368. public bool HasValidData
  369. {
  370. get
  371. {
  372. return m_blendData.DataCheck == TemplateDataCheck.Valid ||
  373. m_cullModeData.DataCheck == TemplateDataCheck.Valid ||
  374. m_colorMaskData.DataCheck == TemplateDataCheck.Valid ||
  375. m_stencilData.DataCheck == TemplateDataCheck.Valid ||
  376. m_depthData.DataCheck == TemplateDataCheck.Valid ||
  377. m_tagData.DataCheck == TemplateDataCheck.Valid ||
  378. m_shaderModel.DataCheck == TemplateDataCheck.Valid ||
  379. m_globalsTag.IsValid ||
  380. m_allModulesTag.IsValid ||
  381. m_functionsTag.IsValid ||
  382. m_pragmaTag.IsValid ||
  383. m_passTag.IsValid ||
  384. m_inputsVertTag.IsValid ||
  385. m_inputsFragTag.IsValid;
  386. }
  387. }
  388. public TemplateBlendData BlendData { get { return m_blendData; } }
  389. public TemplateCullModeData CullModeData { get { return m_cullModeData; } }
  390. public TemplateColorMaskData ColorMaskData { get { return m_colorMaskData; } }
  391. public TemplateStencilData StencilData { get { return m_stencilData; } }
  392. public TemplateDepthData DepthData { get { return m_depthData; } }
  393. public TemplateTagsModuleData TagData { get { return m_tagData; } }
  394. public TemplateTagData GlobalsTag { get { return m_globalsTag; } }
  395. public TemplateTagData AllModulesTag { get { return m_allModulesTag; } }
  396. public TemplateTagData FunctionsTag { get { return m_functionsTag; } }
  397. public TemplateTagData PragmaTag { get { return m_pragmaTag; } }
  398. public TemplateTagData PassTag { get { return m_passTag; } }
  399. public TemplateTagData InputsVertTag { get { return m_inputsVertTag; } }
  400. public TemplateTagData InputsFragTag { get { return m_inputsFragTag; } }
  401. public TemplateShaderModelData ShaderModel { get { return m_shaderModel; } }
  402. public TemplateSRPType SRPType { get { return m_srpType; } set { m_srpType = value; } }
  403. public bool SRPIsPBR { get { return m_srpIsPBR; } set { m_srpIsPBR = value; } }
  404. public bool SRPIsPBRHD { get { return m_srpIsPBR && m_srpType == TemplateSRPType.HD; } }
  405. public string UniquePrefix { get { return m_uniquePrefix; } }
  406. public TemplateIncludePragmaContainter IncludePragmaContainer { get { return m_includePragmaContainer; } }
  407. public bool AllModulesMode { get { return m_allModulesMode; } }
  408. }
  409. }