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.

447 lines
16 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using UnityEngine;
  5. using UnityEditor;
  6. using System.Collections.Generic;
  7. namespace AmplifyShaderEditor
  8. {
  9. public enum AvailableBlendFactor
  10. {
  11. One = 1,
  12. Zero = 0,
  13. SrcColor = 3,
  14. SrcAlpha = 5,
  15. DstColor = 2,
  16. DstAlpha = 7,
  17. OneMinusSrcColor = 6,
  18. OneMinusSrcAlpha = 10,
  19. OneMinusDstColor = 4,
  20. OneMinusDstAlpha = 8,
  21. SrcAlphaSaturate = 9
  22. };
  23. public enum AvailableBlendOps
  24. {
  25. OFF = 0,
  26. Add,
  27. Sub,
  28. RevSub,
  29. Min,
  30. Max,
  31. //Direct X11 only
  32. LogicalClear,
  33. LogicalSet,
  34. LogicalCopy,
  35. LogicalCopyInverted,
  36. LogicalNoop,
  37. LogicalInvert,
  38. LogicalAnd,
  39. LogicalNand,
  40. LogicalOr,
  41. LogicalNor,
  42. LogicalXor,
  43. LogicalEquiv,
  44. LogicalAndReverse,
  45. LogicalAndInverted,
  46. LogicalOrReverse,
  47. LogicalOrInverted
  48. };
  49. public class CommonBlendTypes
  50. {
  51. public string Name;
  52. public AvailableBlendFactor SourceFactor;
  53. public AvailableBlendFactor DestFactor;
  54. public CommonBlendTypes( string name, AvailableBlendFactor sourceFactor, AvailableBlendFactor destFactor )
  55. {
  56. Name = name;
  57. SourceFactor = sourceFactor;
  58. DestFactor = destFactor;
  59. }
  60. }
  61. [Serializable]
  62. public class BlendOpsHelper
  63. {
  64. public static readonly string[] BlendOpsLabels =
  65. {
  66. "<OFF>",
  67. "Add",
  68. "Sub",
  69. "RevSub",
  70. "Min",
  71. "Max",
  72. "LogicalClear ( DX11.1 Only )",
  73. "LogicalSet ( DX11.1 Only )",
  74. "LogicalCopy ( DX11.1 Only )",
  75. "LogicalCopyInverted ( DX11.1 Only )",
  76. "LogicalNoop ( DX11.1 Only )",
  77. "LogicalInvert ( DX11.1 Only )",
  78. "LogicalAnd ( DX11.1 Only )",
  79. "LogicalNand ( DX11.1 Only )",
  80. "LogicalOr ( DX11.1 Only )",
  81. "LogicalNor ( DX11.1 Only )",
  82. "LogicalXor ( DX11.1 Only )",
  83. "LogicalEquiv ( DX11.1 Only )",
  84. "LogicalAndReverse ( DX11.1 Only )",
  85. "LogicalAndInverted ( DX11.1 Only )",
  86. "LogicalOrReverse ( DX11.1 Only )",
  87. "LogicalOrInverted ( DX11.1 Only )"
  88. };
  89. private const string BlendModesRGBStr = "Blend RGB";
  90. private const string BlendModesAlphaStr = "Blend Alpha";
  91. private const string BlendOpsRGBStr = "Blend Op RGB";
  92. private const string BlendOpsAlphaStr = "Blend Op Alpha";
  93. private const string SourceFactorStr = "Src";
  94. private const string DstFactorStr = "Dst";
  95. private const string SingleBlendFactorStr = "Blend {0} {1}";
  96. private const string SeparateBlendFactorStr = "Blend {0} {1} , {2} {3}";
  97. private const string SingleBlendOpStr = "BlendOp {0}";
  98. private const string SeparateBlendOpStr = "BlendOp {0} , {1}";
  99. private string[] m_commonBlendTypesArr;
  100. private List<CommonBlendTypes> m_commonBlendTypes = new List<CommonBlendTypes> { new CommonBlendTypes("<OFF>", AvailableBlendFactor.Zero, AvailableBlendFactor.Zero ),
  101. new CommonBlendTypes("Custom", AvailableBlendFactor.Zero, AvailableBlendFactor.Zero ) ,
  102. new CommonBlendTypes("Alpha Blend", AvailableBlendFactor.SrcAlpha, AvailableBlendFactor.OneMinusSrcAlpha ) ,
  103. new CommonBlendTypes("Premultiplied", AvailableBlendFactor.One, AvailableBlendFactor.OneMinusSrcAlpha ),
  104. new CommonBlendTypes("Additive", AvailableBlendFactor.One, AvailableBlendFactor.One ),
  105. new CommonBlendTypes("Soft Additive", AvailableBlendFactor.OneMinusDstColor, AvailableBlendFactor.One ),
  106. new CommonBlendTypes("Multiplicative", AvailableBlendFactor.DstColor, AvailableBlendFactor.Zero ),
  107. new CommonBlendTypes("2x Multiplicative", AvailableBlendFactor.DstColor, AvailableBlendFactor.SrcColor ),
  108. new CommonBlendTypes("Particle Additive", AvailableBlendFactor.SrcAlpha, AvailableBlendFactor.One ),};
  109. [SerializeField]
  110. private bool m_enabled = false;
  111. // Blend Factor
  112. // RGB
  113. [SerializeField]
  114. private int m_currentIndex = 0;
  115. [SerializeField]
  116. private InlineProperty m_sourceFactorRGB = new InlineProperty( 0 );
  117. [SerializeField]
  118. private InlineProperty m_destFactorRGB = new InlineProperty( 0 );
  119. // Alpha
  120. [SerializeField]
  121. private int m_currentAlphaIndex = 0;
  122. [SerializeField]
  123. private InlineProperty m_sourceFactorAlpha = new InlineProperty( 0 );
  124. [SerializeField]
  125. private InlineProperty m_destFactorAlpha = new InlineProperty( 0 );
  126. //Blend Ops
  127. [SerializeField]
  128. private bool m_blendOpEnabled = false;
  129. [SerializeField]
  130. private InlineProperty m_blendOpRGB = new InlineProperty( 0 );
  131. [SerializeField]
  132. private InlineProperty m_blendOpAlpha = new InlineProperty( 0 );
  133. public BlendOpsHelper()
  134. {
  135. m_commonBlendTypesArr = new string[ m_commonBlendTypes.Count ];
  136. for( int i = 0; i < m_commonBlendTypesArr.Length; i++ )
  137. {
  138. m_commonBlendTypesArr[ i ] = m_commonBlendTypes[ i ].Name;
  139. }
  140. }
  141. public void Draw( UndoParentNode owner, bool customBlendAvailable )
  142. {
  143. m_enabled = customBlendAvailable;
  144. // RGB
  145. EditorGUI.BeginChangeCheck();
  146. m_currentIndex = owner.EditorGUILayoutPopup( BlendModesRGBStr, m_currentIndex, m_commonBlendTypesArr );
  147. if( EditorGUI.EndChangeCheck() )
  148. {
  149. if( m_currentIndex > 1 )
  150. {
  151. m_sourceFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].SourceFactor;
  152. m_sourceFactorRGB.SetInlineNodeValue();
  153. m_destFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].DestFactor;
  154. m_destFactorRGB.SetInlineNodeValue();
  155. }
  156. }
  157. EditorGUI.BeginDisabledGroup( m_currentIndex == 0 );
  158. EditorGUI.BeginChangeCheck();
  159. float cached = EditorGUIUtility.labelWidth;
  160. EditorGUIUtility.labelWidth = 40;
  161. EditorGUILayout.BeginHorizontal();
  162. AvailableBlendFactor tempCast = (AvailableBlendFactor)m_sourceFactorRGB.IntValue;
  163. m_sourceFactorRGB.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( SourceFactorStr, tempCast ); }, SourceFactorStr );
  164. m_sourceFactorRGB.IntValue = (int)tempCast;
  165. EditorGUI.indentLevel--;
  166. EditorGUIUtility.labelWidth = 25;
  167. tempCast = (AvailableBlendFactor)m_destFactorRGB.IntValue;
  168. m_destFactorRGB.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( DstFactorStr, tempCast ); }, DstFactorStr );
  169. m_destFactorRGB.IntValue = (int)tempCast;
  170. EditorGUI.indentLevel++;
  171. EditorGUILayout.EndHorizontal();
  172. EditorGUIUtility.labelWidth = cached;
  173. if( EditorGUI.EndChangeCheck() )
  174. {
  175. CheckRGBIndex();
  176. }
  177. // Both these tests should be removed on a later stage
  178. // ASE v154dev004 changed AvailableBlendOps.OFF value from -1 to 0
  179. // If importing the new package into an already opened ASE window makes
  180. // hotcode to preserve the -1 value on these variables
  181. if( m_blendOpRGB.FloatValue < 0 )
  182. m_blendOpRGB.FloatValue = 0;
  183. if( m_blendOpAlpha.FloatValue < 0 )
  184. m_blendOpAlpha.FloatValue = 0;
  185. EditorGUI.BeginChangeCheck();
  186. //AvailableBlendOps tempOpCast = (AvailableBlendOps)m_blendOpRGB.IntValue;
  187. m_blendOpRGB.CustomDrawer( ref owner, ( x ) => { m_blendOpRGB.IntValue = x.EditorGUILayoutPopup( BlendOpsRGBStr, m_blendOpRGB.IntValue, BlendOpsLabels ); }, BlendOpsRGBStr );
  188. //m_blendOpRGB.IntValue = (int)tempOpCast;
  189. if( EditorGUI.EndChangeCheck() )
  190. {
  191. m_blendOpEnabled = ( !m_blendOpRGB.Active && m_blendOpRGB.IntValue > -1 ) || ( m_blendOpRGB.Active && m_blendOpRGB.NodeId > -1 );//AvailableBlendOps.OFF;
  192. m_blendOpRGB.SetInlineNodeValue();
  193. }
  194. EditorGUI.EndDisabledGroup();
  195. // Alpha
  196. EditorGUILayout.Separator();
  197. EditorGUI.BeginChangeCheck();
  198. m_currentAlphaIndex = owner.EditorGUILayoutPopup( BlendModesAlphaStr, m_currentAlphaIndex, m_commonBlendTypesArr );
  199. if( EditorGUI.EndChangeCheck() )
  200. {
  201. if( m_currentAlphaIndex > 0 )
  202. {
  203. m_sourceFactorAlpha.IntValue = (int)m_commonBlendTypes[ m_currentAlphaIndex ].SourceFactor;
  204. m_sourceFactorAlpha.SetInlineNodeValue();
  205. m_destFactorAlpha.IntValue = (int)m_commonBlendTypes[ m_currentAlphaIndex ].DestFactor;
  206. m_destFactorAlpha.SetInlineNodeValue();
  207. }
  208. }
  209. EditorGUI.BeginDisabledGroup( m_currentAlphaIndex == 0 );
  210. EditorGUI.BeginChangeCheck();
  211. cached = EditorGUIUtility.labelWidth;
  212. EditorGUIUtility.labelWidth = 40;
  213. EditorGUILayout.BeginHorizontal();
  214. tempCast = (AvailableBlendFactor)m_sourceFactorAlpha.IntValue;
  215. m_sourceFactorAlpha.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( SourceFactorStr, tempCast ); }, SourceFactorStr );
  216. m_sourceFactorAlpha.IntValue = (int)tempCast;
  217. EditorGUI.indentLevel--;
  218. EditorGUIUtility.labelWidth = 25;
  219. tempCast = (AvailableBlendFactor)m_destFactorAlpha.IntValue;
  220. m_destFactorAlpha.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( DstFactorStr, tempCast ); }, DstFactorStr );
  221. m_destFactorAlpha.IntValue = (int)tempCast;
  222. EditorGUI.indentLevel++;
  223. EditorGUILayout.EndHorizontal();
  224. EditorGUIUtility.labelWidth = cached;
  225. if( EditorGUI.EndChangeCheck() )
  226. {
  227. CheckAlphaIndex();
  228. }
  229. EditorGUI.BeginChangeCheck();
  230. //tempOpCast = (AvailableBlendOps)m_blendOpAlpha.IntValue;
  231. m_blendOpAlpha.CustomDrawer( ref owner, ( x ) => { m_blendOpAlpha.IntValue = x.EditorGUILayoutPopup( BlendOpsAlphaStr, m_blendOpAlpha.IntValue, BlendOpsLabels ); }, BlendOpsAlphaStr );
  232. //m_blendOpAlpha.IntValue = (int)tempOpCast;
  233. if( EditorGUI.EndChangeCheck() )
  234. {
  235. m_blendOpAlpha.SetInlineNodeValue();
  236. }
  237. EditorGUI.EndDisabledGroup();
  238. EditorGUILayout.Separator();
  239. }
  240. void CheckRGBIndex()
  241. {
  242. int count = m_commonBlendTypes.Count;
  243. m_currentIndex = 1;
  244. for( int i = 1; i < count; i++ )
  245. {
  246. if( m_commonBlendTypes[ i ].SourceFactor == (AvailableBlendFactor)m_sourceFactorRGB.IntValue && m_commonBlendTypes[ i ].DestFactor == (AvailableBlendFactor)m_destFactorRGB.IntValue )
  247. {
  248. m_currentIndex = i;
  249. return;
  250. }
  251. }
  252. }
  253. void CheckAlphaIndex()
  254. {
  255. int count = m_commonBlendTypes.Count;
  256. m_currentAlphaIndex = 1;
  257. for( int i = 1; i < count; i++ )
  258. {
  259. if( m_commonBlendTypes[ i ].SourceFactor == (AvailableBlendFactor)m_sourceFactorAlpha.IntValue && m_commonBlendTypes[ i ].DestFactor == (AvailableBlendFactor)m_destFactorAlpha.IntValue )
  260. {
  261. m_currentAlphaIndex = i;
  262. if( m_currentAlphaIndex > 0 && m_currentIndex == 0 )
  263. m_currentIndex = 1;
  264. return;
  265. }
  266. }
  267. if( m_currentAlphaIndex > 0 && m_currentIndex == 0 )
  268. m_currentIndex = 1;
  269. }
  270. public void ReadFromString( ref uint index, ref string[] nodeParams )
  271. {
  272. m_currentIndex = Convert.ToInt32( nodeParams[ index++ ] );
  273. if( UIUtils.CurrentShaderVersion() > 15103 )
  274. {
  275. m_sourceFactorRGB.ReadFromString( ref index, ref nodeParams );
  276. m_destFactorRGB.ReadFromString( ref index, ref nodeParams );
  277. }
  278. else
  279. {
  280. m_sourceFactorRGB.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] );
  281. m_destFactorRGB.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] );
  282. }
  283. m_currentAlphaIndex = Convert.ToInt32( nodeParams[ index++ ] );
  284. if( UIUtils.CurrentShaderVersion() > 15103 )
  285. {
  286. m_sourceFactorAlpha.ReadFromString( ref index, ref nodeParams );
  287. m_destFactorAlpha.ReadFromString( ref index, ref nodeParams );
  288. m_blendOpRGB.ReadFromString( ref index, ref nodeParams );
  289. m_blendOpAlpha.ReadFromString( ref index, ref nodeParams );
  290. if( UIUtils.CurrentShaderVersion() < 15404 )
  291. {
  292. // Now BlendOps enum starts at 0 and not -1
  293. m_blendOpRGB.FloatValue += 1;
  294. m_blendOpAlpha.FloatValue += 1;
  295. }
  296. }
  297. else
  298. {
  299. m_sourceFactorAlpha.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] );
  300. m_destFactorAlpha.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] );
  301. m_blendOpRGB.IntValue = (int)(AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), nodeParams[ index++ ] );
  302. m_blendOpAlpha.IntValue = (int)(AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), nodeParams[ index++ ] );
  303. }
  304. m_enabled = ( m_currentIndex > 0 || m_currentAlphaIndex > 0 );
  305. m_blendOpEnabled = ( !m_blendOpRGB.Active && m_blendOpRGB.IntValue > -1 ) || ( m_blendOpRGB.Active && m_blendOpRGB.NodeId > -1 );
  306. }
  307. public void WriteToString( ref string nodeInfo )
  308. {
  309. IOUtils.AddFieldValueToString( ref nodeInfo, m_currentIndex );
  310. m_sourceFactorRGB.WriteToString( ref nodeInfo );
  311. m_destFactorRGB.WriteToString( ref nodeInfo );
  312. IOUtils.AddFieldValueToString( ref nodeInfo, m_currentAlphaIndex );
  313. m_sourceFactorAlpha.WriteToString( ref nodeInfo );
  314. m_destFactorAlpha.WriteToString( ref nodeInfo );
  315. m_blendOpRGB.WriteToString( ref nodeInfo );
  316. m_blendOpAlpha.WriteToString( ref nodeInfo );
  317. }
  318. public void SetBlendOpsFromBlendMode( AlphaMode mode, bool customBlendAvailable )
  319. {
  320. switch( mode )
  321. {
  322. case AlphaMode.Transparent:
  323. m_currentIndex = 2;
  324. m_sourceFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].SourceFactor;
  325. m_destFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].DestFactor;
  326. break;
  327. case AlphaMode.Masked:
  328. case AlphaMode.Translucent:
  329. m_currentIndex = 0;
  330. break;
  331. case AlphaMode.Premultiply:
  332. m_currentIndex = 3;
  333. m_sourceFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].SourceFactor;
  334. m_destFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].DestFactor;
  335. break;
  336. }
  337. m_enabled = customBlendAvailable;
  338. }
  339. public string CreateBlendOps()
  340. {
  341. string result = "\t\t" + CurrentBlendFactor + "\n";
  342. if( m_blendOpEnabled )
  343. {
  344. result += "\t\t" + CurrentBlendOp + "\n";
  345. }
  346. return result;
  347. }
  348. public string CurrentBlendRGB { get { return m_commonBlendTypes[ m_currentIndex ].Name; } }
  349. public string CurrentBlendFactorSingle { get { return string.Format( SingleBlendFactorStr, m_sourceFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_sourceFactorRGB.IntValue ).ToString() ), m_destFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_destFactorRGB.IntValue ).ToString() ) ); } }
  350. //public string CurrentBlendFactorSingleAlpha { get { return string.Format(SeparateBlendFactorStr, m_sourceFactorRGB, m_destFactorRGB, m_sourceFactorAlpha, m_destFactorAlpha); } }
  351. public string CurrentBlendFactorSeparate
  352. {
  353. get
  354. {
  355. string src = ( m_currentIndex > 0 ? m_sourceFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_sourceFactorRGB.IntValue ).ToString() ) : AvailableBlendFactor.One.ToString() );
  356. string dst = ( m_currentIndex > 0 ? m_destFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_destFactorRGB.IntValue ).ToString() ) : AvailableBlendFactor.Zero.ToString() );
  357. string srca = m_sourceFactorAlpha.GetValueOrProperty( ( (AvailableBlendFactor)m_sourceFactorAlpha.IntValue ).ToString() );
  358. string dsta = m_destFactorAlpha.GetValueOrProperty( ( (AvailableBlendFactor)m_destFactorAlpha.IntValue ).ToString() );
  359. return string.Format( SeparateBlendFactorStr, src, dst, srca, dsta );
  360. }
  361. }
  362. public string CurrentBlendFactor { get { return ( ( m_currentAlphaIndex > 0 ) ? CurrentBlendFactorSeparate : CurrentBlendFactorSingle ); } }
  363. public string CurrentBlendOpSingle
  364. {
  365. get
  366. {
  367. string value = m_blendOpRGB.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpRGB.IntValue ).ToString() );
  368. if( value.Equals( ( AvailableBlendOps.OFF ).ToString() ) )
  369. return string.Empty;
  370. return string.Format( SingleBlendOpStr, value );
  371. }
  372. }
  373. public string CurrentBlendOpSeparate
  374. {
  375. get
  376. {
  377. string rgbValue = m_blendOpRGB.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpRGB.IntValue ).ToString() );
  378. if( rgbValue.Equals( ( AvailableBlendOps.OFF ).ToString() ))
  379. rgbValue = "Add";
  380. string alphaValue = m_blendOpAlpha.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpAlpha.IntValue ).ToString() );
  381. return string.Format( SeparateBlendOpStr, ( m_currentIndex > 0 ? rgbValue : AvailableBlendOps.Add.ToString() ), alphaValue );
  382. }
  383. }
  384. public string CurrentBlendOp { get { return ( ( m_currentAlphaIndex > 0 && m_blendOpAlpha.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpAlpha.IntValue ).ToString() ) != AvailableBlendOps.OFF.ToString() ) ? CurrentBlendOpSeparate : CurrentBlendOpSingle ); } }
  385. public bool Active { get { return m_enabled && ( m_currentIndex > 0 || m_currentAlphaIndex > 0 ); } }
  386. }
  387. }