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.

1868 lines
56 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEditor;
  7. using System.Text.RegularExpressions;
  8. namespace AmplifyShaderEditor
  9. {
  10. public class PropertyDataCollector
  11. {
  12. public int NodeId;
  13. public int OrderIndex;
  14. public string PropertyName;
  15. public WirePortDataType DataType;
  16. public PropertyDataCollector( int nodeId, string propertyName, int orderIndex = -1 )
  17. {
  18. NodeId = nodeId;
  19. PropertyName = propertyName;
  20. OrderIndex = orderIndex;
  21. }
  22. }
  23. public class InputCoordsCollector
  24. {
  25. public int NodeId;
  26. public string CoordName;
  27. public WirePortDataType DataType;
  28. public PrecisionType Precision;
  29. public int TextureSlot;
  30. public int TextureIndex;
  31. public InputCoordsCollector( int nodeId, string coordName, WirePortDataType dataType, PrecisionType precision, int textureSlot, int textureIndex )
  32. {
  33. NodeId = nodeId;
  34. CoordName = coordName;
  35. DataType = dataType;
  36. Precision = precision;
  37. TextureSlot = textureSlot;
  38. TextureIndex = textureIndex;
  39. }
  40. }
  41. public class TextureDefaultsDataColector
  42. {
  43. private List<string> m_names = new List<string>();
  44. private List<Texture> m_values = new List<Texture>();
  45. public void AddValue( string newName, Texture newValue )
  46. {
  47. m_names.Add( newName );
  48. m_values.Add( newValue );
  49. }
  50. public void Destroy()
  51. {
  52. m_names.Clear();
  53. m_names = null;
  54. m_values.Clear();
  55. m_values = null;
  56. }
  57. public string[] NamesArr { get { return m_names.ToArray(); } }
  58. public Texture[] ValuesArr { get { return m_values.ToArray(); } }
  59. }
  60. public enum TextureChannelUsage
  61. {
  62. Not_Used,
  63. Used,
  64. Required
  65. }
  66. public class MasterNodeDataCollector
  67. {
  68. private bool m_showDebugMessages = false;
  69. private string m_input;
  70. private string m_customInput;
  71. private string m_properties;
  72. private string m_instancedProperties;
  73. private string m_instanceBlockName;
  74. private string m_uniforms;
  75. private string m_includes;
  76. private string m_pragmas;
  77. private string m_defines;
  78. private string m_instructions;
  79. private string m_localVariables;
  80. private string m_vertexLocalVariables;
  81. private string m_specialLocalVariables;
  82. private string m_vertexData;
  83. private string m_customOutput;
  84. private string m_functions;
  85. private string m_grabPass;
  86. private List<PropertyDataCollector> m_inputList;
  87. private List<PropertyDataCollector> m_customInputList;
  88. private List<PropertyDataCollector> m_propertiesList;
  89. private List<PropertyDataCollector> m_instancedPropertiesList;
  90. private List<PropertyDataCollector> m_uniformsList;
  91. private List<PropertyDataCollector> m_includesList;
  92. private List<PropertyDataCollector> m_additionalDirectivesList;
  93. //private List<PropertyDataCollector> m_tagsList;
  94. private List<PropertyDataCollector> m_pragmasList;
  95. private List<PropertyDataCollector> m_definesList;
  96. private List<PropertyDataCollector> m_instructionsList;
  97. private List<PropertyDataCollector> m_localVariablesList;
  98. private List<PropertyDataCollector> m_vertexLocalVariablesList;
  99. private List<PropertyDataCollector> m_specialLocalVariablesList;
  100. private List<PropertyDataCollector> m_vertexDataList;
  101. private List<PropertyDataCollector> m_customOutputList;
  102. private List<PropertyDataCollector> m_functionsList;
  103. private List<PropertyDataCollector> m_grabPassList;
  104. private List<InputCoordsCollector> m_customShadowCoordsList;
  105. private List<int> m_packSlotsList;
  106. private string m_customAppDataItems;
  107. private Dictionary<string, PropertyDataCollector> m_inputDict;
  108. private Dictionary<string, PropertyDataCollector> m_customInputDict;
  109. private Dictionary<string, PropertyDataCollector> m_propertiesDict;
  110. private Dictionary<string, PropertyDataCollector> m_instancedPropertiesDict;
  111. private Dictionary<string, PropertyDataCollector> m_uniformsDict;
  112. private Dictionary<string, PropertyDataCollector> m_includesDict;
  113. private Dictionary<string, PropertyDataCollector> m_additionalDirectivesDict;
  114. private Dictionary<string, string> m_includesExclusionDict;
  115. //private Dictionary<string, PropertyDataCollector> m_tagsDict;
  116. private Dictionary<string, PropertyDataCollector> m_pragmasDict;
  117. private Dictionary<string, PropertyDataCollector> m_definesDict;
  118. private Dictionary<string, int> m_virtualCoordinatesDict;
  119. private Dictionary<string, string> m_virtualVariablesDict;
  120. private Dictionary<string, PropertyDataCollector> m_localVariablesDict;
  121. private Dictionary<string, PropertyDataCollector> m_vertexLocalVariablesDict;
  122. private Dictionary<string, PropertyDataCollector> m_specialLocalVariablesDict;
  123. private Dictionary<string, PropertyDataCollector> m_vertexDataDict;
  124. private Dictionary<string, PropertyDataCollector> m_customOutputDict;
  125. private Dictionary<string, string> m_localFunctions;
  126. private Dictionary<string, string> m_grabPassDict;
  127. private Dictionary<string, string> m_customAppDataItemsDict;
  128. private Dictionary<string, InputCoordsCollector> m_customShadowCoordsDict;
  129. private TextureChannelUsage[] m_requireTextureProperty = { TextureChannelUsage.Not_Used, TextureChannelUsage.Not_Used, TextureChannelUsage.Not_Used, TextureChannelUsage.Not_Used };
  130. private bool m_dirtyAppData;
  131. private bool m_dirtyInputs;
  132. private bool m_dirtyCustomInputs;
  133. private bool m_dirtyFunctions;
  134. private bool m_dirtyProperties;
  135. private bool m_dirtyInstancedProperties;
  136. private bool m_dirtyUniforms;
  137. private bool m_dirtyIncludes;
  138. private bool m_dirtyPragmas;
  139. private bool m_dirtyDefines;
  140. private bool m_dirtyAdditionalDirectives;
  141. private bool m_dirtyInstructions;
  142. private bool m_dirtyLocalVariables;
  143. private bool m_dirtyVertexLocalVariables;
  144. private bool m_dirtySpecialLocalVariables;
  145. private bool m_dirtyPerVertexData;
  146. private bool m_dirtyNormal;
  147. private bool m_forceNormal;
  148. private bool m_usingInternalData;
  149. private bool m_usingVertexColor;
  150. private bool m_usingWorldPosition;
  151. private bool m_usingWorldNormal;
  152. private bool m_usingScreenPos;
  153. private bool m_usingWorldReflection;
  154. private bool m_usingViewDirection;
  155. private bool m_usingLightAttenuation;
  156. private bool m_usingArrayDerivatives;
  157. private bool m_usingHigherSizeTexcoords;
  158. private bool m_usingCustomScreenPos;
  159. private bool m_usingCustomOutlineColor;
  160. private bool m_usingCustomOutlineWidth;
  161. private bool m_usingCustomOutlineAlpha;
  162. private int m_customOutlineSelectedAlpha = 0;
  163. private bool m_usingCustomOutput;
  164. private bool m_safeNormalizeLightDir;
  165. private bool m_safeNormalizeViewDir;
  166. private bool m_isOutlineDataCollector = false;
  167. private bool m_forceNormalIsDirty;
  168. private bool m_grabPassIsDirty;
  169. private bool m_tesselationActive;
  170. private Dictionary<int, PropertyNode> m_propertyNodes;
  171. private MasterNode m_masterNode;
  172. private int m_availableVertexTempId = 0;
  173. private int m_availableFragTempId = 0;
  174. private MasterNodePortCategory m_portCategory;
  175. private PortGenType m_genType;
  176. private RenderPath m_renderPath = RenderPath.All;
  177. private NodeAvailability m_currentCanvasMode = NodeAvailability.SurfaceShader;
  178. //Templates specific data
  179. private AvailableShaderTypes m_masterNodeCategory;
  180. private List<string> m_vertexInputList;
  181. private Dictionary<string, string> m_vertexInputDict;
  182. private List<string> m_interpolatorsList;
  183. private Dictionary<string, string> m_interpolatorsDict;
  184. private List<string> m_vertexInterpDeclList;
  185. private Dictionary<string, string> m_vertexInterpDeclDict;
  186. private TemplateDataCollector m_templateDataCollector;
  187. public MasterNodeDataCollector( MasterNode masterNode ) : this()
  188. {
  189. m_masterNode = masterNode;
  190. m_masterNodeCategory = masterNode.CurrentMasterNodeCategory;
  191. m_currentCanvasMode = masterNode.ContainerGraph.CurrentCanvasMode;
  192. }
  193. public MasterNodeDataCollector()
  194. {
  195. //m_masterNode = masterNode;
  196. m_input = "struct Input\n\t\t{\n";
  197. m_customInput = "\t\tstruct SurfaceOutput{0}\n\t\t{\n";
  198. m_properties = IOUtils.PropertiesBegin;//"\tProperties\n\t{\n";
  199. m_uniforms = string.Empty;
  200. m_instructions = string.Empty;
  201. m_includes = string.Empty;
  202. m_pragmas = string.Empty;
  203. m_defines = string.Empty;
  204. m_localVariables = string.Empty;
  205. m_specialLocalVariables = string.Empty;
  206. m_customOutput = string.Empty;
  207. m_inputList = new List<PropertyDataCollector>();
  208. m_customInputList = new List<PropertyDataCollector>();
  209. m_propertiesList = new List<PropertyDataCollector>();
  210. m_instancedPropertiesList = new List<PropertyDataCollector>();
  211. m_uniformsList = new List<PropertyDataCollector>();
  212. m_includesList = new List<PropertyDataCollector>();
  213. m_additionalDirectivesList = new List<PropertyDataCollector>();
  214. //m_tagsList = new List<PropertyDataCollector>();
  215. m_pragmasList = new List<PropertyDataCollector>();
  216. m_definesList = new List<PropertyDataCollector>();
  217. m_instructionsList = new List<PropertyDataCollector>();
  218. m_localVariablesList = new List<PropertyDataCollector>();
  219. m_vertexLocalVariablesList = new List<PropertyDataCollector>();
  220. m_specialLocalVariablesList = new List<PropertyDataCollector>();
  221. m_vertexDataList = new List<PropertyDataCollector>();
  222. m_customOutputList = new List<PropertyDataCollector>();
  223. m_functionsList = new List<PropertyDataCollector>();
  224. m_grabPassList = new List<PropertyDataCollector>();
  225. m_customAppDataItems = string.Empty;
  226. m_customAppDataItemsDict = new Dictionary<string, string>();
  227. m_customShadowCoordsList = new List<InputCoordsCollector>();
  228. m_packSlotsList = new List<int>();
  229. m_inputDict = new Dictionary<string, PropertyDataCollector>();
  230. m_customInputDict = new Dictionary<string, PropertyDataCollector>();
  231. m_propertiesDict = new Dictionary<string, PropertyDataCollector>();
  232. m_instancedPropertiesDict = new Dictionary<string, PropertyDataCollector>();
  233. m_uniformsDict = new Dictionary<string, PropertyDataCollector>();
  234. m_includesDict = new Dictionary<string, PropertyDataCollector>();
  235. m_additionalDirectivesDict = new Dictionary<string, PropertyDataCollector>();
  236. m_includesExclusionDict = new Dictionary<string, string>();
  237. //m_tagsDict = new Dictionary<string, PropertyDataCollector>();
  238. m_pragmasDict = new Dictionary<string, PropertyDataCollector>();
  239. m_definesDict = new Dictionary<string, PropertyDataCollector>();
  240. m_virtualCoordinatesDict = new Dictionary<string, int>();
  241. m_localVariablesDict = new Dictionary<string, PropertyDataCollector>();
  242. m_virtualVariablesDict = new Dictionary<string, string>();
  243. m_specialLocalVariablesDict = new Dictionary<string, PropertyDataCollector>();
  244. m_vertexLocalVariablesDict = new Dictionary<string, PropertyDataCollector>();
  245. m_localFunctions = new Dictionary<string, string>();
  246. m_vertexDataDict = new Dictionary<string, PropertyDataCollector>();
  247. m_customOutputDict = new Dictionary<string, PropertyDataCollector>();
  248. m_grabPassDict = new Dictionary<string, string>();
  249. m_customShadowCoordsDict = new Dictionary<string, InputCoordsCollector>();
  250. m_dirtyAppData = false;
  251. m_dirtyInputs = false;
  252. m_dirtyCustomInputs = false;
  253. m_dirtyProperties = false;
  254. m_dirtyInstancedProperties = false;
  255. m_dirtyUniforms = false;
  256. m_dirtyInstructions = false;
  257. m_dirtyIncludes = false;
  258. m_dirtyPragmas = false;
  259. m_dirtyDefines = false;
  260. m_dirtyAdditionalDirectives = false;
  261. m_dirtyLocalVariables = false;
  262. m_dirtySpecialLocalVariables = false;
  263. m_grabPassIsDirty = false;
  264. m_portCategory = MasterNodePortCategory.Fragment;
  265. m_propertyNodes = new Dictionary<int, PropertyNode>();
  266. m_showDebugMessages = ( m_showDebugMessages && DebugConsoleWindow.DeveloperMode );
  267. //templates
  268. //m_masterNodeCategory = masterNode.CurrentMasterNodeCategory;
  269. m_vertexInputList = new List<string>();
  270. m_vertexInputDict = new Dictionary<string, string>();
  271. m_interpolatorsList = new List<string>();
  272. m_interpolatorsDict = new Dictionary<string, string>();
  273. m_vertexInterpDeclList = new List<string>();
  274. m_vertexInterpDeclDict = new Dictionary<string, string>();
  275. m_templateDataCollector = new TemplateDataCollector();
  276. }
  277. public void SetChannelUsage( int channelId, TextureChannelUsage usage )
  278. {
  279. if( channelId > -1 && channelId < 4 )
  280. m_requireTextureProperty[ channelId ] = usage;
  281. }
  282. public TextureChannelUsage GetChannelUsage( int channelId )
  283. {
  284. if( channelId > -1 && channelId < 4 )
  285. return m_requireTextureProperty[ channelId ];
  286. return TextureChannelUsage.Not_Used;
  287. }
  288. public void OpenPerVertexHeader( bool includeCustomData )
  289. {
  290. string appData ="inout " + (m_dirtyAppData ? Constants.CustomAppDataFullName : Constants.AppDataFullName)+" ";
  291. if( m_dirtyPerVertexData )
  292. return;
  293. m_dirtyPerVertexData = true;
  294. if( m_tesselationActive )
  295. {
  296. m_vertexData = "\t\tvoid " + Constants.VertexDataFunc + "( "+ appData + Constants.VertexShaderInputStr + " )\n\t\t{\n";
  297. }
  298. else
  299. {
  300. m_vertexData = "\t\tvoid " + Constants.VertexDataFunc + "( "+ appData + Constants.VertexShaderInputStr + ( includeCustomData ? ( string.Format( ", out Input {0}", Constants.VertexShaderOutputStr ) ) : string.Empty ) + " )\n\t\t{\n";
  301. if( includeCustomData )
  302. m_vertexData += string.Format( "\t\t\tUNITY_INITIALIZE_OUTPUT( Input, {0} );\n", Constants.VertexShaderOutputStr );
  303. }
  304. }
  305. public void ClosePerVertexHeader()
  306. {
  307. if( m_dirtyPerVertexData )
  308. m_vertexData += "\t\t}\n\n";
  309. }
  310. public void AddToVertexDisplacement( string value, VertexMode vertexMode )
  311. {
  312. if( string.IsNullOrEmpty( value ) )
  313. return;
  314. if( !m_dirtyPerVertexData )
  315. {
  316. OpenPerVertexHeader( true );
  317. }
  318. switch( vertexMode )
  319. {
  320. default:
  321. case VertexMode.Relative:
  322. {
  323. m_vertexData += "\t\t\t" + Constants.VertexShaderInputStr + ".vertex.xyz += " + value + ";\n";
  324. }
  325. break;
  326. case VertexMode.Absolute:
  327. {
  328. m_vertexData += "\t\t\t" + Constants.VertexShaderInputStr + ".vertex.xyz = " + value + ";\n";
  329. }
  330. break;
  331. }
  332. }
  333. public void AddToVertexNormal( string value )
  334. {
  335. if( string.IsNullOrEmpty( value ) )
  336. return;
  337. if( !m_dirtyPerVertexData )
  338. {
  339. OpenPerVertexHeader( true );
  340. }
  341. m_vertexData += "\t\t\t" + Constants.VertexShaderInputStr + ".normal = " + value + ";\n";
  342. }
  343. public void AddVertexInstruction( string value, int nodeId = -1, bool addDelimiters = true )
  344. {
  345. if( !m_dirtyPerVertexData && !IsOutlineDataCollector/*&& !(m_usingCustomOutlineColor || m_usingCustomOutlineWidth)*/ )
  346. {
  347. OpenPerVertexHeader( true );
  348. }
  349. if( !m_vertexDataDict.ContainsKey( value ) )
  350. {
  351. m_vertexDataDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  352. m_vertexDataList.Add( m_vertexDataDict[ value ] );
  353. m_vertexData += ( addDelimiters ? ( "\t\t\t" + value + ";\n" ) : value );
  354. }
  355. }
  356. public bool ContainsInput( string value )
  357. {
  358. return m_inputDict.ContainsKey( value );
  359. }
  360. public void AddToInput( int nodeId, string interpName, WirePortDataType dataType, PrecisionType precision = PrecisionType.Float, bool addSemiColon = true )
  361. {
  362. string value = UIUtils.FinalPrecisionWirePortToCgType( precision, dataType ) + " " + interpName;
  363. AddToInput( nodeId, value, addSemiColon );
  364. if( !m_customShadowCoordsDict.ContainsKey( interpName ) )
  365. {
  366. int slot = 0;
  367. int index = 0;
  368. int size = UIUtils.GetChannelsAmount( dataType );
  369. if( m_packSlotsList.Count == 0 )
  370. m_packSlotsList.Add( 4 );
  371. for( int i = 0; i < m_packSlotsList.Count; i++ )
  372. {
  373. slot = i;
  374. if( m_packSlotsList[ i ] >= size )
  375. {
  376. index = 4 - m_packSlotsList[ i ];
  377. m_packSlotsList[ i ] -= size;
  378. break;
  379. }
  380. else if( i == m_packSlotsList.Count - 1 )
  381. {
  382. m_packSlotsList.Add( 4 );
  383. }
  384. }
  385. m_customShadowCoordsDict.Add( interpName, new InputCoordsCollector( nodeId, interpName, dataType, precision, slot, index ) );
  386. m_customShadowCoordsList.Add( m_customShadowCoordsDict[ interpName ] );
  387. }
  388. }
  389. public void AddToInput( int nodeId, SurfaceInputs surfaceInput, PrecisionType precision = PrecisionType.Float, bool addSemiColon = true )
  390. {
  391. switch( surfaceInput )
  392. {
  393. case SurfaceInputs.VIEW_DIR:
  394. UsingViewDirection = true;
  395. break;
  396. case SurfaceInputs.SCREEN_POS:
  397. UsingScreenPos = true;
  398. break;
  399. case SurfaceInputs.WORLD_POS:
  400. UsingWorldPosition = true;
  401. break;
  402. case SurfaceInputs.WORLD_REFL:
  403. UsingWorldReflection = true;
  404. break;
  405. case SurfaceInputs.WORLD_NORMAL:
  406. UsingWorldNormal = true;
  407. break;
  408. case SurfaceInputs.INTERNALDATA:
  409. UsingInternalData = true;
  410. break;
  411. case SurfaceInputs.COLOR:
  412. UsingVertexColor = true;
  413. break;
  414. }
  415. AddToInput( nodeId, UIUtils.GetInputDeclarationFromType( precision, surfaceInput ), addSemiColon );
  416. }
  417. /// <summary>
  418. /// Direct access to inputs, plese use another overload
  419. /// </summary>
  420. /// <param name="nodeId"></param>
  421. /// <param name="value"></param>
  422. /// <param name="addSemiColon"></param>
  423. public void AddToInput( int nodeId, string value, bool addSemiColon )
  424. {
  425. if( string.IsNullOrEmpty( value ) )
  426. return;
  427. if( !m_inputDict.ContainsKey( value ) )
  428. {
  429. m_inputDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  430. m_inputList.Add( m_inputDict[ value ] );
  431. m_input += "\t\t\t" + value + ( ( addSemiColon ) ? ( ";\n" ) : "\n" );
  432. m_dirtyInputs = true;
  433. }
  434. }
  435. public void CloseInputs()
  436. {
  437. m_input += "\t\t};";
  438. }
  439. public void ChangeCustomInputHeader( string value )
  440. {
  441. m_customInput = m_customInput.Replace( "{0}", value );
  442. }
  443. public void AddToCustomInput( int nodeId, string value, bool addSemiColon )
  444. {
  445. if( string.IsNullOrEmpty( value ) )
  446. return;
  447. if( !m_customInputDict.ContainsKey( value ) )
  448. {
  449. m_customInputDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  450. m_customInputList.Add( m_customInputDict[ value ] );
  451. m_customInput += "\t\t\t" + value + ( ( addSemiColon ) ? ( ";\n" ) : "\n" );
  452. m_dirtyCustomInputs = true;
  453. }
  454. }
  455. public void CloseCustomInputs()
  456. {
  457. m_customInput += "\t\t};";
  458. }
  459. // Used by Template Master Node to add tabs into variable declaration
  460. public void TabifyInstancedVars()
  461. {
  462. for( int i = 0; i < m_instancedPropertiesList.Count; i++ )
  463. {
  464. m_instancedPropertiesList[ i ].PropertyName = '\t' + m_instancedPropertiesList[ i ].PropertyName;
  465. }
  466. }
  467. private int GetWeightForInstancedType( WirePortDataType type )
  468. {
  469. switch( type )
  470. {
  471. case WirePortDataType.INT:
  472. case WirePortDataType.FLOAT: return -1;
  473. case WirePortDataType.FLOAT2: return -2;
  474. case WirePortDataType.FLOAT3: return -3;
  475. case WirePortDataType.COLOR:
  476. case WirePortDataType.FLOAT4: return -4;
  477. case WirePortDataType.FLOAT3x3: return -9;
  478. case WirePortDataType.FLOAT4x4: return -16;
  479. default:
  480. case WirePortDataType.OBJECT:
  481. case WirePortDataType.SAMPLER1D:
  482. case WirePortDataType.SAMPLER2D:
  483. case WirePortDataType.SAMPLER3D:
  484. case WirePortDataType.SAMPLERCUBE:
  485. return 0;
  486. }
  487. }
  488. public void OptimizeInstancedProperties()
  489. {
  490. if( m_instancedPropertiesList.Count > 0 )
  491. {
  492. m_instancedProperties = string.Empty;
  493. m_instancedPropertiesList.Sort( ( x, y ) => { return GetWeightForInstancedType( x.DataType ).CompareTo( GetWeightForInstancedType( y.DataType ) ); } );
  494. int count = m_instancedPropertiesList.Count;
  495. for( int i = 0; i < count; i++ )
  496. {
  497. m_instancedProperties += m_instancedPropertiesList[ i ].PropertyName;
  498. }
  499. }
  500. }
  501. // Instanced properties
  502. public void SetupInstancePropertiesBlock( string blockName )
  503. {
  504. m_instanceBlockName = blockName;
  505. if( IsTemplate )
  506. {
  507. //if( DebugConsoleWindow.DeveloperMode )
  508. // Debug.LogWarning( "SetupInstancePropertiesBlock should not be used during template mode" );
  509. return;
  510. }
  511. OptimizeInstancedProperties();
  512. if( m_dirtyInstancedProperties )
  513. {
  514. m_instancedProperties = string.Format( IOUtils.InstancedPropertiesBeginTabs, blockName ) + m_instancedProperties + IOUtils.InstancedPropertiesEndTabs;
  515. }
  516. }
  517. public void AddToInstancedProperties( WirePortDataType dataType, int nodeId, string value, int orderIndex )
  518. {
  519. if( string.IsNullOrEmpty( value ) )
  520. return;
  521. if( !m_instancedPropertiesDict.ContainsKey( value ) )
  522. {
  523. PropertyDataCollector dataColl = new PropertyDataCollector( nodeId, value, orderIndex );
  524. dataColl.DataType = dataType;
  525. m_instancedPropertiesDict.Add( value, dataColl );
  526. m_instancedPropertiesList.Add( dataColl );
  527. m_instancedProperties += value;
  528. m_dirtyInstancedProperties = true;
  529. }
  530. }
  531. public void CloseInstancedProperties()
  532. {
  533. if( m_dirtyInstancedProperties )
  534. {
  535. m_instancedProperties += IOUtils.InstancedPropertiesEnd;
  536. }
  537. }
  538. // Properties
  539. public void CopyPropertiesFromDataCollector( MasterNodeDataCollector dataCollector )
  540. {
  541. if( dataCollector == null )
  542. return;
  543. int propertyCount = dataCollector.PropertiesList.Count;
  544. for( int i = 0; i < propertyCount; i++ )
  545. {
  546. AddToProperties( dataCollector.PropertiesList[ i ].NodeId,
  547. dataCollector.PropertiesList[ i ].PropertyName,
  548. dataCollector.PropertiesList[ i ].OrderIndex );
  549. }
  550. foreach( KeyValuePair<string, string> kvp in dataCollector.GrabPassDict )
  551. {
  552. AddGrabPass( kvp.Value );
  553. }
  554. }
  555. public void AddToProperties( int nodeId, string value, int orderIndex )
  556. {
  557. if( string.IsNullOrEmpty( value ) )
  558. return;
  559. if( !m_propertiesDict.ContainsKey( value ) )
  560. {
  561. //Debug.Log( UIUtils );
  562. m_propertiesDict.Add( value, new PropertyDataCollector( nodeId, value, orderIndex ) );
  563. m_propertiesList.Add( m_propertiesDict[ value ] );
  564. m_properties += string.Format( IOUtils.PropertiesElement, value );
  565. m_dirtyProperties = true;
  566. }
  567. }
  568. public string BuildPropertiesString()
  569. {
  570. List<PropertyDataCollector> list = new List<PropertyDataCollector>( m_propertiesDict.Values );
  571. //for ( int i = 0; i < list.Count; i++ )
  572. //{
  573. // Debug.Log( list[ i ].OrderIndex + " " + list[ i ].PropertyName );
  574. //}
  575. list.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } );
  576. CleanUpList( ref list );
  577. m_properties = IOUtils.PropertiesBegin;
  578. for( int i = 0; i < list.Count; i++ )
  579. {
  580. m_properties += string.Format( IOUtils.PropertiesElement, list[ i ].PropertyName );
  581. //Debug.Log()
  582. }
  583. m_properties += IOUtils.PropertiesEnd;
  584. return m_properties;
  585. }
  586. public string[] BuildUnformatedPropertiesStringArr()
  587. {
  588. List<PropertyDataCollector> list = new List<PropertyDataCollector>( m_propertiesDict.Values );
  589. list.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } );
  590. CleanUpList( ref list );
  591. string[] arr = new string[ list.Count ];
  592. for( int i = 0; i < list.Count; i++ )
  593. {
  594. arr[ i ] = list[ i ].PropertyName;
  595. }
  596. return arr;
  597. }
  598. //This clean up was set to remove Header attributes from shader functions which would be last on the property list
  599. //Thus creating a label on the inspector with no properties below
  600. public void CleanUpList( ref List<PropertyDataCollector> list )
  601. {
  602. if( list.Count == 0 )
  603. return;
  604. if( list[ list.Count - 1 ].PropertyName.Contains( "[Header(" ) )
  605. {
  606. //Check if this is a complete property or just a standalone header
  607. Match match = Regex.Match( list[ list.Count - 1 ].PropertyName, TemplateHelperFunctions.PropertiesPatternD );
  608. if( !match.Success )
  609. {
  610. list.RemoveAt( list.Count - 1 );
  611. CleanUpList( ref list );
  612. }
  613. }
  614. }
  615. public void CloseProperties()
  616. {
  617. if( m_dirtyProperties )
  618. {
  619. m_properties += IOUtils.PropertiesEnd;
  620. }
  621. }
  622. public void AddGrabPass( string value )
  623. {
  624. if( m_grabPassDict.ContainsKey( value ) )
  625. return;
  626. m_grabPassDict.Add( value, value );
  627. if( string.IsNullOrEmpty( value ) )
  628. {
  629. if( !m_grabPassIsDirty )
  630. m_grabPass += IOUtils.GrabPassEmpty;
  631. }
  632. else
  633. {
  634. m_grabPass += IOUtils.GrabPassBegin + value + IOUtils.GrabPassEnd;
  635. }
  636. m_grabPassList.Add( new PropertyDataCollector( -1, m_grabPass.Replace( "\t", string.Empty ).Replace( "\n", string.Empty ) ) );
  637. m_grabPassIsDirty = true;
  638. }
  639. // This is used by templates global variables to register already existing globals/properties
  640. //public void SoftRegisterUniform( string dataName )
  641. //{
  642. // if( !m_uniformsDict.ContainsKey( dataName ) )
  643. // {
  644. // m_uniformsDict.Add( dataName, new PropertyDataCollector( -1, dataName ) );
  645. // }
  646. //}
  647. public void SoftRegisterUniform( TemplateShaderPropertyData data )
  648. {
  649. bool excludeUniformKeyword = ( data.PropertyType == PropertyType.InstancedProperty ) || IsSRP;
  650. string uniformName = UIUtils.GenerateUniformName( excludeUniformKeyword, data.PropertyDataType, data.PropertyName );
  651. if( !m_uniformsDict.ContainsKey( uniformName ) )
  652. {
  653. m_uniformsDict.Add( uniformName, new PropertyDataCollector( -1, uniformName ) );
  654. }
  655. }
  656. public void AddToUniforms( int nodeId, string dataType, string dataName )
  657. {
  658. if( string.IsNullOrEmpty( dataName ) || string.IsNullOrEmpty( dataType ) )
  659. return;
  660. string value = UIUtils.GenerateUniformName( IsSRP, dataType, dataName );
  661. if( !m_uniformsDict.ContainsKey( value ) && !m_uniformsDict.ContainsKey( dataName ) )
  662. {
  663. m_uniforms += "\t\t" + value + '\n';
  664. m_uniformsDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  665. m_uniformsList.Add( m_uniformsDict[ value ] );
  666. m_dirtyUniforms = true;
  667. }
  668. //else if ( m_uniformsDict[ value ].NodeId != nodeId )
  669. //{
  670. // if ( m_showDebugMessages ) UIUtils.ShowMessage( "AddToUniforms:Attempting to add duplicate " + value, MessageSeverity.Warning );
  671. //}
  672. }
  673. public void AddToUniforms( int nodeId, string value )
  674. {
  675. if( string.IsNullOrEmpty( value ) )
  676. return;
  677. if( !m_uniformsDict.ContainsKey( value ) )
  678. {
  679. m_uniforms += "\t\t" + value + '\n';
  680. m_uniformsDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  681. m_uniformsList.Add( m_uniformsDict[ value ] );
  682. m_dirtyUniforms = true;
  683. }
  684. else if( m_uniformsDict[ value ].NodeId != nodeId )
  685. {
  686. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToUniforms:Attempting to add duplicate " + value, MessageSeverity.Warning );
  687. }
  688. }
  689. public void AddToMisc( string value )
  690. {
  691. if( string.IsNullOrEmpty( value ) )
  692. return;
  693. if( !m_additionalDirectivesDict.ContainsKey( value ) )
  694. {
  695. PropertyDataCollector data = new PropertyDataCollector( -1, value );
  696. m_additionalDirectivesDict.Add( value, data );
  697. m_additionalDirectivesList.Add( data );
  698. m_dirtyAdditionalDirectives = true;
  699. }
  700. }
  701. public void AddToIncludes( int nodeId, string value )
  702. {
  703. if( string.IsNullOrEmpty( value ) )
  704. return;
  705. if( m_includesExclusionDict.ContainsKey( value ) )
  706. {
  707. return;
  708. }
  709. if( IsTemplate )
  710. {
  711. if( m_templateDataCollector.HasDirective( AdditionalLineType.Include, value ) )
  712. return;
  713. }
  714. if( !m_includesDict.ContainsKey( value ) )
  715. {
  716. PropertyDataCollector data = new PropertyDataCollector( nodeId, "#include \"" + value + "\"" );
  717. m_includesDict.Add( value, data );
  718. m_includesList.Add( data );
  719. m_includes += "\t\t#include \"" + value + "\"\n";
  720. m_dirtyIncludes = true;
  721. }
  722. else
  723. {
  724. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToIncludes:Attempting to add duplicate " + value, MessageSeverity.Warning );
  725. }
  726. }
  727. public void RemoveFromIncludes( string value )
  728. {
  729. if( string.IsNullOrEmpty( value ) )
  730. return;
  731. if( !m_includesExclusionDict.ContainsKey( value ) )
  732. {
  733. m_includesExclusionDict.Add( value, value );
  734. }
  735. if( m_includesDict.ContainsKey( value ) )
  736. {
  737. PropertyDataCollector data = m_includesDict[ value ];
  738. m_includesDict.Remove( value );
  739. m_includesList.Remove( data );
  740. m_dirtyIncludes = true;
  741. string finalValueName = "\t\t#include \"" + value + "\"\n";
  742. m_includes = m_includes.Replace( finalValueName, string.Empty );
  743. }
  744. }
  745. //public void AddToTags( int nodeId, string name, string value )
  746. //{
  747. // if( string.IsNullOrEmpty( name ) || string.IsNullOrEmpty( value ) )
  748. // return;
  749. // if( !m_tagsDict.ContainsKey( name ) )
  750. // {
  751. // string finalResult = string.Format( "\"{0}\"=\"{1}\"", name, value );
  752. // m_tagsDict.Add( name, new PropertyDataCollector( nodeId, finalResult ) );
  753. // m_tagsList.Add( new PropertyDataCollector( nodeId, finalResult ) );
  754. // }
  755. //}
  756. public void AddToPragmas( int nodeId, string value )
  757. {
  758. if( string.IsNullOrEmpty( value ) )
  759. return;
  760. if( IsTemplate )
  761. {
  762. if( m_templateDataCollector.HasDirective( AdditionalLineType.Pragma, value ) )
  763. return;
  764. }
  765. if( !m_pragmasDict.ContainsKey( value ) )
  766. {
  767. m_pragmasDict.Add( value, new PropertyDataCollector( nodeId, "#pragma " + value ) );
  768. m_pragmasList.Add( m_pragmasDict[ value ] );
  769. m_pragmas += "\t\t#pragma " + value + "\n";
  770. m_dirtyPragmas = true;
  771. }
  772. else
  773. {
  774. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToPragmas:Attempting to add duplicate " + value, MessageSeverity.Warning );
  775. }
  776. }
  777. public void AddToDefines( int nodeId, string value, bool define = true )
  778. {
  779. if( string.IsNullOrEmpty( value ) )
  780. return;
  781. if( IsTemplate )
  782. {
  783. if( m_templateDataCollector.HasDirective( AdditionalLineType.Define, value ) )
  784. return;
  785. }
  786. if( !m_definesDict.ContainsKey( value ) )
  787. {
  788. string defineValue = ( define ? "#define " : "#undef " ) + value;
  789. m_definesDict.Add( value, new PropertyDataCollector( nodeId, defineValue ) );
  790. m_definesList.Add( m_definesDict[ value ] );
  791. m_defines += "\t\t"+ defineValue + "\n";
  792. m_dirtyDefines = true;
  793. }
  794. else
  795. {
  796. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToDefines:Attempting to add duplicate " + value, MessageSeverity.Warning );
  797. }
  798. }
  799. public int GetVirtualCoordinatesId( int nodeId, string coord, string lodBias )
  800. {
  801. if( !m_virtualCoordinatesDict.ContainsKey( coord ) )
  802. {
  803. m_virtualCoordinatesDict.Add( coord, nodeId );
  804. AddLocalVariable( nodeId, "VirtualCoord " + Constants.VirtualCoordNameStr + nodeId + " = VTComputeVirtualCoord" + lodBias + "(" + coord + ");" );
  805. return nodeId;
  806. }
  807. else
  808. {
  809. int fetchedId = 0;
  810. m_virtualCoordinatesDict.TryGetValue( coord, out fetchedId );
  811. return fetchedId;
  812. }
  813. }
  814. public bool AddToLocalVariables( MasterNodePortCategory category, int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue )
  815. {
  816. if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) )
  817. return false;
  818. string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";";
  819. return AddToLocalVariables( category, nodeId, value );
  820. }
  821. public bool AddToLocalVariables( int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue )
  822. {
  823. if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) )
  824. return false;
  825. string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";";
  826. return AddToLocalVariables( nodeId, value );
  827. }
  828. public bool AddToLocalVariables( MasterNodePortCategory category, int nodeId, string value, bool ignoreDuplicates = false )
  829. {
  830. if( string.IsNullOrEmpty( value ) )
  831. return false;
  832. switch( category )
  833. {
  834. case MasterNodePortCategory.Vertex:
  835. case MasterNodePortCategory.Tessellation:
  836. {
  837. return AddToVertexLocalVariables( nodeId, value, ignoreDuplicates );
  838. }
  839. case MasterNodePortCategory.Fragment:
  840. case MasterNodePortCategory.Debug:
  841. {
  842. return AddToLocalVariables( nodeId, value, ignoreDuplicates );
  843. }
  844. }
  845. return false;
  846. }
  847. public bool AddLocalVariable( int nodeId, string customType, string varName, string varValue )
  848. {
  849. if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) )
  850. return false;
  851. string value = customType + " " + varName + " = " + varValue + ";";
  852. return AddLocalVariable( nodeId, value );
  853. }
  854. public bool AddLocalVariable( int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue )
  855. {
  856. if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) )
  857. return false;
  858. string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";";
  859. return AddLocalVariable( nodeId, value );
  860. }
  861. public bool AddLocalVariable( int nodeId, string name, string value, bool ignoreDuplicates = false )
  862. {
  863. return AddLocalVariable( nodeId, name + " = " + value, ignoreDuplicates );
  864. }
  865. public bool AddLocalVariable( int nodeId, string value, bool ignoreDuplicates = false )
  866. {
  867. if( string.IsNullOrEmpty( value ) )
  868. return false;
  869. switch( m_portCategory )
  870. {
  871. case MasterNodePortCategory.Vertex:
  872. case MasterNodePortCategory.Tessellation:
  873. {
  874. return AddToVertexLocalVariables( nodeId, value, ignoreDuplicates );
  875. }
  876. case MasterNodePortCategory.Fragment:
  877. case MasterNodePortCategory.Debug:
  878. {
  879. return AddToLocalVariables( nodeId, value, ignoreDuplicates );
  880. }
  881. }
  882. return false;
  883. }
  884. public string AddVirtualLocalVariable( int nodeId, string variable, string value )
  885. {
  886. if( string.IsNullOrEmpty( value ) )
  887. return string.Empty;
  888. string result = string.Empty;
  889. //switch ( m_portCategory )
  890. //{
  891. //case MasterNodePortCategory.Vertex:
  892. //case MasterNodePortCategory.Tessellation:
  893. //{
  894. //}
  895. //break;
  896. //case MasterNodePortCategory.Fragment:
  897. //case MasterNodePortCategory.Debug:
  898. //{
  899. if( !m_virtualVariablesDict.ContainsKey( value ) )
  900. {
  901. m_virtualVariablesDict.Add( value, variable );
  902. result = variable;
  903. }
  904. else
  905. {
  906. m_virtualVariablesDict.TryGetValue( value, out result );
  907. }
  908. //}
  909. //break;
  910. //}
  911. return result;
  912. }
  913. public void AddCodeComments( bool forceForwardSlash, params string[] comments )
  914. {
  915. if( m_portCategory == MasterNodePortCategory.Tessellation || m_portCategory == MasterNodePortCategory.Vertex )
  916. {
  917. AddToVertexLocalVariables( 0, IOUtils.CreateCodeComments( forceForwardSlash, comments ) );
  918. }
  919. else
  920. {
  921. AddToLocalVariables( 0, IOUtils.CreateCodeComments( forceForwardSlash, comments ) );
  922. }
  923. }
  924. public bool AddToLocalVariables( int nodeId, string value, bool ignoreDuplicates = false )
  925. {
  926. if( string.IsNullOrEmpty( value ) )
  927. return false;
  928. if( m_usingCustomOutput )
  929. {
  930. if( !m_customOutputDict.ContainsKey( value ) || ignoreDuplicates )
  931. {
  932. if( !m_customOutputDict.ContainsKey( value ) )
  933. m_customOutputDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  934. m_customOutputList.Add( m_customOutputDict[ value ] );
  935. m_customOutput += "\t\t\t" + value + '\n';
  936. return true;
  937. }
  938. else
  939. {
  940. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning );
  941. }
  942. }
  943. else
  944. {
  945. if( !m_localVariablesDict.ContainsKey( value ) || ignoreDuplicates )
  946. {
  947. if( !m_localVariablesDict.ContainsKey( value ) )
  948. m_localVariablesDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  949. m_localVariablesList.Add( m_localVariablesDict[ value ] );
  950. AddToSpecialLocalVariables( nodeId, value, ignoreDuplicates );
  951. return true;
  952. }
  953. else
  954. {
  955. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning );
  956. }
  957. }
  958. return false;
  959. }
  960. public void AddToSpecialLocalVariables( int nodeId, string value, bool ignoreDuplicates = false )
  961. {
  962. if( string.IsNullOrEmpty( value ) )
  963. return;
  964. if( m_usingCustomOutput )
  965. {
  966. if( !m_customOutputDict.ContainsKey( value ) || ignoreDuplicates )
  967. {
  968. if( !m_customOutputDict.ContainsKey( value ) )
  969. m_customOutputDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  970. m_customOutputList.Add( m_customOutputDict[ value ] );
  971. m_customOutput += "\t\t\t" + value + '\n';
  972. m_dirtySpecialLocalVariables = true;
  973. }
  974. else
  975. {
  976. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToSpecialLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning );
  977. }
  978. }
  979. else
  980. {
  981. if( !m_specialLocalVariablesDict.ContainsKey( value ) || ignoreDuplicates )
  982. {
  983. if( !m_specialLocalVariablesDict.ContainsKey( value ) )
  984. m_specialLocalVariablesDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  985. m_specialLocalVariablesList.Add( m_specialLocalVariablesDict[ value ] );
  986. m_specialLocalVariables += "\t\t\t" + value + '\n';
  987. m_dirtySpecialLocalVariables = true;
  988. }
  989. else
  990. {
  991. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToSpecialLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning );
  992. }
  993. }
  994. }
  995. public void ClearSpecialLocalVariables()
  996. {
  997. //m_specialLocalVariablesDict.Clear();
  998. m_specialLocalVariables = string.Empty;
  999. m_dirtySpecialLocalVariables = false;
  1000. }
  1001. public bool AddToVertexLocalVariables( int nodeId, string varName, string varValue )
  1002. {
  1003. if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) )
  1004. return false;
  1005. string value = varName + " = " + varValue + ";";
  1006. return AddToVertexLocalVariables( nodeId, value );
  1007. }
  1008. public bool AddToVertexLocalVariables( int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue )
  1009. {
  1010. if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) )
  1011. return false;
  1012. string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";";
  1013. return AddToVertexLocalVariables( nodeId, value );
  1014. }
  1015. public bool AddToVertexLocalVariables( int nodeId, string value, bool ignoreDuplicates = false )
  1016. {
  1017. if( string.IsNullOrEmpty( value ) )
  1018. return false;
  1019. if( !m_vertexLocalVariablesDict.ContainsKey( value ) || ignoreDuplicates )
  1020. {
  1021. if( !m_vertexLocalVariablesDict.ContainsKey( value ) )
  1022. m_vertexLocalVariablesDict.Add( value, new PropertyDataCollector( nodeId, value ) );
  1023. m_vertexLocalVariablesList.Add( m_vertexLocalVariablesDict[ value ] );
  1024. m_vertexLocalVariables += "\t\t\t" + value + '\n';
  1025. m_dirtyVertexLocalVariables = true;
  1026. return true;
  1027. }
  1028. else
  1029. {
  1030. if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToVertexLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning );
  1031. }
  1032. return false;
  1033. }
  1034. public void ClearVertexLocalVariables()
  1035. {
  1036. //m_vertexLocalVariablesDict.Clear();
  1037. m_vertexLocalVariables = string.Empty;
  1038. m_dirtyVertexLocalVariables = false;
  1039. }
  1040. public bool CheckFunction( string header )
  1041. {
  1042. return m_localFunctions.ContainsKey( header );
  1043. }
  1044. public string AddFunctions( string header, string body, params object[] inParams )
  1045. {
  1046. if( !m_localFunctions.ContainsKey( header ) )
  1047. {
  1048. m_localFunctions.Add( header, body );
  1049. m_functionsList.Add( new PropertyDataCollector( -1, body.Replace( "\t\t", string.Empty ) ) );
  1050. m_functions += "\n" + body + "\n";
  1051. m_dirtyFunctions = true;
  1052. }
  1053. return String.Format( header, inParams );
  1054. }
  1055. public string AddFunctions( string header, string[] bodyLines, bool addNewLine, params object[] inParams )
  1056. {
  1057. if( !m_localFunctions.ContainsKey( header ) )
  1058. {
  1059. string body = string.Empty;
  1060. for( int i = 0; i < bodyLines.Length; i++ )
  1061. {
  1062. body += ( m_masterNodeCategory == AvailableShaderTypes.Template ) ? bodyLines[ i ] : "\t\t" + bodyLines[ i ];
  1063. if( addNewLine )
  1064. body += '\n';
  1065. }
  1066. m_localFunctions.Add( header, body );
  1067. m_functionsList.Add( new PropertyDataCollector( -1, body ) );
  1068. m_functions += "\n" + body + "\n";
  1069. m_dirtyFunctions = true;
  1070. }
  1071. return String.Format( header, inParams );
  1072. }
  1073. public bool HasFunction( string functionId )
  1074. {
  1075. return m_localFunctions.ContainsKey( functionId );
  1076. }
  1077. public void AddFunction( string functionId, string body )
  1078. {
  1079. if( !m_localFunctions.ContainsKey( functionId ) )
  1080. {
  1081. m_functionsList.Add( new PropertyDataCollector( -1, body ) );
  1082. m_localFunctions.Add( functionId, body );
  1083. m_functions += "\n" + body + "\n";
  1084. m_dirtyFunctions = true;
  1085. }
  1086. }
  1087. public void AddFunction( string functionId, string[] bodyLines, bool addNewline )
  1088. {
  1089. if( !m_localFunctions.ContainsKey( functionId ) )
  1090. {
  1091. string body = string.Empty;
  1092. for( int i = 0; i < bodyLines.Length; i++ )
  1093. {
  1094. body += ( m_masterNodeCategory == AvailableShaderTypes.Template ) ? bodyLines[ i ] : "\t\t" + bodyLines[ i ];
  1095. if( addNewline )
  1096. body += '\n';
  1097. }
  1098. m_functionsList.Add( new PropertyDataCollector( -1, body ) );
  1099. m_localFunctions.Add( functionId, body );
  1100. m_functions += "\n" + body + "\n";
  1101. m_dirtyFunctions = true;
  1102. }
  1103. }
  1104. public void AddInstructions( string value, bool addTabs = false, bool addLineEnding = false )
  1105. {
  1106. m_instructionsList.Add( new PropertyDataCollector( -1, value ) );
  1107. m_instructions += addTabs ? "\t\t\t" + value : value;
  1108. if( addLineEnding )
  1109. {
  1110. m_instructions += '\n';
  1111. }
  1112. m_dirtyInstructions = true;
  1113. }
  1114. public void AddInstructions( bool addLineEnding, bool addTabs, params string[] values )
  1115. {
  1116. for( int i = 0; i < values.Length; i++ )
  1117. {
  1118. m_instructionsList.Add( new PropertyDataCollector( -1, values[ i ] ) );
  1119. m_instructions += addTabs ? "\t\t\t" + values[ i ] : values[ i ];
  1120. if( addLineEnding )
  1121. {
  1122. m_instructions += '\n';
  1123. }
  1124. }
  1125. m_dirtyInstructions = true;
  1126. }
  1127. public void AddToStartInstructions( string value )
  1128. {
  1129. if( string.IsNullOrEmpty( value ) )
  1130. return;
  1131. m_instructions = value + m_instructions;
  1132. m_dirtyInstructions = true;
  1133. }
  1134. public void ResetInstructions()
  1135. {
  1136. m_instructionsList.Clear();
  1137. m_instructions = string.Empty;
  1138. m_dirtyInstructions = false;
  1139. }
  1140. public void ResetVertexInstructions()
  1141. {
  1142. m_vertexDataList.Clear();
  1143. m_vertexData = string.Empty;
  1144. m_dirtyPerVertexData = false;
  1145. }
  1146. public void AddPropertyNode( PropertyNode node )
  1147. {
  1148. if( !m_propertyNodes.ContainsKey( node.UniqueId ) )
  1149. {
  1150. m_propertyNodes.Add( node.UniqueId, node );
  1151. }
  1152. }
  1153. public void UpdateMaterialOnPropertyNodes( Material material )
  1154. {
  1155. m_masterNode.UpdateMaterial( material );
  1156. foreach( KeyValuePair<int, PropertyNode> kvp in m_propertyNodes )
  1157. {
  1158. kvp.Value.UpdateMaterial( material );
  1159. }
  1160. }
  1161. public void AddToVertexInput( string value )
  1162. {
  1163. if( !m_vertexInputDict.ContainsKey( value ) )
  1164. {
  1165. m_vertexInputDict.Add( value, value );
  1166. m_vertexInputList.Add( value );
  1167. }
  1168. }
  1169. public void AddToInterpolators( string value )
  1170. {
  1171. if( !m_interpolatorsDict.ContainsKey( value ) )
  1172. {
  1173. m_interpolatorsDict.Add( value, value );
  1174. m_interpolatorsList.Add( value );
  1175. }
  1176. }
  1177. public void AddToVertexInterpolatorsDecl( string value )
  1178. {
  1179. if( !m_vertexInterpDeclDict.ContainsKey( value ) )
  1180. {
  1181. m_vertexInterpDeclDict.Add( value, value );
  1182. m_vertexInterpDeclList.Add( value );
  1183. }
  1184. }
  1185. public void UpdateShaderImporter( ref Shader shader )
  1186. {
  1187. ShaderImporter importer = (ShaderImporter)ShaderImporter.GetAtPath( AssetDatabase.GetAssetPath( shader ) );
  1188. if( m_propertyNodes.Count > 0 )
  1189. {
  1190. try
  1191. {
  1192. bool hasContents = false;
  1193. TextureDefaultsDataColector defaultCol = new TextureDefaultsDataColector();
  1194. foreach( KeyValuePair<int, PropertyNode> kvp in m_propertyNodes )
  1195. {
  1196. hasContents = kvp.Value.UpdateShaderDefaults( ref shader, ref defaultCol ) || hasContents;
  1197. }
  1198. if( hasContents )
  1199. {
  1200. importer.SetDefaultTextures( defaultCol.NamesArr, defaultCol.ValuesArr );
  1201. defaultCol.Destroy();
  1202. defaultCol = null;
  1203. }
  1204. }
  1205. catch( Exception e )
  1206. {
  1207. Debug.LogException( e );
  1208. }
  1209. }
  1210. importer.SaveAndReimport();
  1211. }
  1212. public void AddCustomAppData( string value )
  1213. {
  1214. if( m_customAppDataItemsDict.ContainsKey( value ) )
  1215. return;
  1216. m_customAppDataItemsDict.Add( value, value );
  1217. m_customAppDataItems += "\t\t\t"+value+"\n";
  1218. m_dirtyAppData = true;
  1219. }
  1220. public string CustomAppDataName { get { return m_dirtyAppData ? Constants.CustomAppDataFullName : Constants.AppDataFullName; } }
  1221. public string CustomAppData
  1222. {
  1223. get
  1224. {
  1225. if( m_dirtyPerVertexData )
  1226. return Constants.CustomAppDataFullBody + m_customAppDataItems + "\t\t};\n";
  1227. return string.Empty;
  1228. }
  1229. }
  1230. public void Destroy()
  1231. {
  1232. m_masterNode = null;
  1233. m_customAppDataItemsDict.Clear();
  1234. m_customAppDataItemsDict = null;
  1235. m_inputList.Clear();
  1236. m_inputList = null;
  1237. m_customInputList.Clear();
  1238. m_customInputList = null;
  1239. m_propertiesList.Clear();
  1240. m_propertiesList = null;
  1241. m_instancedPropertiesList.Clear();
  1242. m_instancedPropertiesList = null;
  1243. m_uniformsList.Clear();
  1244. m_uniformsList = null;
  1245. m_additionalDirectivesList.Clear();
  1246. m_additionalDirectivesList = null;
  1247. m_includesList.Clear();
  1248. m_includesList = null;
  1249. //m_tagsList.Clear();
  1250. //m_tagsList = null;
  1251. m_pragmasList.Clear();
  1252. m_pragmasList = null;
  1253. m_definesList.Clear();
  1254. m_definesList = null;
  1255. m_instructionsList.Clear();
  1256. m_instructionsList = null;
  1257. m_localVariablesList.Clear();
  1258. m_localVariablesList = null;
  1259. m_vertexLocalVariablesList.Clear();
  1260. m_vertexLocalVariablesList = null;
  1261. m_specialLocalVariablesList.Clear();
  1262. m_specialLocalVariablesList = null;
  1263. m_vertexDataList.Clear();
  1264. m_vertexDataList = null;
  1265. m_customOutputList.Clear();
  1266. m_customOutputList = null;
  1267. m_functionsList.Clear();
  1268. m_functionsList = null;
  1269. m_grabPassList.Clear();
  1270. m_grabPassList = null;
  1271. m_grabPassDict.Clear();
  1272. m_grabPassDict = null;
  1273. m_propertyNodes.Clear();
  1274. m_propertyNodes = null;
  1275. m_inputDict.Clear();
  1276. m_inputDict = null;
  1277. m_customInputDict.Clear();
  1278. m_customInputDict = null;
  1279. m_propertiesDict.Clear();
  1280. m_propertiesDict = null;
  1281. m_instancedPropertiesDict.Clear();
  1282. m_instancedPropertiesDict = null;
  1283. m_uniformsDict.Clear();
  1284. m_uniformsDict = null;
  1285. m_includesDict.Clear();
  1286. m_includesDict = null;
  1287. m_additionalDirectivesDict.Clear();
  1288. m_additionalDirectivesDict = null;
  1289. m_includesExclusionDict.Clear();
  1290. m_includesExclusionDict = null;
  1291. //m_tagsDict.Clear();
  1292. //m_tagsDict = null;
  1293. m_pragmasDict.Clear();
  1294. m_pragmasDict = null;
  1295. m_definesDict.Clear();
  1296. m_definesDict = null;
  1297. m_virtualCoordinatesDict.Clear();
  1298. m_virtualCoordinatesDict = null;
  1299. m_virtualVariablesDict.Clear();
  1300. m_virtualVariablesDict = null;
  1301. m_localVariablesDict.Clear();
  1302. m_localVariablesDict = null;
  1303. m_specialLocalVariablesDict.Clear();
  1304. m_specialLocalVariablesDict = null;
  1305. m_vertexLocalVariablesDict.Clear();
  1306. m_vertexLocalVariablesDict = null;
  1307. m_localFunctions.Clear();
  1308. m_localFunctions = null;
  1309. m_vertexDataDict.Clear();
  1310. m_vertexDataDict = null;
  1311. m_customOutputDict.Clear();
  1312. m_customOutputDict = null;
  1313. //templates
  1314. m_vertexInputList.Clear();
  1315. m_vertexInputList = null;
  1316. m_vertexInputDict.Clear();
  1317. m_vertexInputDict = null;
  1318. m_interpolatorsList.Clear();
  1319. m_interpolatorsList = null;
  1320. m_interpolatorsDict.Clear();
  1321. m_interpolatorsDict = null;
  1322. m_vertexInterpDeclList.Clear();
  1323. m_vertexInterpDeclList = null;
  1324. m_vertexInterpDeclDict.Clear();
  1325. m_vertexInterpDeclDict = null;
  1326. m_templateDataCollector.Destroy();
  1327. m_templateDataCollector = null;
  1328. m_customShadowCoordsDict.Clear();
  1329. m_customShadowCoordsDict = null;
  1330. m_customShadowCoordsList.Clear();
  1331. m_customShadowCoordsDict = null;
  1332. m_packSlotsList.Clear();
  1333. m_packSlotsList = null;
  1334. }
  1335. public string Inputs { get { return m_input; } }
  1336. public string CustomInput { get { return m_customInput; } }
  1337. public string Properties { get { return m_properties; } }
  1338. public string InstanceBlockName { get { return m_instanceBlockName; } }
  1339. public string InstancedProperties { get { return m_instancedProperties; } }
  1340. public string Uniforms { get { return m_uniforms; } }
  1341. public string Instructions { get { return m_instructions; } }
  1342. public string Includes { get { return m_includes; } }
  1343. public string Pragmas { get { return m_pragmas; } }
  1344. public string Defines { get { return m_defines; } }
  1345. public string LocalVariables { get { return m_localVariables; } }
  1346. public string SpecialLocalVariables { get { return m_specialLocalVariables; } }
  1347. public string VertexLocalVariables { get { return m_vertexLocalVariables; } }
  1348. public string VertexLocalVariablesFromList
  1349. {
  1350. get
  1351. {
  1352. string result = string.Empty;
  1353. int count = m_vertexLocalVariablesList.Count;
  1354. for( int i = 0; i < count; i++ )
  1355. {
  1356. result += m_vertexLocalVariablesList[ i ].PropertyName + "\n";
  1357. }
  1358. return result;
  1359. }
  1360. }
  1361. public string VertexData { get { return m_vertexData; } }
  1362. public string CustomOutput { get { return m_customOutput; } }
  1363. public string Functions { get { return m_functions; } }
  1364. public string GrabPass { get { return m_grabPass; } }
  1365. public bool DirtyAppData { get { return m_dirtyAppData; } }
  1366. public bool DirtyInstructions { get { return m_dirtyInstructions; } }
  1367. public bool DirtyUniforms { get { return m_dirtyUniforms; } }
  1368. public bool DirtyProperties { get { return m_dirtyProperties; } }
  1369. public bool DirtyInstancedProperties { get { return m_dirtyInstancedProperties; } }
  1370. public bool DirtyInputs { get { return m_dirtyInputs; } }
  1371. public bool DirtyCustomInput { get { return m_dirtyCustomInputs; } }
  1372. public bool DirtyIncludes { get { return m_dirtyIncludes; } }
  1373. public bool DirtyPragmas { get { return m_dirtyPragmas; } }
  1374. public bool DirtyDefines { get { return m_dirtyDefines; } }
  1375. public bool DirtyAdditionalDirectives { get { return m_dirtyAdditionalDirectives; } }
  1376. public bool DirtyLocalVariables { get { return m_dirtyLocalVariables; } }
  1377. public bool DirtyVertexVariables { get { return m_dirtyVertexLocalVariables; } }
  1378. public bool DirtySpecialLocalVariables { get { return m_dirtySpecialLocalVariables; } }
  1379. public bool DirtyPerVertexData { get { return m_dirtyPerVertexData; } }
  1380. public bool DirtyFunctions { get { return m_dirtyFunctions; } }
  1381. public bool DirtyGrabPass { get { return m_grabPassIsDirty; } }
  1382. public int LocalVariablesAmount { get { return m_localVariablesDict.Count; } }
  1383. public int SpecialLocalVariablesAmount { get { return m_specialLocalVariablesDict.Count; } }
  1384. public int VertexLocalVariablesAmount { get { return m_vertexLocalVariablesDict.Count; } }
  1385. public bool TesselationActive { set { m_tesselationActive = value; } get { return m_tesselationActive; } }
  1386. public int AvailableVertexTempId { get { return m_availableVertexTempId++; } }
  1387. public int AvailableFragTempId { get { return m_availableFragTempId++; } }
  1388. /// <summary>
  1389. /// Returns true if Normal output is being written by something else
  1390. /// </summary>
  1391. public bool DirtyNormal
  1392. {
  1393. get { return m_dirtyNormal; }
  1394. set { m_dirtyNormal = value; }
  1395. }
  1396. public bool IsFragmentCategory
  1397. {
  1398. get { return m_portCategory == MasterNodePortCategory.Fragment || m_portCategory == MasterNodePortCategory.Debug; }
  1399. }
  1400. public MasterNodePortCategory PortCategory
  1401. {
  1402. get { return m_portCategory; }
  1403. set { m_portCategory = value; }
  1404. }
  1405. public PortGenType GenType
  1406. {
  1407. get { return m_genType; }
  1408. set { m_genType = value; }
  1409. }
  1410. public bool IsTemplate { get { return m_masterNodeCategory == AvailableShaderTypes.Template; } }
  1411. public bool IsSRP { get { return ( TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.Lightweight || TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD); } }
  1412. public AvailableShaderTypes MasterNodeCategory
  1413. {
  1414. get { return m_masterNodeCategory; }
  1415. set { m_masterNodeCategory = value; }
  1416. }
  1417. /// <summary>
  1418. /// Forces write to Normal output when the output is not connected
  1419. /// </summary>
  1420. public bool ForceNormal
  1421. {
  1422. get { return m_forceNormal; }
  1423. set
  1424. {
  1425. if( value )
  1426. {
  1427. if( !m_forceNormalIsDirty )
  1428. {
  1429. m_forceNormal = value;
  1430. m_forceNormalIsDirty = value;
  1431. }
  1432. }
  1433. else
  1434. {
  1435. m_forceNormal = value;
  1436. }
  1437. }
  1438. }
  1439. public bool UsingVertexColor
  1440. {
  1441. get { return m_usingVertexColor; }
  1442. set { m_usingVertexColor = value; }
  1443. }
  1444. public bool UsingInternalData
  1445. {
  1446. get { return m_usingInternalData; }
  1447. set { m_usingInternalData = value; }
  1448. }
  1449. public bool UsingScreenPos
  1450. {
  1451. get { return m_usingScreenPos; }
  1452. set { m_usingScreenPos = value; }
  1453. }
  1454. public bool UsingCustomScreenPos
  1455. {
  1456. get { return m_usingCustomScreenPos; }
  1457. set { m_usingCustomScreenPos = value; }
  1458. }
  1459. public bool UsingWorldNormal
  1460. {
  1461. get { return m_usingWorldNormal; }
  1462. set { m_usingWorldNormal = value; }
  1463. }
  1464. public bool UsingWorldReflection
  1465. {
  1466. get { return m_usingWorldReflection; }
  1467. set { m_usingWorldReflection = value; }
  1468. }
  1469. public bool UsingWorldPosition
  1470. {
  1471. get { return m_usingWorldPosition; }
  1472. set { m_usingWorldPosition = value; }
  1473. }
  1474. public bool UsingViewDirection
  1475. {
  1476. get { return m_usingViewDirection; }
  1477. set { m_usingViewDirection = value; }
  1478. }
  1479. public bool IsOutlineDataCollector
  1480. {
  1481. get { return m_isOutlineDataCollector; }
  1482. set { m_isOutlineDataCollector = value; }
  1483. }
  1484. public bool UsingCustomOutlineColor
  1485. {
  1486. get { return m_usingCustomOutlineColor; }
  1487. set { m_usingCustomOutlineColor = value; }
  1488. }
  1489. public bool UsingCustomOutlineWidth
  1490. {
  1491. get { return m_usingCustomOutlineWidth; }
  1492. set { m_usingCustomOutlineWidth = value; }
  1493. }
  1494. public bool UsingCustomOutlineAlpha
  1495. {
  1496. get { return m_usingCustomOutlineAlpha; }
  1497. set { m_usingCustomOutlineAlpha = value; }
  1498. }
  1499. public int CustomOutlineSelectedAlpha
  1500. {
  1501. get { return m_customOutlineSelectedAlpha; }
  1502. set { m_customOutlineSelectedAlpha = value; }
  1503. }
  1504. public bool UsingCustomOutput
  1505. {
  1506. get { return m_usingCustomOutput; }
  1507. set { m_usingCustomOutput = value; }
  1508. }
  1509. public bool UsingHigherSizeTexcoords
  1510. {
  1511. get { return m_usingHigherSizeTexcoords; }
  1512. set { m_usingHigherSizeTexcoords = value; }
  1513. }
  1514. public bool UsingLightAttenuation
  1515. {
  1516. get { return m_usingLightAttenuation; }
  1517. set { m_usingLightAttenuation = value; }
  1518. }
  1519. public bool UsingArrayDerivatives
  1520. {
  1521. get { return m_usingArrayDerivatives; }
  1522. set { m_usingArrayDerivatives = value; }
  1523. }
  1524. public bool SafeNormalizeLightDir
  1525. {
  1526. get { return m_safeNormalizeLightDir; }
  1527. set { m_safeNormalizeLightDir = value; }
  1528. }
  1529. public bool SafeNormalizeViewDir
  1530. {
  1531. get { return m_safeNormalizeViewDir; }
  1532. set { m_safeNormalizeViewDir = value; }
  1533. }
  1534. public string StandardAdditionalDirectives
  1535. {
  1536. get
  1537. {
  1538. string body = string.Empty;
  1539. int count = m_additionalDirectivesList.Count;
  1540. for( int i = 0; i < count; i++ )
  1541. {
  1542. body += "\t\t" + m_additionalDirectivesList[i].PropertyName + "\n";
  1543. }
  1544. return body;
  1545. }
  1546. }
  1547. public List<PropertyDataCollector> InputList { get { return m_inputList; } }
  1548. public List<PropertyDataCollector> CustomInputList { get { return m_customInputList; } }
  1549. public List<PropertyDataCollector> PropertiesList { get { return m_propertiesList; } }
  1550. public List<PropertyDataCollector> InstancedPropertiesList { get { return m_instancedPropertiesList; } }
  1551. public List<PropertyDataCollector> UniformsList { get { return m_uniformsList; } }
  1552. public List<PropertyDataCollector> MiscList { get { return m_additionalDirectivesList; } }
  1553. public List<PropertyDataCollector> IncludesList { get { return m_includesList; } }
  1554. //public List<PropertyDataCollector> TagsList { get { return m_tagsList; } }
  1555. public List<PropertyDataCollector> PragmasList { get { return m_pragmasList; } }
  1556. public List<PropertyDataCollector> DefinesList { get { return m_definesList; } }
  1557. public List<PropertyDataCollector> InstructionsList { get { return m_instructionsList; } }
  1558. public List<PropertyDataCollector> LocalVariablesList { get { return m_localVariablesList; } }
  1559. public List<PropertyDataCollector> VertexLocalVariablesList { get { return m_vertexLocalVariablesList; } }
  1560. public List<PropertyDataCollector> SpecialLocalVariablesList { get { return m_specialLocalVariablesList; } }
  1561. public List<PropertyDataCollector> VertexDataList { get { return m_vertexDataList; } }
  1562. public List<PropertyDataCollector> CustomOutputList { get { return m_customOutputList; } }
  1563. public List<PropertyDataCollector> FunctionsList { get { return m_functionsList; } }
  1564. public List<PropertyDataCollector> GrabPassList { get { return m_grabPassList; } }
  1565. public Dictionary<string, string> GrabPassDict { get { return m_grabPassDict; } }
  1566. public List<InputCoordsCollector> CustomShadowCoordsList { get { return m_customShadowCoordsList; } }
  1567. public List<int> PackSlotsList { get { return m_packSlotsList; } }
  1568. public Dictionary<string, string> LocalFunctions { get { return m_localFunctions; } }
  1569. //Templates
  1570. public List<string> VertexInputList { get { return m_vertexInputList; } }
  1571. public List<string> InterpolatorList { get { return m_interpolatorsList; } }
  1572. public List<string> VertexInterpDeclList { get { return m_vertexInterpDeclList; } }
  1573. public TemplateDataCollector TemplateDataCollectorInstance { get { return m_templateDataCollector; } }
  1574. public RenderPath CurrentRenderPath
  1575. {
  1576. get { return m_renderPath; }
  1577. set { m_renderPath = value; }
  1578. }
  1579. public NodeAvailability CurrentCanvasMode { get { return m_currentCanvasMode; } set { m_currentCanvasMode = value; } }
  1580. public TemplateSRPType CurrentSRPType
  1581. {
  1582. get
  1583. {
  1584. if( IsTemplate )
  1585. return m_templateDataCollector.CurrentSRPType;
  1586. return TemplateSRPType.BuiltIn;
  1587. }
  1588. }
  1589. }
  1590. }