ASETextureArrayCreator.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. //#define NEW_TEXTURE_3D_METHOD
  4. using UnityEngine;
  5. using UnityEditor;
  6. using System.Collections.Generic;
  7. using UnityEditorInternal;
  8. using System;
  9. using System.IO;
  10. namespace AmplifyShaderEditor
  11. {
  12. [CustomEditor( typeof( TextureArrayCreatorAsset ) )]
  13. public class TextureArrayCreatorAssetEditor : Editor
  14. {
  15. private string[] m_sizesStr = { "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192" };
  16. private int[] m_sizes = { 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
  17. private const string ArrayFilename = "NewTextureArray";
  18. private const string Texture3DFilename = "NewTexture3D";
  19. private GUIContent m_pathButtonContent = new GUIContent();
  20. private GUIStyle m_pathButtonStyle = null;
  21. public TextureArrayCreatorAsset Instance;
  22. private DragAndDropTool m_dragAndDropTool;
  23. SerializedObject m_so;
  24. SerializedProperty m_selectedSize;
  25. SerializedProperty m_lockRatio;
  26. SerializedProperty m_sizeX;
  27. SerializedProperty m_sizeY;
  28. SerializedProperty m_tex3DMode;
  29. SerializedProperty m_linearMode;
  30. SerializedProperty m_mipMaps;
  31. SerializedProperty m_wrapMode;
  32. SerializedProperty m_filterMode;
  33. SerializedProperty m_anisoLevel;
  34. SerializedProperty m_selectedFormatEnum;
  35. SerializedProperty m_quality;
  36. SerializedProperty m_folderPath;
  37. SerializedProperty m_fileName;
  38. SerializedProperty m_filenameChanged;
  39. SerializedProperty m_allTextures;
  40. [SerializeField]
  41. private ReorderableList m_listTextures = null;
  42. [SerializeField]
  43. private int m_previewSize;
  44. public void OnEnable()
  45. {
  46. Instance = (TextureArrayCreatorAsset)target;
  47. m_so = serializedObject;
  48. m_selectedSize = m_so.FindProperty( "m_selectedSize" );
  49. m_lockRatio = m_so.FindProperty( "m_lockRatio" );
  50. m_sizeX = m_so.FindProperty( "m_sizeX" );
  51. m_sizeY = m_so.FindProperty( "m_sizeY" );
  52. m_tex3DMode = m_so.FindProperty( "m_tex3DMode" );
  53. m_linearMode = m_so.FindProperty( "m_linearMode" );
  54. m_mipMaps = m_so.FindProperty( "m_mipMaps" );
  55. m_wrapMode = m_so.FindProperty( "m_wrapMode" );
  56. m_filterMode = m_so.FindProperty( "m_filterMode" );
  57. m_anisoLevel = m_so.FindProperty( "m_anisoLevel" );
  58. m_selectedFormatEnum = m_so.FindProperty( "m_selectedFormatEnum" );
  59. m_quality = m_so.FindProperty( "m_quality" );
  60. m_folderPath = m_so.FindProperty( "m_folderPath" );
  61. m_fileName = m_so.FindProperty( "m_fileName" );
  62. m_filenameChanged = m_so.FindProperty( "m_filenameChanged" );
  63. m_allTextures = m_so.FindProperty( "m_allTextures" );
  64. if( m_listTextures == null )
  65. {
  66. m_listTextures = new ReorderableList( m_so, m_allTextures, true, true, true, true );
  67. m_listTextures.elementHeight = 16;
  68. m_listTextures.drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) =>
  69. {
  70. m_allTextures.GetArrayElementAtIndex( index ).objectReferenceValue = (Texture2D)EditorGUI.ObjectField( rect, "Texture " + index, m_allTextures.GetArrayElementAtIndex( index ).objectReferenceValue, typeof( Texture2D ), false );
  71. };
  72. m_listTextures.drawHeaderCallback = ( Rect rect ) =>
  73. {
  74. m_previewSize = EditorGUI.IntSlider( rect, "Texture List", m_previewSize, 16, 64 );
  75. if( (float)m_previewSize != m_listTextures.elementHeight )
  76. m_listTextures.elementHeight = m_previewSize;
  77. };
  78. m_listTextures.onAddCallback = ( list ) =>
  79. {
  80. m_allTextures.InsertArrayElementAtIndex( m_allTextures.arraySize );
  81. m_allTextures.GetArrayElementAtIndex( m_allTextures.arraySize - 1 ).objectReferenceValue = null;
  82. };
  83. m_listTextures.onRemoveCallback = ( list ) =>
  84. {
  85. m_allTextures.GetArrayElementAtIndex( list.index ).objectReferenceValue = null;
  86. m_allTextures.DeleteArrayElementAtIndex( list.index );
  87. };
  88. }
  89. m_dragAndDropTool = new DragAndDropTool();
  90. m_dragAndDropTool.OnValidDropObjectEvt += OnValidObjectsDropped;
  91. }
  92. public void OnValidObjectsDropped( UnityEngine.Object[] droppedObjs )
  93. {
  94. for( int objIdx = 0; objIdx < droppedObjs.Length; objIdx++ )
  95. {
  96. Texture2D tex = droppedObjs[ objIdx ] as Texture2D;
  97. if( tex != null )
  98. {
  99. m_allTextures.InsertArrayElementAtIndex( m_allTextures.arraySize );
  100. m_allTextures.GetArrayElementAtIndex( m_allTextures.arraySize - 1 ).objectReferenceValue = tex;
  101. m_so.ApplyModifiedProperties();
  102. }
  103. else
  104. {
  105. DefaultAsset asset = droppedObjs[ objIdx ] as DefaultAsset;
  106. if( asset != null )
  107. {
  108. string path = AssetDatabase.GetAssetPath( asset );
  109. if( AssetDatabase.IsValidFolder( path ) )
  110. {
  111. string[] pathArr = { path };
  112. string[] texInDir = AssetDatabase.FindAssets( "t:Texture2D", pathArr );
  113. for( int texIdx = 0; texIdx < texInDir.Length; texIdx++ )
  114. {
  115. Texture2D internalTex = AssetDatabase.LoadAssetAtPath<Texture2D>( AssetDatabase.GUIDToAssetPath( texInDir[ texIdx ] ) );
  116. if( internalTex != null )
  117. {
  118. m_allTextures.InsertArrayElementAtIndex( m_allTextures.arraySize );
  119. m_allTextures.GetArrayElementAtIndex( m_allTextures.arraySize - 1 ).objectReferenceValue = internalTex;
  120. m_so.ApplyModifiedProperties();
  121. }
  122. }
  123. }
  124. }
  125. }
  126. }
  127. Instance.AllTextures.Sort( ( x, y ) => string.Compare( x.name, y.name ) );
  128. m_so.Update();
  129. }
  130. private void OnDestroy()
  131. {
  132. m_dragAndDropTool.Destroy();
  133. m_dragAndDropTool = null;
  134. }
  135. public override void OnInspectorGUI()
  136. {
  137. m_so.Update();
  138. if( m_pathButtonStyle == null )
  139. m_pathButtonStyle = "minibutton";
  140. EditorGUILayout.BeginHorizontal();
  141. var cache = EditorGUIUtility.labelWidth;
  142. EditorGUILayout.PrefixLabel( "Size" );
  143. EditorGUIUtility.labelWidth = 16;
  144. if( m_lockRatio.boolValue )
  145. {
  146. m_selectedSize.intValue = EditorGUILayout.Popup( "X", m_selectedSize.intValue, m_sizesStr );
  147. EditorGUI.BeginDisabledGroup( m_lockRatio.boolValue );
  148. EditorGUILayout.Popup( "Y", m_selectedSize.intValue, m_sizesStr );
  149. EditorGUI.EndDisabledGroup();
  150. }
  151. else
  152. {
  153. EditorGUILayout.PropertyField( m_sizeX, new GUIContent( "X" ) );
  154. EditorGUILayout.PropertyField( m_sizeY, new GUIContent( "Y" ) );
  155. }
  156. EditorGUIUtility.labelWidth = 100;
  157. m_lockRatio.boolValue = GUILayout.Toggle( m_lockRatio.boolValue, "L", "minibutton", GUILayout.Width( 18 ) );
  158. if( m_lockRatio.boolValue )
  159. {
  160. m_sizeX.intValue = m_sizes[ m_selectedSize.intValue ];
  161. m_sizeY.intValue = m_sizes[ m_selectedSize.intValue ];
  162. }
  163. EditorGUIUtility.labelWidth = cache;
  164. EditorGUILayout.EndHorizontal();
  165. EditorGUI.BeginChangeCheck();
  166. EditorGUILayout.PropertyField( m_tex3DMode, new GUIContent( "Texture 3D" ) );
  167. if( EditorGUI.EndChangeCheck() )
  168. {
  169. if( !m_filenameChanged.boolValue )
  170. {
  171. m_fileName.stringValue = m_tex3DMode.boolValue ? Texture3DFilename : ArrayFilename;
  172. }
  173. }
  174. EditorGUILayout.PropertyField( m_linearMode, new GUIContent( "Linear" ) );
  175. EditorGUILayout.PropertyField( m_mipMaps );
  176. EditorGUILayout.PropertyField( m_wrapMode );
  177. EditorGUILayout.PropertyField( m_filterMode );
  178. m_anisoLevel.intValue = EditorGUILayout.IntSlider( "Aniso Level", m_anisoLevel.intValue, 0, 16 );
  179. EditorGUILayout.PropertyField( m_selectedFormatEnum, new GUIContent( "Format" ) );
  180. if( m_selectedFormatEnum.intValue == (int)TextureFormat.DXT1Crunched )
  181. {
  182. m_selectedFormatEnum.intValue = (int)TextureFormat.DXT1;
  183. Debug.Log( "Texture Array does not support crunched DXT1 format. Changing to DXT1..." );
  184. }
  185. else if( m_selectedFormatEnum.intValue == (int)TextureFormat.DXT5Crunched )
  186. {
  187. m_selectedFormatEnum.intValue = (int)TextureFormat.DXT5;
  188. Debug.Log( "Texture Array does not support crunched DXT5 format. Changing to DXT5..." );
  189. }
  190. m_quality.intValue = EditorGUILayout.IntSlider( "Format Quality", m_quality.intValue, 0, 100 );
  191. EditorGUILayout.Separator();
  192. EditorGUILayout.LabelField( "Path and Name" );
  193. EditorGUILayout.BeginHorizontal();
  194. m_pathButtonContent.text = m_folderPath.stringValue;
  195. Vector2 buttonSize = m_pathButtonStyle.CalcSize( m_pathButtonContent );
  196. if( GUILayout.Button( m_pathButtonContent, m_pathButtonStyle, GUILayout.MaxWidth( Mathf.Min( Screen.width * 0.5f, buttonSize.x ) ) ) )
  197. {
  198. string folderpath = EditorUtility.OpenFolderPanel( "Save Texture Array to folder", "Assets/", "" );
  199. folderpath = FileUtil.GetProjectRelativePath( folderpath );
  200. if( string.IsNullOrEmpty( folderpath ) )
  201. m_folderPath.stringValue = "Assets/";
  202. else
  203. m_folderPath.stringValue = folderpath + "/";
  204. }
  205. EditorGUI.BeginChangeCheck();
  206. m_fileName.stringValue = EditorGUILayout.TextField( m_fileName.stringValue, GUILayout.ExpandWidth( true ) );
  207. if( EditorGUI.EndChangeCheck() )
  208. {
  209. m_filenameChanged.boolValue = m_fileName.stringValue == ArrayFilename ? false : true;
  210. }
  211. EditorGUILayout.LabelField( ".asset", GUILayout.MaxWidth( 40 ) );
  212. EditorGUILayout.EndHorizontal();
  213. EditorGUILayout.Separator();
  214. if( GUILayout.Button( "Clear" ) )
  215. {
  216. m_allTextures.ClearArray();
  217. }
  218. if( m_listTextures != null )
  219. m_listTextures.DoLayoutList();
  220. EditorGUILayout.Separator();
  221. m_dragAndDropTool.TestDragAndDrop( new Rect( 0, 0, Screen.width, Screen.height ) );
  222. m_so.ApplyModifiedProperties();
  223. }
  224. }
  225. public class ASETextureArrayCreator : EditorWindow
  226. {
  227. [MenuItem( "Window/Amplify Shader Editor/Texture Array Creator", false, 1001 )]
  228. static void ShowWindow()
  229. {
  230. ASETextureArrayCreator window = EditorWindow.GetWindow<ASETextureArrayCreator>();
  231. window.titleContent.text = "Texture Array";
  232. window.minSize = new Vector2( 302, 350 );
  233. window.Show();
  234. }
  235. private const string ClearButtonStr = "Clear";
  236. private const string TextureFilter = "t:Texture2D";
  237. private const string BuildArrayMessage = "Build Array";
  238. private const string BuildTexture3DMessage = "Build Texture 3D";
  239. private const string ArrayFilename = "NewTextureArray";
  240. private const string Texture3DFilename = "NewTexture3D";
  241. TextureArrayCreatorAssetEditor m_editor;
  242. [SerializeField]
  243. private TextureArrayCreatorAsset m_asset;
  244. [SerializeField]
  245. private TextureArrayCreatorAsset m_dummyAsset;
  246. private static List<TextureFormat> UncompressedFormats = new List<TextureFormat>()
  247. {
  248. TextureFormat.RGBAFloat,
  249. TextureFormat.RGBAHalf,
  250. TextureFormat.ARGB32,
  251. TextureFormat.RGBA32,
  252. TextureFormat.RGB24,
  253. TextureFormat.Alpha8
  254. };
  255. private GUIStyle m_contentStyle = null;
  256. private Vector2 m_scrollPos;
  257. private Texture m_lastSaved;
  258. private string m_message = string.Empty;
  259. private void OnEnable()
  260. {
  261. if( m_contentStyle == null )
  262. {
  263. m_contentStyle = new GUIStyle( GUIStyle.none );
  264. m_contentStyle.margin = new RectOffset( 6, 4, 5, 5 );
  265. }
  266. }
  267. private void OnDestroy()
  268. {
  269. DestroyImmediate( m_editor );
  270. if( m_dummyAsset != null && m_dummyAsset != m_asset )
  271. DestroyImmediate( m_dummyAsset );
  272. }
  273. void OnGUI()
  274. {
  275. TextureArrayCreatorAsset currentAsset = null;
  276. if( m_asset != null )
  277. {
  278. currentAsset = m_asset;
  279. }
  280. else
  281. {
  282. if( m_dummyAsset == null )
  283. {
  284. m_dummyAsset = ScriptableObject.CreateInstance<TextureArrayCreatorAsset>();
  285. m_dummyAsset.name = "Dummy";
  286. }
  287. currentAsset = m_dummyAsset;
  288. }
  289. m_scrollPos = EditorGUILayout.BeginScrollView( m_scrollPos, GUILayout.Height( position.height ) );
  290. float cachedWidth = EditorGUIUtility.labelWidth;
  291. EditorGUIUtility.labelWidth = 100;
  292. EditorGUILayout.BeginVertical( m_contentStyle );
  293. string buildButtonStr = currentAsset.Tex3DMode ? BuildTexture3DMessage : BuildArrayMessage;
  294. // build button
  295. EditorGUILayout.BeginHorizontal();
  296. EditorGUI.BeginDisabledGroup( currentAsset.AllTextures.Count <= 0 );
  297. if( GUILayout.Button( buildButtonStr, "prebutton", GUILayout.Height( 20 ) ) )
  298. {
  299. bool showWarning = false;
  300. for( int i = 0; i < currentAsset.AllTextures.Count; i++ )
  301. {
  302. if( currentAsset.AllTextures[ i ].width != currentAsset.SizeX || currentAsset.AllTextures[ i ].height != currentAsset.SizeY )
  303. {
  304. showWarning = true;
  305. }
  306. }
  307. if( !showWarning )
  308. {
  309. m_message = string.Empty;
  310. if( currentAsset.Tex3DMode )
  311. BuildTexture3D( currentAsset );
  312. else
  313. BuildArray( currentAsset );
  314. }
  315. else if( EditorUtility.DisplayDialog( "Warning!", "Some textures need to be resized to fit the selected size. Do you want to continue?", "Yes", "No" ) )
  316. {
  317. m_message = string.Empty;
  318. if( currentAsset.Tex3DMode )
  319. BuildTexture3D( currentAsset );
  320. else
  321. BuildArray( currentAsset );
  322. }
  323. }
  324. EditorGUI.EndDisabledGroup();
  325. EditorGUI.BeginDisabledGroup( m_lastSaved == null );
  326. GUIContent icon = EditorGUIUtility.IconContent( "icons/d_ViewToolZoom.png" );
  327. if( GUILayout.Button( icon, "prebutton", GUILayout.Width( 28 ), GUILayout.Height( 20 ) ) )
  328. {
  329. EditorGUIUtility.PingObject( m_lastSaved );
  330. }
  331. EditorGUI.EndDisabledGroup();
  332. EditorGUILayout.EndHorizontal();
  333. // message
  334. if( !string.IsNullOrEmpty( m_message ) )
  335. if( GUILayout.Button( "BUILD REPORT (click to hide):\n\n" + m_message, "helpbox" ) )
  336. m_message = string.Empty;
  337. // asset
  338. EditorGUILayout.BeginHorizontal();
  339. m_asset = EditorGUILayout.ObjectField( "Asset Preset", m_asset, typeof( TextureArrayCreatorAsset ), false ) as TextureArrayCreatorAsset;
  340. if( GUILayout.Button( m_asset != null ? "Save" : "Create", "minibutton", GUILayout.Width( 50 ) ) )
  341. {
  342. string defaultName = "ArrayPreset";
  343. if( m_asset != null )
  344. defaultName = m_asset.name;
  345. string path = EditorUtility.SaveFilePanelInProject( "Save as", defaultName, "asset", string.Empty );
  346. if( !string.IsNullOrEmpty( path ) )
  347. {
  348. TextureArrayCreatorAsset outfile = AssetDatabase.LoadMainAssetAtPath( path ) as TextureArrayCreatorAsset;
  349. if( outfile != null )
  350. {
  351. EditorUtility.CopySerialized( currentAsset, outfile );
  352. AssetDatabase.SaveAssets();
  353. Selection.activeObject = outfile;
  354. EditorGUIUtility.PingObject( outfile );
  355. }
  356. else
  357. {
  358. if( m_asset != null )
  359. {
  360. currentAsset = ScriptableObject.CreateInstance<TextureArrayCreatorAsset>();
  361. EditorUtility.CopySerialized( m_asset, currentAsset );
  362. }
  363. AssetDatabase.CreateAsset( currentAsset, path );
  364. Selection.activeObject = currentAsset;
  365. EditorGUIUtility.PingObject( currentAsset );
  366. m_asset = currentAsset;
  367. }
  368. }
  369. }
  370. EditorGUILayout.EndHorizontal();
  371. EditorGUILayout.Separator();
  372. if( Event.current.type == EventType.Layout )
  373. {
  374. if( m_editor == null )
  375. {
  376. m_editor = Editor.CreateEditor( currentAsset, typeof( TextureArrayCreatorAssetEditor ) ) as TextureArrayCreatorAssetEditor;
  377. }
  378. else
  379. {
  380. if( m_editor.Instance != currentAsset )
  381. {
  382. DestroyImmediate( m_editor );
  383. m_editor = Editor.CreateEditor( currentAsset, typeof( TextureArrayCreatorAssetEditor ) ) as TextureArrayCreatorAssetEditor;
  384. }
  385. }
  386. }
  387. if( m_editor != null )
  388. m_editor.OnInspectorGUI();
  389. GUILayout.Space( 20 );
  390. EditorGUILayout.EndVertical();
  391. EditorGUIUtility.labelWidth = cachedWidth;
  392. EditorGUILayout.EndScrollView();
  393. }
  394. private void CopyToArray( ref Texture2D from, ref Texture2DArray to, int arrayIndex, int mipLevel, bool compressed = true )
  395. {
  396. if( compressed )
  397. {
  398. Graphics.CopyTexture( from, 0, mipLevel, to, arrayIndex, mipLevel );
  399. }
  400. else
  401. {
  402. to.SetPixels( from.GetPixels(), arrayIndex, mipLevel );
  403. to.Apply();
  404. }
  405. }
  406. #if NEW_TEXTURE_3D_METHOD
  407. private void BuildTexture3D( TextureArrayCreatorAsset asset )
  408. {
  409. int sizeX = asset.SizeX;
  410. int sizeY = asset.SizeY;
  411. Texture3D texture3D = new Texture3D( sizeX, sizeY, asset.AllTextures.Count, asset.SelectedFormatEnum, asset.MipMaps );
  412. texture3D.wrapMode = asset.WrapMode;
  413. texture3D.filterMode = asset.FilterMode;
  414. texture3D.anisoLevel = asset.AnisoLevel;
  415. //texture3D.Apply( false );
  416. RenderTexture cache = RenderTexture.active;
  417. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default );
  418. rt.Create();
  419. List<Texture2D> textures = new List<Texture2D>( asset.AllTextures.Count );
  420. for( int i = 0; i < asset.AllTextures.Count; i++ )
  421. {
  422. // build report
  423. int widthChanges = asset.AllTextures[ i ].width < sizeX ? -1 : asset.AllTextures[ i ].width > sizeX ? 1 : 0;
  424. int heightChanges = asset.AllTextures[ i ].height < sizeY ? -1 : asset.AllTextures[ i ].height > sizeY ? 1 : 0;
  425. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  426. m_message += asset.AllTextures[ i ].name + " was upscaled\n";
  427. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  428. m_message += asset.AllTextures[ i ].name + " was downscaled\n";
  429. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  430. m_message += asset.AllTextures[ i ].name + " changed dimensions\n";
  431. // blit image to upscale or downscale the image to any size
  432. RenderTexture.active = rt;
  433. bool cachedsrgb = GL.sRGBWrite;
  434. GL.sRGBWrite = !asset.LinearMode;
  435. Graphics.Blit( asset.AllTextures[ i ], rt );
  436. GL.sRGBWrite = cachedsrgb;
  437. textures.Add( new Texture2D( sizeX, sizeY, TextureFormat.ARGB32, asset.MipMaps, asset.LinearMode ) );
  438. textures[ i ].ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, asset.MipMaps );
  439. RenderTexture.active = null;
  440. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( asset.SelectedFormatEnum ) ) < 0;
  441. if( isCompressed )
  442. {
  443. EditorUtility.CompressTexture( textures[ i ], asset.SelectedFormatEnum, asset.Quality );
  444. // t2d.Apply( false );
  445. }
  446. textures[ i ].Apply( false );
  447. }
  448. rt.Release();
  449. RenderTexture.active = cache;
  450. if( m_message.Length > 0 )
  451. m_message = m_message.Substring( 0, m_message.Length - 1 );
  452. int sizeZ = textures.Count;
  453. Color[] colors = new Color[ sizeX * sizeY * sizeZ ];
  454. int idx = 0;
  455. for( int z = 0; z < sizeZ; z++ )
  456. {
  457. for( int y = 0; y < sizeY; y++ )
  458. {
  459. for( int x = 0; x < sizeX; x++, idx++ )
  460. {
  461. colors[ idx ] = textures[ z ].GetPixel(x,y);
  462. }
  463. }
  464. }
  465. texture3D.SetPixels( colors );
  466. texture3D.Apply();
  467. string path = asset.FolderPath + asset.FileName + ".asset";
  468. Texture3D outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture3D;
  469. if( outfile != null )
  470. {
  471. EditorUtility.CopySerialized( texture3D, outfile );
  472. AssetDatabase.SaveAssets();
  473. EditorGUIUtility.PingObject( outfile );
  474. m_lastSaved = outfile;
  475. }
  476. else
  477. {
  478. AssetDatabase.CreateAsset( texture3D, path );
  479. EditorGUIUtility.PingObject( texture3D );
  480. m_lastSaved = texture3D;
  481. }
  482. }
  483. #else
  484. private void BuildTexture3D( TextureArrayCreatorAsset asset )
  485. {
  486. int sizeX = asset.SizeX;
  487. int sizeY = asset.SizeY;
  488. int numLevels = 1 + (int)Mathf.Floor( Mathf.Log( Mathf.Max( sizeX, sizeY ), 2 ) );
  489. int mipCount = asset.MipMaps ? numLevels : 1;
  490. Texture3D texture3D = new Texture3D( sizeX, sizeY, asset.AllTextures.Count, asset.SelectedFormatEnum, asset.MipMaps );
  491. texture3D.wrapMode = asset.WrapMode;
  492. texture3D.filterMode = asset.FilterMode;
  493. texture3D.anisoLevel = asset.AnisoLevel;
  494. texture3D.Apply( false );
  495. RenderTexture cache = RenderTexture.active;
  496. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default );
  497. rt.Create();
  498. List<List<Color>> mipColor = new List<List<Color>>();
  499. if( asset.MipMaps )
  500. {
  501. for( int i = 0; i < mipCount; i++ )
  502. {
  503. mipColor.Add( new List<Color>() );
  504. }
  505. }
  506. else
  507. {
  508. mipColor.Add( new List<Color>() );
  509. }
  510. for( int i = 0; i < asset.AllTextures.Count; i++ )
  511. {
  512. // build report
  513. int widthChanges = asset.AllTextures[ i ].width < sizeX ? -1 : asset.AllTextures[ i ].width > sizeX ? 1 : 0;
  514. int heightChanges = asset.AllTextures[ i ].height < sizeY ? -1 : asset.AllTextures[ i ].height > sizeY ? 1 : 0;
  515. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  516. m_message += asset.AllTextures[ i ].name + " was upscaled\n";
  517. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  518. m_message += asset.AllTextures[ i ].name + " was downscaled\n";
  519. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  520. m_message += asset.AllTextures[ i ].name + " changed dimensions\n";
  521. // blit image to upscale or downscale the image to any size
  522. RenderTexture.active = rt;
  523. bool cachedsrgb = GL.sRGBWrite;
  524. GL.sRGBWrite = !asset.LinearMode;
  525. Graphics.Blit( asset.AllTextures[ i ], rt );
  526. GL.sRGBWrite = cachedsrgb;
  527. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( asset.SelectedFormatEnum ) ) < 0;
  528. TextureFormat validReadPixelsFormat = isCompressed ? TextureFormat.RGBAFloat : asset.SelectedFormatEnum;
  529. Texture2D t2d = new Texture2D( sizeX, sizeY, validReadPixelsFormat, asset.MipMaps, asset.LinearMode );
  530. t2d.ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, asset.MipMaps );
  531. RenderTexture.active = null;
  532. if( isCompressed )
  533. {
  534. EditorUtility.CompressTexture( t2d, asset.SelectedFormatEnum, asset.Quality );
  535. // t2d.Apply( false );
  536. }
  537. t2d.Apply( false );
  538. if( asset.MipMaps )
  539. {
  540. for( int mip = 0; mip < mipCount; mip++ )
  541. {
  542. mipColor[ mip ].AddRange( t2d.GetPixels( mip ) );
  543. }
  544. }
  545. else
  546. {
  547. mipColor[ 0 ].AddRange( t2d.GetPixels( 0 ) );
  548. }
  549. }
  550. rt.Release();
  551. RenderTexture.active = cache;
  552. if( m_message.Length > 0 )
  553. m_message = m_message.Substring( 0, m_message.Length - 1 );
  554. for( int i = 0; i < mipCount; i++ )
  555. {
  556. texture3D.SetPixels( mipColor[ i ].ToArray(), i );
  557. }
  558. texture3D.Apply( false );
  559. string path = asset.FolderPath + asset.FileName + ".asset";
  560. Texture3D outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture3D;
  561. if( outfile != null )
  562. {
  563. EditorUtility.CopySerialized( texture3D, outfile );
  564. AssetDatabase.SaveAssets();
  565. EditorGUIUtility.PingObject( outfile );
  566. m_lastSaved = outfile;
  567. }
  568. else
  569. {
  570. AssetDatabase.CreateAsset( texture3D, path );
  571. EditorGUIUtility.PingObject( texture3D );
  572. m_lastSaved = texture3D;
  573. }
  574. }
  575. #endif
  576. private void BuildTexture3DAutoMips( TextureArrayCreatorAsset asset )
  577. {
  578. int sizeX = asset.SizeX;
  579. int sizeY = asset.SizeY;
  580. Texture3D texture3D = new Texture3D( sizeX, sizeY, asset.AllTextures.Count, asset.SelectedFormatEnum, asset.MipMaps );
  581. texture3D.wrapMode = asset.WrapMode;
  582. texture3D.filterMode = asset.FilterMode;
  583. texture3D.anisoLevel = asset.AnisoLevel;
  584. texture3D.Apply( false );
  585. RenderTexture cache = RenderTexture.active;
  586. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default );
  587. rt.Create();
  588. List<Color> texColors = new List<Color>();
  589. for( int i = 0; i < asset.AllTextures.Count; i++ )
  590. {
  591. // build report
  592. int widthChanges = asset.AllTextures[ i ].width < sizeX ? -1 : asset.AllTextures[ i ].width > sizeX ? 1 : 0;
  593. int heightChanges = asset.AllTextures[ i ].height < sizeY ? -1 : asset.AllTextures[ i ].height > sizeY ? 1 : 0;
  594. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  595. m_message += asset.AllTextures[ i ].name + " was upscaled\n";
  596. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  597. m_message += asset.AllTextures[ i ].name + " was downscaled\n";
  598. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  599. m_message += asset.AllTextures[ i ].name + " changed dimensions\n";
  600. // blit image to upscale or downscale the image to any size
  601. RenderTexture.active = rt;
  602. bool cachedsrgb = GL.sRGBWrite;
  603. GL.sRGBWrite = !asset.LinearMode;
  604. Graphics.Blit( asset.AllTextures[ i ], rt );
  605. GL.sRGBWrite = cachedsrgb;
  606. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( asset.SelectedFormatEnum ) ) < 0;
  607. TextureFormat validReadPixelsFormat = isCompressed ? TextureFormat.RGBAFloat : asset.SelectedFormatEnum;
  608. Texture2D t2d = new Texture2D( sizeX, sizeY, validReadPixelsFormat, asset.MipMaps, asset.LinearMode );
  609. t2d.ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, asset.MipMaps );
  610. RenderTexture.active = null;
  611. if( isCompressed )
  612. {
  613. EditorUtility.CompressTexture( t2d, asset.SelectedFormatEnum, asset.Quality );
  614. t2d.Apply( false );
  615. }
  616. texColors.AddRange( t2d.GetPixels() );
  617. }
  618. rt.Release();
  619. RenderTexture.active = cache;
  620. if( m_message.Length > 0 )
  621. m_message = m_message.Substring( 0, m_message.Length - 1 );
  622. texture3D.SetPixels( texColors.ToArray() );
  623. texture3D.Apply();
  624. string path = asset.FolderPath + asset.FileName + ".asset";
  625. Texture3D outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture3D;
  626. if( outfile != null )
  627. {
  628. EditorUtility.CopySerialized( texture3D, outfile );
  629. AssetDatabase.SaveAssets();
  630. EditorGUIUtility.PingObject( outfile );
  631. m_lastSaved = outfile;
  632. }
  633. else
  634. {
  635. AssetDatabase.CreateAsset( texture3D, path );
  636. EditorGUIUtility.PingObject( texture3D );
  637. m_lastSaved = texture3D;
  638. }
  639. }
  640. private void BuildArray( TextureArrayCreatorAsset asset )
  641. {
  642. int sizeX = asset.SizeX;
  643. int sizeY = asset.SizeY;
  644. Texture2DArray textureArray = new Texture2DArray( sizeX, sizeY, asset.AllTextures.Count, asset.SelectedFormatEnum, asset.MipMaps, asset.LinearMode );
  645. textureArray.wrapMode = asset.WrapMode;
  646. textureArray.filterMode = asset.FilterMode;
  647. textureArray.anisoLevel = asset.AnisoLevel;
  648. textureArray.Apply( false );
  649. RenderTexture cache = RenderTexture.active;
  650. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default );
  651. rt.Create();
  652. for( int i = 0; i < asset.AllTextures.Count; i++ )
  653. {
  654. // build report
  655. int widthChanges = asset.AllTextures[ i ].width < sizeX ? -1 : asset.AllTextures[ i ].width > sizeX ? 1 : 0;
  656. int heightChanges = asset.AllTextures[ i ].height < sizeY ? -1 : asset.AllTextures[ i ].height > sizeY ? 1 : 0;
  657. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  658. m_message += asset.AllTextures[ i ].name + " was upscaled\n";
  659. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  660. m_message += asset.AllTextures[ i ].name + " was downscaled\n";
  661. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  662. m_message += asset.AllTextures[ i ].name + " changed dimensions\n";
  663. // blit image to upscale or downscale the image to any size
  664. RenderTexture.active = rt;
  665. bool cachedsrgb = GL.sRGBWrite;
  666. GL.sRGBWrite = !asset.LinearMode;
  667. Graphics.Blit( asset.AllTextures[ i ], rt );
  668. GL.sRGBWrite = cachedsrgb;
  669. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( asset.SelectedFormatEnum ) ) < 0;
  670. TextureFormat validReadPixelsFormat = isCompressed ? TextureFormat.RGBAFloat : asset.SelectedFormatEnum;
  671. Texture2D t2d = new Texture2D( sizeX, sizeY, validReadPixelsFormat, asset.MipMaps, asset.LinearMode );
  672. t2d.ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, asset.MipMaps );
  673. RenderTexture.active = null;
  674. if( isCompressed )
  675. {
  676. EditorUtility.CompressTexture( t2d, asset.SelectedFormatEnum, asset.Quality );
  677. t2d.Apply( false );
  678. }
  679. if( asset.MipMaps )
  680. {
  681. int maxSize = Mathf.Max( sizeX, sizeY );
  682. int numLevels = 1 + (int)Mathf.Floor( Mathf.Log( maxSize, 2 ) );
  683. for( int mip = 0; mip < numLevels; mip++ )
  684. {
  685. CopyToArray( ref t2d, ref textureArray, i, mip, isCompressed );
  686. }
  687. }
  688. else
  689. {
  690. CopyToArray( ref t2d, ref textureArray, i, 0, isCompressed );
  691. }
  692. }
  693. rt.Release();
  694. RenderTexture.active = cache;
  695. if( m_message.Length > 0 )
  696. m_message = m_message.Substring( 0, m_message.Length - 1 );
  697. string path = asset.FolderPath + asset.FileName + ".asset";
  698. Texture2DArray outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture2DArray;
  699. if( outfile != null )
  700. {
  701. EditorUtility.CopySerialized( textureArray, outfile );
  702. AssetDatabase.SaveAssets();
  703. EditorGUIUtility.PingObject( outfile );
  704. m_lastSaved = outfile;
  705. }
  706. else
  707. {
  708. AssetDatabase.CreateAsset( textureArray, path );
  709. EditorGUIUtility.PingObject( textureArray );
  710. m_lastSaved = textureArray;
  711. }
  712. }
  713. }
  714. }