TextureArrayNode.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. namespace AmplifyShaderEditor
  7. {
  8. [Serializable]
  9. //[NodeAttributes( "Texture Array", "Textures", "Texture Array fetches a texture from a texture2DArray asset file given a index value", KeyCode.None, true, 0, int.MaxValue, typeof( Texture2DArray ) )]
  10. [NodeAttributes( "[Old]Texture Array", "Textures", "Texture Array fetches a texture from a texture2DArray asset file given a index value", null, KeyCode.None, true, true, "SamplerNode", typeof( SamplerNode ) )]
  11. public class TextureArrayNode : PropertyNode
  12. {
  13. [SerializeField]
  14. private Texture2DArray m_defaultTextureArray;
  15. [SerializeField]
  16. private Texture2DArray m_materialTextureArray;
  17. [SerializeField]
  18. private TexReferenceType m_referenceType = TexReferenceType.Object;
  19. [SerializeField]
  20. private int m_uvSet = 0;
  21. [SerializeField]
  22. private MipType m_mipMode = MipType.Auto;
  23. private readonly string[] m_mipOptions = { "Auto", "Mip Level", "Derivative" };
  24. private TextureArrayNode m_referenceSampler = null;
  25. [SerializeField]
  26. private int m_referenceArrayId = -1;
  27. [SerializeField]
  28. private int m_referenceNodeId = -1;
  29. [SerializeField]
  30. private bool m_autoUnpackNormals = false;
  31. private InputPort m_texPort;
  32. private InputPort m_uvPort;
  33. private InputPort m_indexPort;
  34. private InputPort m_lodPort;
  35. private InputPort m_normalPort;
  36. private InputPort m_ddxPort;
  37. private InputPort m_ddyPort;
  38. private OutputPort m_colorPort;
  39. private const string AutoUnpackNormalsStr = "Normal";
  40. private const string NormalScaleStr = "Scale";
  41. private string m_labelText = "None (Texture2DArray)";
  42. private readonly Color ReferenceHeaderColor = new Color( 2.66f, 1.02f, 0.6f, 1.0f );
  43. private int m_cachedUvsId = -1;
  44. private int m_cachedSamplerId = -1;
  45. private int m_texConnectedId = -1;
  46. private int m_cachedUnpackId = -1;
  47. private int m_cachedLodId = -1;
  48. private Rect m_iconPos;
  49. private bool m_isEditingPicker;
  50. private bool m_linearTexture;
  51. protected bool m_drawPicker;
  52. private ReferenceState m_state = ReferenceState.Self;
  53. private ParentNode m_previewTextProp = null;
  54. protected override void CommonInit( int uniqueId )
  55. {
  56. base.CommonInit( uniqueId );
  57. AddOutputColorPorts( "RGBA" );
  58. m_colorPort = m_outputPorts[ 0 ];
  59. AddInputPort( WirePortDataType.SAMPLER2D, false, "Tex", -1, MasterNodePortCategory.Fragment, 6 );
  60. AddInputPort( WirePortDataType.FLOAT2, false, "UV", -1, MasterNodePortCategory.Fragment, 0 );
  61. AddInputPort( WirePortDataType.FLOAT, false, "Index", -1, MasterNodePortCategory.Fragment, 1 );
  62. AddInputPort( WirePortDataType.FLOAT, false, "Level", -1, MasterNodePortCategory.Fragment, 2 );
  63. AddInputPort( WirePortDataType.FLOAT, false, NormalScaleStr, -1, MasterNodePortCategory.Fragment, 3 );
  64. AddInputPort( WirePortDataType.FLOAT2, false, "DDX", -1, MasterNodePortCategory.Fragment, 4 );
  65. AddInputPort( WirePortDataType.FLOAT2, false, "DDY", -1, MasterNodePortCategory.Fragment, 5 );
  66. m_inputPorts[ 2 ].AutoDrawInternalData = true;
  67. m_texPort = m_inputPorts[ 0 ];
  68. m_uvPort = m_inputPorts[ 1 ];
  69. m_indexPort = m_inputPorts[ 2 ];
  70. m_lodPort = m_inputPorts[ 3 ];
  71. m_lodPort.Visible = false;
  72. m_normalPort = m_inputPorts[ 4 ];
  73. m_normalPort.Visible = m_autoUnpackNormals;
  74. m_normalPort.FloatInternalData = 1.0f;
  75. m_ddxPort = m_inputPorts[ 5 ];
  76. m_ddxPort.Visible = false;
  77. m_ddyPort = m_inputPorts[ 6 ];
  78. m_ddyPort.Visible = false;
  79. m_insideSize.Set( 128, 128 + 5 );
  80. m_drawPrecisionUI = false;
  81. m_currentParameterType = PropertyType.Property;
  82. m_availableAttribs.Add( new PropertyAttributes( "No Scale Offset", "[NoScaleOffset]" ) );
  83. m_freeType = false;
  84. m_showPreview = true;
  85. m_drawPreviewExpander = false;
  86. m_drawPreview = false;
  87. m_drawPicker = true;
  88. m_customPrefix = "Texture Array ";
  89. m_selectedLocation = PreviewLocation.TopCenter;
  90. m_previewShaderGUID = "2e6d093df2d289f47b827b36efb31a81";
  91. m_showAutoRegisterUI = false;
  92. }
  93. public override void SetPreviewInputs()
  94. {
  95. base.SetPreviewInputs();
  96. if( m_cachedUvsId == -1 )
  97. m_cachedUvsId = Shader.PropertyToID( "_CustomUVs" );
  98. if( m_cachedSamplerId == -1 )
  99. m_cachedSamplerId = Shader.PropertyToID( "_Sampler" );
  100. if( m_texConnectedId == -1 )
  101. m_texConnectedId = Shader.PropertyToID( "_TexConnected" );
  102. if( m_cachedUnpackId == -1 )
  103. m_cachedUnpackId = Shader.PropertyToID( "_Unpack" );
  104. if( m_cachedLodId == -1 )
  105. m_cachedLodId = Shader.PropertyToID( "_LodType" );
  106. PreviewMaterial.SetFloat( m_cachedLodId, ( m_mipMode == MipType.MipLevel ? 1 : 0 ) );
  107. PreviewMaterial.SetFloat( m_cachedUnpackId, m_autoUnpackNormals ? 1 : 0 );
  108. if( m_referenceType == TexReferenceType.Instance && m_referenceSampler != null )
  109. {
  110. if( (ParentNode)m_referenceSampler != m_referenceSampler.PreviewTextProp )
  111. {
  112. PreviewMaterial.SetInt( m_texConnectedId, 1 );
  113. PreviewMaterial.SetTexture( "_G", m_referenceSampler.PreviewTextProp.PreviewTexture );
  114. }
  115. else
  116. {
  117. PreviewMaterial.SetInt( m_texConnectedId, 0 );
  118. PreviewMaterial.SetTexture( m_cachedSamplerId, m_referenceSampler.TextureArray );
  119. }
  120. }
  121. else if( m_texPort.IsConnected )
  122. {
  123. PreviewMaterial.SetInt( m_texConnectedId, 1 );
  124. }
  125. else
  126. {
  127. PreviewMaterial.SetInt( m_texConnectedId, 0 );
  128. PreviewMaterial.SetTexture( m_cachedSamplerId, TextureArray );
  129. }
  130. PreviewMaterial.SetFloat( m_cachedUvsId, ( m_uvPort.IsConnected ? 1 : 0 ) );
  131. }
  132. protected override void OnUniqueIDAssigned()
  133. {
  134. base.OnUniqueIDAssigned();
  135. if( m_referenceType == TexReferenceType.Object )
  136. {
  137. UIUtils.RegisterTextureArrayNode( this );
  138. UIUtils.RegisterPropertyNode( this );
  139. }
  140. if( UniqueId > -1 )
  141. ContainerGraph.TextureArrayNodes.OnReorderEventComplete += OnReorderEventComplete;
  142. }
  143. private void OnReorderEventComplete()
  144. {
  145. if( m_referenceType == TexReferenceType.Instance && m_referenceSampler != null )
  146. {
  147. m_referenceArrayId = ContainerGraph.TextureArrayNodes.GetNodeRegisterIdx( m_referenceSampler.UniqueId );
  148. }
  149. }
  150. new void ShowDefaults()
  151. {
  152. m_uvSet = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_uvSet, Constants.AvailableUVSetsStr, Constants.AvailableUVSets );
  153. MipType newMipMode = (MipType)EditorGUILayoutPopup( "Mip Mode", (int)m_mipMode, m_mipOptions );
  154. if( newMipMode != m_mipMode )
  155. {
  156. m_mipMode = newMipMode;
  157. }
  158. switch( m_mipMode )
  159. {
  160. case MipType.Auto:
  161. m_lodPort.Visible = false;
  162. m_ddxPort.Visible = false;
  163. m_ddyPort.Visible = false;
  164. break;
  165. case MipType.MipLevel:
  166. m_lodPort.Visible = true;
  167. m_ddxPort.Visible = false;
  168. m_ddyPort.Visible = false;
  169. break;
  170. case MipType.MipBias:
  171. case MipType.Derivative:
  172. m_ddxPort.Visible = true;
  173. m_ddyPort.Visible = true;
  174. m_lodPort.Visible = false;
  175. break;
  176. }
  177. if( m_ddxPort.Visible )
  178. {
  179. EditorGUILayout.HelpBox( "Warning: Derivative Mip Mode only works on some platforms (D3D11 XBOXONE GLES3 GLCORE)", MessageType.Warning );
  180. }
  181. if( !m_lodPort.IsConnected && m_lodPort.Visible )
  182. {
  183. m_lodPort.FloatInternalData = EditorGUILayoutFloatField( "Mip Level", m_lodPort.FloatInternalData );
  184. }
  185. if( !m_indexPort.IsConnected )
  186. {
  187. m_indexPort.FloatInternalData = EditorGUILayoutFloatField( "Index", m_indexPort.FloatInternalData );
  188. }
  189. }
  190. public override void DrawMainPropertyBlock()
  191. {
  192. EditorGUI.BeginChangeCheck();
  193. m_referenceType = (TexReferenceType)EditorGUILayoutPopup( Constants.ReferenceTypeStr, (int)m_referenceType, Constants.ReferenceArrayLabels );
  194. if( EditorGUI.EndChangeCheck() )
  195. {
  196. if( m_referenceType == TexReferenceType.Object )
  197. {
  198. UIUtils.RegisterTextureArrayNode( this );
  199. UIUtils.RegisterPropertyNode( this );
  200. SetTitleText( m_propertyInspectorName );
  201. SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) );
  202. m_referenceArrayId = -1;
  203. m_referenceNodeId = -1;
  204. m_referenceSampler = null;
  205. }
  206. else
  207. {
  208. UIUtils.UnregisterTextureArrayNode( this );
  209. UIUtils.UnregisterPropertyNode( this );
  210. }
  211. UpdateHeaderColor();
  212. }
  213. if( m_referenceType == TexReferenceType.Object )
  214. {
  215. EditorGUI.BeginChangeCheck();
  216. base.DrawMainPropertyBlock();
  217. if( EditorGUI.EndChangeCheck() )
  218. {
  219. OnPropertyNameChanged();
  220. }
  221. }
  222. else
  223. {
  224. string[] arr = UIUtils.TextureArrayNodeArr();
  225. bool guiEnabledBuffer = GUI.enabled;
  226. if( arr != null && arr.Length > 0 )
  227. {
  228. GUI.enabled = true;
  229. }
  230. else
  231. {
  232. m_referenceArrayId = -1;
  233. GUI.enabled = false;
  234. }
  235. m_referenceArrayId = EditorGUILayoutPopup( Constants.AvailableReferenceStr, m_referenceArrayId, arr );
  236. GUI.enabled = guiEnabledBuffer;
  237. ShowDefaults();
  238. DrawSamplerOptions();
  239. }
  240. }
  241. public override void OnPropertyNameChanged()
  242. {
  243. base.OnPropertyNameChanged();
  244. UIUtils.UpdateTextureArrayDataNode( UniqueId, PropertyInspectorName );
  245. }
  246. public override void DrawSubProperties()
  247. {
  248. ShowDefaults();
  249. DrawSamplerOptions();
  250. EditorGUI.BeginChangeCheck();
  251. m_defaultTextureArray = EditorGUILayoutObjectField( Constants.DefaultValueLabel, m_defaultTextureArray, typeof( Texture2DArray ), false ) as Texture2DArray;
  252. if( EditorGUI.EndChangeCheck() )
  253. {
  254. CheckTextureImporter( true );
  255. SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) );
  256. }
  257. }
  258. public override void DrawMaterialProperties()
  259. {
  260. ShowDefaults();
  261. DrawSamplerOptions();
  262. EditorGUI.BeginChangeCheck();
  263. m_materialTextureArray = EditorGUILayoutObjectField( Constants.MaterialValueLabel, m_materialTextureArray, typeof( Texture2DArray ), false ) as Texture2DArray;
  264. if( EditorGUI.EndChangeCheck() )
  265. {
  266. CheckTextureImporter( true );
  267. SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) );
  268. m_requireMaterialUpdate = true;
  269. }
  270. }
  271. public void DrawSamplerOptions()
  272. {
  273. EditorGUI.BeginChangeCheck();
  274. bool autoUnpackNormals = EditorGUILayoutToggle( "Normal Map", m_autoUnpackNormals );
  275. if( EditorGUI.EndChangeCheck() )
  276. {
  277. if( m_autoUnpackNormals != autoUnpackNormals )
  278. {
  279. AutoUnpackNormals = autoUnpackNormals;
  280. ConfigureInputPorts();
  281. ConfigureOutputPorts();
  282. }
  283. }
  284. if( m_autoUnpackNormals && !m_normalPort.IsConnected )
  285. {
  286. m_normalPort.FloatInternalData = EditorGUILayoutFloatField( NormalScaleStr, m_normalPort.FloatInternalData );
  287. }
  288. }
  289. public void ConfigureInputPorts()
  290. {
  291. m_normalPort.Visible = AutoUnpackNormals;
  292. m_sizeIsDirty = true;
  293. }
  294. public void ConfigureOutputPorts()
  295. {
  296. m_outputPorts[ m_colorPort.PortId + 4 ].Visible = !AutoUnpackNormals;
  297. if( !AutoUnpackNormals )
  298. {
  299. m_colorPort.ChangeProperties( "RGBA", WirePortDataType.FLOAT4, false );
  300. m_outputPorts[ m_colorPort.PortId + 1 ].ChangeProperties( "R", WirePortDataType.FLOAT, false );
  301. m_outputPorts[ m_colorPort.PortId + 2 ].ChangeProperties( "G", WirePortDataType.FLOAT, false );
  302. m_outputPorts[ m_colorPort.PortId + 3 ].ChangeProperties( "B", WirePortDataType.FLOAT, false );
  303. m_outputPorts[ m_colorPort.PortId + 4 ].ChangeProperties( "A", WirePortDataType.FLOAT, false );
  304. }
  305. else
  306. {
  307. m_colorPort.ChangeProperties( "XYZ", WirePortDataType.FLOAT3, false );
  308. m_outputPorts[ m_colorPort.PortId + 1 ].ChangeProperties( "X", WirePortDataType.FLOAT, false );
  309. m_outputPorts[ m_colorPort.PortId + 2 ].ChangeProperties( "Y", WirePortDataType.FLOAT, false );
  310. m_outputPorts[ m_colorPort.PortId + 3 ].ChangeProperties( "Z", WirePortDataType.FLOAT, false );
  311. }
  312. m_sizeIsDirty = true;
  313. }
  314. public virtual void CheckTextureImporter( bool additionalCheck )
  315. {
  316. m_requireMaterialUpdate = true;
  317. Texture2DArray texture = m_materialMode ? m_materialTextureArray : m_defaultTextureArray;
  318. UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath( AssetDatabase.GetAssetPath( texture ), typeof( UnityEngine.Object ) );
  319. if( obj != null )
  320. {
  321. SerializedObject serializedObject = new UnityEditor.SerializedObject( obj );
  322. if( serializedObject != null )
  323. {
  324. SerializedProperty colorSpace = serializedObject.FindProperty( "m_ColorSpace" );
  325. m_linearTexture = ( colorSpace.intValue == 0 );
  326. }
  327. }
  328. }
  329. void UpdateHeaderColor()
  330. {
  331. m_headerColorModifier = ( m_referenceType == TexReferenceType.Object ) ? Color.white : ReferenceHeaderColor;
  332. }
  333. public override void DrawGUIControls( DrawInfo drawInfo )
  334. {
  335. base.DrawGUIControls( drawInfo );
  336. if( !( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp || drawInfo.CurrentEventType == EventType.ExecuteCommand || drawInfo.CurrentEventType == EventType.DragPerform ) )
  337. return;
  338. bool insideBox = m_previewRect.Contains( drawInfo.MousePosition );
  339. if( insideBox )
  340. {
  341. m_isEditingPicker = true;
  342. }
  343. else if( m_isEditingPicker && !insideBox && drawInfo.CurrentEventType != EventType.ExecuteCommand )
  344. {
  345. GUI.FocusControl( null );
  346. m_isEditingPicker = false;
  347. }
  348. if( m_state != ReferenceState.Self && drawInfo.CurrentEventType == EventType.MouseDown && m_previewRect.Contains( drawInfo.MousePosition ) )
  349. {
  350. UIUtils.FocusOnNode( m_previewTextProp, 1, true );
  351. Event.current.Use();
  352. }
  353. }
  354. public override void OnNodeLayout( DrawInfo drawInfo )
  355. {
  356. base.OnNodeLayout( drawInfo );
  357. if( m_drawPreview )
  358. {
  359. m_iconPos = m_globalPosition;
  360. m_iconPos.width = 19 * drawInfo.InvertedZoom;
  361. m_iconPos.height = 19 * drawInfo.InvertedZoom;
  362. m_iconPos.y += 10 * drawInfo.InvertedZoom;
  363. m_iconPos.x += m_globalPosition.width - m_iconPos.width - 5 * drawInfo.InvertedZoom;
  364. }
  365. bool instanced = CheckReference();
  366. if( instanced )
  367. {
  368. m_state = ReferenceState.Instance;
  369. m_previewTextProp = m_referenceSampler;
  370. }
  371. else if( m_texPort.IsConnected )
  372. {
  373. m_state = ReferenceState.Connected;
  374. m_previewTextProp = m_texPort.GetOutputNode( 0 ) as ParentNode;
  375. }
  376. else
  377. {
  378. m_state = ReferenceState.Self;
  379. m_previewTextProp = this;
  380. }
  381. if( m_previewTextProp == null )
  382. m_previewTextProp = this;
  383. }
  384. public override void Draw( DrawInfo drawInfo )
  385. {
  386. base.Draw( drawInfo );
  387. if( m_isEditingPicker && m_drawPicker )
  388. {
  389. Rect hitRect = m_previewRect;
  390. hitRect.height = 14 * drawInfo.InvertedZoom;
  391. hitRect.y = m_previewRect.yMax - hitRect.height;
  392. hitRect.width = 4 * 14 * drawInfo.InvertedZoom;
  393. bool restoreMouse = false;
  394. if( Event.current.type == EventType.MouseDown && hitRect.Contains( drawInfo.MousePosition ) )
  395. {
  396. restoreMouse = true;
  397. Event.current.type = EventType.Ignore;
  398. }
  399. EditorGUI.BeginChangeCheck();
  400. m_colorBuffer = GUI.color;
  401. GUI.color = Color.clear;
  402. if( m_materialMode )
  403. m_materialTextureArray = EditorGUIObjectField( m_previewRect, m_materialTextureArray, typeof( Texture2DArray ), false ) as Texture2DArray;
  404. else
  405. m_defaultTextureArray = EditorGUIObjectField( m_previewRect, m_defaultTextureArray, typeof( Texture2DArray ), false ) as Texture2DArray;
  406. GUI.color = m_colorBuffer;
  407. if( EditorGUI.EndChangeCheck() )
  408. {
  409. PreviewIsDirty = true;
  410. CheckTextureImporter( true );
  411. SetTitleText( PropertyInspectorName );
  412. SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) );
  413. ConfigureInputPorts();
  414. ConfigureOutputPorts();
  415. BeginDelayedDirtyProperty();
  416. m_requireMaterialUpdate = true;
  417. }
  418. if( restoreMouse )
  419. {
  420. Event.current.type = EventType.MouseDown;
  421. }
  422. if( ( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp ) )
  423. DrawPreviewMaskButtonsLayout( drawInfo, m_previewRect );
  424. }
  425. if( drawInfo.CurrentEventType != EventType.Repaint )
  426. return;
  427. switch( m_state )
  428. {
  429. default:
  430. case ReferenceState.Self:
  431. if( drawInfo.CurrentEventType == EventType.Repaint )
  432. {
  433. m_drawPreview = false;
  434. m_drawPicker = true;
  435. DrawTexturePicker( drawInfo );
  436. }
  437. break;
  438. case ReferenceState.Connected:
  439. if( drawInfo.CurrentEventType == EventType.Repaint )
  440. {
  441. m_drawPreview = true;
  442. m_drawPicker = false;
  443. if( m_previewTextProp != null )
  444. {
  445. SetTitleTextOnCallback( m_previewTextProp.TitleContent.text, ( instance, newTitle ) => instance.TitleContent.text = newTitle + " (Input)" );
  446. SetAdditonalTitleText( m_previewTextProp.AdditonalTitleContent.text );
  447. }
  448. // Draw chain lock
  449. GUI.Label( m_iconPos, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerTextureIcon ) );
  450. // Draw frame around preview
  451. GUI.Label( m_previewRect, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) );
  452. }
  453. break;
  454. case ReferenceState.Instance:
  455. {
  456. m_drawPreview = true;
  457. m_drawPicker = false;
  458. if( m_referenceSampler != null )
  459. {
  460. SetTitleTextOnCallback( m_referenceSampler.PreviewTextProp.TitleContent.text, ( instance, newTitle ) => instance.TitleContent.text = newTitle + Constants.InstancePostfixStr );
  461. SetAdditonalTitleText( m_referenceSampler.PreviewTextProp.AdditonalTitleContent.text );
  462. }
  463. // Draw chain lock
  464. GUI.Label( m_iconPos, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerTextureIcon ) );
  465. // Draw frame around preview
  466. GUI.Label( m_previewRect, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) );
  467. }
  468. break;
  469. }
  470. }
  471. protected void DrawTexturePicker( DrawInfo drawInfo )
  472. {
  473. Rect newRect = m_previewRect;
  474. Texture2DArray currentValue = m_materialMode ? m_materialTextureArray : m_defaultTextureArray;
  475. if( currentValue == null )
  476. GUI.Label( newRect, string.Empty, UIUtils.ObjectFieldThumb );
  477. else
  478. DrawPreview( drawInfo, m_previewRect );
  479. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 )
  480. {
  481. Rect butRect = m_previewRect;
  482. butRect.y -= 1;
  483. butRect.x += 1;
  484. Rect smallButton = newRect;
  485. smallButton.height = 14 * drawInfo.InvertedZoom;
  486. smallButton.y = newRect.yMax - smallButton.height - 2;
  487. smallButton.width = 40 * drawInfo.InvertedZoom;
  488. smallButton.x = newRect.xMax - smallButton.width - 2;
  489. if( currentValue == null )
  490. {
  491. GUI.Label( newRect, m_labelText, UIUtils.ObjectFieldThumbOverlay );
  492. }
  493. else
  494. {
  495. DrawPreviewMaskButtonsRepaint( drawInfo, butRect );
  496. }
  497. GUI.Label( smallButton, "Select", UIUtils.GetCustomStyle( CustomStyle.SamplerButton ) );
  498. }
  499. GUI.Label( newRect, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) );
  500. }
  501. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  502. {
  503. if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
  504. return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) );
  505. OnPropertyNameChanged();
  506. if( CheckReference() )
  507. {
  508. OrderIndex = m_referenceSampler.RawOrderIndex;
  509. OrderIndexOffset = m_referenceSampler.OrderIndexOffset;
  510. }
  511. bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation );
  512. bool instanced = false;
  513. if( m_referenceType == TexReferenceType.Instance && m_referenceSampler != null )
  514. instanced = true;
  515. if( instanced )
  516. {
  517. if( !m_referenceSampler.TexPort.IsConnected )
  518. base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar );
  519. }
  520. else if( !m_texPort.IsConnected )
  521. base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar );
  522. string level = string.Empty;
  523. if( m_lodPort.Visible )
  524. {
  525. level = m_lodPort.GeneratePortInstructions( ref dataCollector );
  526. }
  527. if( isVertex && !m_lodPort.Visible )
  528. level = "0";
  529. string propertyName = string.Empty;
  530. if( instanced )
  531. {
  532. if( m_referenceSampler.TexPort.IsConnected )
  533. propertyName = m_referenceSampler.TexPort.GeneratePortInstructions( ref dataCollector );
  534. else
  535. propertyName = m_referenceSampler.PropertyName;
  536. }
  537. else if( m_texPort.IsConnected )
  538. propertyName = m_texPort.GeneratePortInstructions( ref dataCollector );
  539. else
  540. propertyName = PropertyName;
  541. string uvs = string.Empty;
  542. if( m_uvPort.IsConnected )
  543. {
  544. uvs = m_uvPort.GeneratePortInstructions( ref dataCollector );
  545. }
  546. else
  547. {
  548. if( dataCollector.IsTemplate )
  549. {
  550. uvs = dataCollector.TemplateDataCollectorInstance.GetTextureCoord( m_uvSet, propertyName/*( instanced ? m_referenceSampler.PropertyName : PropertyName )*/, UniqueId, CurrentPrecisionType );
  551. }
  552. else
  553. {
  554. if( isVertex )
  555. uvs = TexCoordVertexDataNode.GenerateVertexUVs( ref dataCollector, UniqueId, m_uvSet, propertyName );
  556. else
  557. uvs = TexCoordVertexDataNode.GenerateFragUVs( ref dataCollector, UniqueId, m_uvSet, propertyName );
  558. }
  559. }
  560. string index = m_indexPort.GeneratePortInstructions( ref dataCollector );
  561. string result = string.Empty;
  562. if( dataCollector.IsTemplate && dataCollector.IsSRP )
  563. {
  564. //CAREFUL mipbias here means derivative (this needs index changes)
  565. //TODO: unity now supports bias as well
  566. if( m_mipMode == MipType.MipBias )
  567. {
  568. GeneratorUtils.AddCustomArraySamplingMacros( ref dataCollector );
  569. result = propertyName + ".SampleGrad(sampler" + propertyName + ", float3(" + uvs + ", " + index + "), " + m_ddxPort.GeneratePortInstructions( ref dataCollector ) + ", " + m_ddyPort.GeneratePortInstructions( ref dataCollector ) + ");";
  570. }
  571. else if( m_lodPort.Visible || isVertex )
  572. {
  573. result = "SAMPLE_TEXTURE2D_ARRAY_LOD(" + propertyName + ", sampler" + propertyName + ", " + uvs + ", " + index + ", " + level + " )";
  574. }
  575. else
  576. {
  577. result = "SAMPLE_TEXTURE2D_ARRAY(" + propertyName + ", sampler" + propertyName + ", " + uvs + ", " + index + " )";
  578. }
  579. }
  580. else
  581. {
  582. //CAREFUL mipbias here means derivative (this needs index changes)
  583. if( m_mipMode == MipType.MipBias )
  584. {
  585. GeneratorUtils.AddCustomArraySamplingMacros( ref dataCollector );
  586. result = "ASE_SAMPLE_TEX2DARRAY_GRAD(" + propertyName + ", float3(" + uvs + ", " + index + "), " + m_ddxPort.GeneratePortInstructions( ref dataCollector ) + ", " + m_ddyPort.GeneratePortInstructions( ref dataCollector ) + " )";
  587. }
  588. else if( m_lodPort.Visible || isVertex )
  589. {
  590. result = "UNITY_SAMPLE_TEX2DARRAY_LOD(" + propertyName + ", float3(" + uvs + ", " + index + "), " + level + " )";
  591. }
  592. else
  593. {
  594. result = "UNITY_SAMPLE_TEX2DARRAY" + ( m_lodPort.Visible || isVertex ? "_LOD" : "" ) + "(" + propertyName + ", float3(" + uvs + ", " + index + ") " + ( m_lodPort.Visible || isVertex ? ", " + level : "" ) + " )";
  595. }
  596. }
  597. if( m_autoUnpackNormals )
  598. {
  599. bool isScaledNormal = false;
  600. if( m_normalPort.IsConnected )
  601. {
  602. isScaledNormal = true;
  603. }
  604. else
  605. {
  606. if( m_normalPort.FloatInternalData != 1 )
  607. {
  608. isScaledNormal = true;
  609. }
  610. }
  611. string scaleValue = isScaledNormal ? m_normalPort.GeneratePortInstructions( ref dataCollector ) : "1.0";
  612. result = GeneratorUtils.GenerateUnpackNormalStr( ref dataCollector, CurrentPrecisionType, UniqueId, OutputId, result, isScaledNormal, scaleValue, UnpackInputMode.Tangent );
  613. if( isScaledNormal && ( !dataCollector.IsTemplate || !dataCollector.IsSRP ) )
  614. {
  615. dataCollector.AddToIncludes( UniqueId, Constants.UnityStandardUtilsLibFuncs );
  616. }
  617. }
  618. RegisterLocalVariable( 0, result, ref dataCollector, "texArray" + OutputId );
  619. return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) );
  620. }
  621. public override string PropertyName
  622. {
  623. get
  624. {
  625. if( m_referenceType == TexReferenceType.Instance && m_referenceSampler != null )
  626. return m_referenceSampler.PropertyName;
  627. else
  628. return base.PropertyName;
  629. }
  630. }
  631. public override string PropertyInspectorName
  632. {
  633. get
  634. {
  635. if( m_referenceType == TexReferenceType.Instance && m_referenceSampler != null )
  636. return m_referenceSampler.PropertyInspectorName;
  637. else
  638. return base.PropertyInspectorName;
  639. }
  640. }
  641. public override string GetPropertyValue()
  642. {
  643. return PropertyAttributes + PropertyName + "(\"" + PropertyInspectorName + "\", 2DArray ) = \"\" {}";
  644. }
  645. public override bool GetUniformData( out string dataType, out string dataName, ref bool fullValue )
  646. {
  647. MasterNode currMasterNode = ( m_containerGraph.CurrentMasterNode != null ) ? m_containerGraph.CurrentMasterNode : m_containerGraph.ParentWindow.OutsideGraph.CurrentMasterNode;
  648. if( currMasterNode != null && currMasterNode.CurrentDataCollector.IsTemplate && currMasterNode.CurrentDataCollector.IsSRP )
  649. {
  650. dataType = "TEXTURE2D_ARRAY( " + PropertyName + "";
  651. dataName = ");\nuniform SAMPLER( sampler" + PropertyName + " )";
  652. return true;
  653. }
  654. dataType = "UNITY_DECLARE_TEX2DARRAY(";
  655. dataName = PropertyName + " )";
  656. return true;
  657. }
  658. public override void ReadFromString( ref string[] nodeParams )
  659. {
  660. base.ReadFromString( ref nodeParams );
  661. string textureName = GetCurrentParam( ref nodeParams );
  662. m_defaultTextureArray = AssetDatabase.LoadAssetAtPath<Texture2DArray>( textureName );
  663. m_uvSet = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  664. m_referenceType = (TexReferenceType)Enum.Parse( typeof( TexReferenceType ), GetCurrentParam( ref nodeParams ) );
  665. m_referenceNodeId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  666. if( UIUtils.CurrentShaderVersion() > 3202 )
  667. m_mipMode = (MipType)Enum.Parse( typeof( MipType ), GetCurrentParam( ref nodeParams ) );
  668. if( UIUtils.CurrentShaderVersion() > 5105 )
  669. m_autoUnpackNormals = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
  670. if( m_referenceType == TexReferenceType.Instance )
  671. {
  672. UIUtils.UnregisterTextureArrayNode( this );
  673. UIUtils.UnregisterPropertyNode( this );
  674. }
  675. ConfigureInputPorts();
  676. ConfigureOutputPorts();
  677. m_lodPort.Visible = ( m_mipMode == MipType.MipLevel );
  678. m_ddxPort.Visible = ( m_mipMode == MipType.MipBias ); //not really bias, it's derivative
  679. m_ddyPort.Visible = ( m_mipMode == MipType.MipBias ); //not really bias, it's derivative
  680. UpdateHeaderColor();
  681. if( m_defaultTextureArray )
  682. {
  683. m_materialTextureArray = m_defaultTextureArray;
  684. }
  685. if( !m_isNodeBeingCopied && m_referenceType == TexReferenceType.Object )
  686. {
  687. ContainerGraph.TextureArrayNodes.UpdateDataOnNode( UniqueId, DataToArray );
  688. }
  689. }
  690. public override void RefreshExternalReferences()
  691. {
  692. base.RefreshExternalReferences();
  693. m_referenceSampler = UIUtils.GetNode( m_referenceNodeId ) as TextureArrayNode;
  694. m_referenceArrayId = UIUtils.GetTextureArrayNodeRegisterId( m_referenceNodeId );
  695. OnPropertyNameChanged();
  696. }
  697. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  698. {
  699. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  700. IOUtils.AddFieldValueToString( ref nodeInfo, ( m_defaultTextureArray != null ) ? AssetDatabase.GetAssetPath( m_defaultTextureArray ) : Constants.NoStringValue );
  701. IOUtils.AddFieldValueToString( ref nodeInfo, m_uvSet.ToString() );
  702. IOUtils.AddFieldValueToString( ref nodeInfo, m_referenceType );
  703. IOUtils.AddFieldValueToString( ref nodeInfo, ( ( m_referenceSampler != null ) ? m_referenceSampler.UniqueId : -1 ) );
  704. IOUtils.AddFieldValueToString( ref nodeInfo, m_mipMode );
  705. IOUtils.AddFieldValueToString( ref nodeInfo, m_autoUnpackNormals );
  706. }
  707. public override void ReadAdditionalClipboardData( ref string[] nodeParams )
  708. {
  709. base.ReadAdditionalClipboardData( ref nodeParams );
  710. string textureName = GetCurrentParam( ref nodeParams );
  711. m_materialTextureArray = AssetDatabase.LoadAssetAtPath<Texture2DArray>( textureName );
  712. }
  713. public override void WriteAdditionalClipboardData( ref string nodeInfo )
  714. {
  715. base.WriteAdditionalClipboardData( ref nodeInfo );
  716. IOUtils.AddFieldValueToString( ref nodeInfo, ( m_materialTextureArray != null ) ? AssetDatabase.GetAssetPath( m_materialTextureArray ) : Constants.NoStringValue );
  717. }
  718. public override void UpdateMaterial( Material mat )
  719. {
  720. base.UpdateMaterial( mat );
  721. if( UIUtils.IsProperty( m_currentParameterType ) && !InsideShaderFunction && m_referenceType == TexReferenceType.Object )
  722. {
  723. OnPropertyNameChanged();
  724. if( mat.HasProperty( PropertyName ) )
  725. {
  726. mat.SetTexture( PropertyName, m_materialTextureArray );
  727. }
  728. }
  729. }
  730. public override void SetMaterialMode( Material mat, bool fetchMaterialValues )
  731. {
  732. base.SetMaterialMode( mat, fetchMaterialValues );
  733. if( fetchMaterialValues && m_materialMode && UIUtils.IsProperty( m_currentParameterType ) )
  734. {
  735. if( mat.HasProperty( PropertyName ) )
  736. {
  737. m_materialTextureArray = (Texture2DArray)mat.GetTexture( PropertyName );
  738. if( m_materialTextureArray == null )
  739. m_materialTextureArray = m_defaultTextureArray;
  740. }
  741. }
  742. }
  743. public override void ForceUpdateFromMaterial( Material material )
  744. {
  745. if( UIUtils.IsProperty( m_currentParameterType ) && material.HasProperty( PropertyName ) )
  746. {
  747. m_materialTextureArray = (Texture2DArray)material.GetTexture( PropertyName );
  748. if( m_materialTextureArray == null )
  749. m_materialTextureArray = m_defaultTextureArray;
  750. PreviewIsDirty = true;
  751. }
  752. }
  753. public override bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol )
  754. {
  755. if( m_defaultTextureArray != null )
  756. {
  757. defaultCol.AddValue( PropertyName, m_defaultTextureArray );
  758. }
  759. return true;
  760. }
  761. public override string GetPropertyValStr()
  762. {
  763. return m_materialMode ? ( m_materialTextureArray != null ? m_materialTextureArray.name : IOUtils.NO_TEXTURES ) : ( m_defaultTextureArray != null ? m_defaultTextureArray.name : IOUtils.NO_TEXTURES );
  764. }
  765. public bool CheckReference()
  766. {
  767. if( m_referenceType == TexReferenceType.Instance && m_referenceArrayId > -1 )
  768. {
  769. m_referenceSampler = UIUtils.GetTextureArrayNode( m_referenceArrayId );
  770. if( m_referenceSampler == null )
  771. {
  772. m_texPort.Locked = false;
  773. m_referenceArrayId = -1;
  774. }
  775. else
  776. m_texPort.Locked = true;
  777. }
  778. else
  779. {
  780. m_texPort.Locked = false;
  781. }
  782. return m_referenceSampler != null;
  783. }
  784. public override void SetupFromCastObject( UnityEngine.Object obj )
  785. {
  786. base.SetupFromCastObject( obj );
  787. SetupFromObject( obj );
  788. }
  789. public override void OnObjectDropped( UnityEngine.Object obj )
  790. {
  791. SetupFromObject( obj );
  792. }
  793. private void SetupFromObject( UnityEngine.Object obj )
  794. {
  795. if( m_materialMode )
  796. m_materialTextureArray = obj as Texture2DArray;
  797. else
  798. m_defaultTextureArray = obj as Texture2DArray;
  799. }
  800. public Texture2DArray TextureArray { get { return ( m_materialMode ? m_materialTextureArray : m_defaultTextureArray ); } }
  801. public bool IsLinearTexture { get { return m_linearTexture; } }
  802. public bool AutoUnpackNormals
  803. {
  804. get { return m_autoUnpackNormals; }
  805. set { m_autoUnpackNormals = value; }
  806. }
  807. public override string DataToArray { get { return PropertyInspectorName; } }
  808. public override void Destroy()
  809. {
  810. base.Destroy();
  811. m_defaultTextureArray = null;
  812. m_materialTextureArray = null;
  813. m_texPort = null;
  814. m_uvPort = null;
  815. m_indexPort = null;
  816. m_lodPort = null;
  817. m_normalPort = null;
  818. m_ddxPort = null;
  819. m_ddyPort = null;
  820. if( m_referenceType == TexReferenceType.Object )
  821. {
  822. UIUtils.UnregisterTextureArrayNode( this );
  823. UIUtils.UnregisterPropertyNode( this );
  824. }
  825. if( UniqueId > -1 )
  826. ContainerGraph.TextureArrayNodes.OnReorderEventComplete -= OnReorderEventComplete;
  827. }
  828. public ParentNode PreviewTextProp { get { return m_previewTextProp; } }
  829. public InputPort TexPort { get { return m_texPort; } }
  830. }
  831. }