Pārlūkot izejas kodu

[unity] BlendModeMaterials Asset.

pharan 7 gadi atpakaļ
vecāks
revīzija
7b631b2961
21 mainītis faili ar 359 papildinājumiem un 24 dzēšanām
  1. 5 0
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDataAssetInspector.cs
  2. 54 10
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs
  3. 120 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/BlendModeMaterialsAsset.cs
  4. 18 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/BlendModeMaterialsAsset.cs.meta
  5. 8 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs
  6. 8 8
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs
  7. 9 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes.meta
  8. BIN
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Default BlendModeMaterials.asset
  9. 9 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Default BlendModeMaterials.asset.meta
  10. BIN
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAAdditive.mat
  11. 9 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAAdditive.mat.meta
  12. 0 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAMultiply.mat
  13. 0 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAMultiply.mat.meta
  14. 0 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAScreen.mat
  15. 0 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAScreen.mat.meta
  16. 106 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader
  17. 9 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader.meta
  18. 2 4
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader
  19. 0 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader.meta
  20. 2 2
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader
  21. 0 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader.meta

+ 5 - 0
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDataAssetInspector.cs

@@ -51,6 +51,7 @@ namespace Spine.Unity.Editor {
 		internal static bool showAttachments = false;
 		internal static bool showAttachments = false;
 
 
 		SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
 		SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
+		SerializedProperty blendModeMaterials;
 		#if SPINE_TK2D
 		#if SPINE_TK2D
 		SerializedProperty spriteCollection;
 		SerializedProperty spriteCollection;
 		#endif
 		#endif
@@ -100,6 +101,8 @@ namespace Spine.Unity.Editor {
 			duration = serializedObject.FindProperty("duration");
 			duration = serializedObject.FindProperty("duration");
 			defaultMix = serializedObject.FindProperty("defaultMix");
 			defaultMix = serializedObject.FindProperty("defaultMix");
 
 
+			blendModeMaterials = serializedObject.FindProperty("blendModeMaterials");
+
 			#if SPINE_SKELETON_MECANIM
 			#if SPINE_SKELETON_MECANIM
 			controller = serializedObject.FindProperty("controller");
 			controller = serializedObject.FindProperty("controller");
 			#endif
 			#endif
@@ -315,6 +318,8 @@ namespace Spine.Unity.Editor {
 
 
 			if (atlasAssets.arraySize == 0)
 			if (atlasAssets.arraySize == 0)
 				EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
 				EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
+
+			EditorGUILayout.PropertyField(blendModeMaterials);
 		}
 		}
 
 
 		void HandleAtlasAssetsNulls () {
 		void HandleAtlasAssetsNulls () {

+ 54 - 10
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs

@@ -179,7 +179,7 @@ namespace Spine.Unity.Editor {
 		static void Initialize () {
 		static void Initialize () {
 			Preferences.Load();
 			Preferences.Load();
 
 
-			DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
+			var rootDir = new DirectoryInfo(Application.dataPath);
 			FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
 			FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
 			editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
 			editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
 			editorGUIPath = editorPath + "/GUI";
 			editorGUIPath = editorPath + "/GUI";
@@ -194,15 +194,27 @@ namespace Spine.Unity.Editor {
 			EditorApplication.hierarchyWindowItemOnGUI += HierarchyHandler.HandleDragAndDrop;
 			EditorApplication.hierarchyWindowItemOnGUI += HierarchyHandler.HandleDragAndDrop;
 
 
 			// Hierarchy Icons
 			// Hierarchy Icons
-			#if UNITY_2017_2_OR_NEWER
+#if UNITY_2017_2_OR_NEWER
 			EditorApplication.playModeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
 			EditorApplication.playModeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
 			EditorApplication.playModeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
 			EditorApplication.playModeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
 			HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
 			HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
-			#else
+#else
 			EditorApplication.playmodeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
 			EditorApplication.playmodeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
 			EditorApplication.playmodeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
 			EditorApplication.playmodeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
 			HierarchyHandler.IconsOnPlaymodeStateChanged();
 			HierarchyHandler.IconsOnPlaymodeStateChanged();
-			#endif
+#endif
+
+			// Data Refresh Edit Mode.
+			// This prevents deserialized SkeletonData from persisting from play mode to edit mode.
+#if UNITY_2017_2_OR_NEWER
+			EditorApplication.playModeStateChanged -= DataReloadHandler.OnPlaymodeStateChanged;
+			EditorApplication.playModeStateChanged += DataReloadHandler.OnPlaymodeStateChanged;
+			DataReloadHandler.OnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
+#else
+			EditorApplication.playmodeStateChanged -= DataReloadHandler.OnPlaymodeStateChanged;
+			EditorApplication.playmodeStateChanged += DataReloadHandler.OnPlaymodeStateChanged;
+			DataReloadHandler.OnPlaymodeStateChanged();
+#endif
 
 
 			initialized = true;
 			initialized = true;
 		}
 		}
@@ -214,11 +226,11 @@ namespace Spine.Unity.Editor {
 		#endregion
 		#endregion
 
 
 		public static class Preferences {
 		public static class Preferences {
-			#if SPINE_TK2D
+#if SPINE_TK2D
 			const float DEFAULT_DEFAULT_SCALE = 1f;
 			const float DEFAULT_DEFAULT_SCALE = 1f;
-			#else
+#else
 			const float DEFAULT_DEFAULT_SCALE = 0.01f;
 			const float DEFAULT_DEFAULT_SCALE = 0.01f;
-			#endif
+#endif
 			const string DEFAULT_SCALE_KEY = "SPINE_DEFAULT_SCALE";
 			const string DEFAULT_SCALE_KEY = "SPINE_DEFAULT_SCALE";
 			public static float defaultScale = DEFAULT_DEFAULT_SCALE;
 			public static float defaultScale = DEFAULT_DEFAULT_SCALE;
 
 
@@ -268,11 +280,11 @@ namespace Spine.Unity.Editor {
 				showHierarchyIcons = EditorGUILayout.Toggle(new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes."), showHierarchyIcons);
 				showHierarchyIcons = EditorGUILayout.Toggle(new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes."), showHierarchyIcons);
 				if (EditorGUI.EndChangeCheck()) {
 				if (EditorGUI.EndChangeCheck()) {
 					EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons);
 					EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons);
-					#if UNITY_2017_2_OR_NEWER
+#if UNITY_2017_2_OR_NEWER
 					HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
 					HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
-					#else
+#else
 					HierarchyHandler.IconsOnPlaymodeStateChanged();
 					HierarchyHandler.IconsOnPlaymodeStateChanged();
-					#endif
+#endif
 				}
 				}
 
 
 				EditorGUILayout.Separator();
 				EditorGUILayout.Separator();
@@ -333,6 +345,38 @@ namespace Spine.Unity.Editor {
 			}
 			}
 		}
 		}
 
 
+		public static class DataReloadHandler {
+#if UNITY_2017_2_OR_NEWER
+			internal static void OnPlaymodeStateChanged (PlayModeStateChange stateChange) {
+#else
+			internal static void OnPlaymodeStateChanged () {
+#endif
+				ReloadAllActiveSkeletons();
+			}
+
+			static void ReloadAllActiveSkeletons () {
+				var skeletonDataAssetsToReload = new HashSet<SkeletonDataAsset>();
+
+				var activeSkeletonRenderers = GameObject.FindObjectsOfType<SkeletonRenderer>();
+				foreach (var sr in activeSkeletonRenderers) {
+					var skeletonDataAsset = sr.skeletonDataAsset;
+					if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset);
+				}
+
+				var activeSkeletonGraphics = GameObject.FindObjectsOfType<SkeletonGraphic>();
+				foreach (var sg in activeSkeletonGraphics) {
+					var skeletonDataAsset = sg.skeletonDataAsset;
+					if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset);
+				}
+
+				foreach (var sda in skeletonDataAssetsToReload)
+					sda.Clear();
+
+				foreach (var sr in activeSkeletonRenderers)	sr.Initialize(true);
+				foreach (var sg in activeSkeletonGraphics) sg.Initialize(true);
+			}
+		}
+
 		public static class AssetUtility {
 		public static class AssetUtility {
 			public const string SkeletonDataSuffix = "_SkeletonData";
 			public const string SkeletonDataSuffix = "_SkeletonData";
 			public const string AtlasSuffix = "_Atlas";
 			public const string AtlasSuffix = "_Atlas";

+ 120 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/BlendModeMaterialsAsset.cs

@@ -0,0 +1,120 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+using Spine;
+using Spine.Unity;
+
+namespace Spine.Unity {
+	[CreateAssetMenu(menuName = "Spine/Blend Mode Materials Asset", order = 200)]
+	public class BlendModeMaterialsAsset : ScriptableObject {
+		public Material multiplyMaterialTemplate;
+		public Material screenMaterialTemplate;
+		public Material additiveMaterialTemplate;
+
+		public bool applyAdditiveMaterial;
+
+		public void Apply (SkeletonData skeletonData) {
+			ApplyMaterials(skeletonData, multiplyMaterialTemplate, screenMaterialTemplate, additiveMaterialTemplate, applyAdditiveMaterial);
+		}
+
+		public static void ApplyMaterials (SkeletonData skeletonData, Material multiplyTemplate, Material screenTemplate, Material additiveTemplate, bool includeAdditiveSlots) {
+			if (skeletonData == null) throw new ArgumentNullException("skeletonData");
+
+			var atlasPageMaterialCache = new Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage>();
+			var attachmentBuffer = new List<Attachment>();
+			var slotsItems = skeletonData.Slots.Items;
+			for (int i = 0, slotCount = skeletonData.Slots.Count; i < slotCount; i++) {
+				var slot = slotsItems[i];
+				if (slot.blendMode == BlendMode.Normal) continue;
+				if (!includeAdditiveSlots && slot.blendMode == BlendMode.Additive) continue;
+
+				attachmentBuffer.Clear();
+				foreach (var skin in skeletonData.Skins)
+					skin.FindAttachmentsForSlot(i, attachmentBuffer);
+
+				Material templateMaterial = null;
+				switch (slot.blendMode) {
+					case BlendMode.Multiply:
+						templateMaterial = multiplyTemplate;
+						break;
+					case BlendMode.Screen:
+						templateMaterial = screenTemplate;
+						break;
+					case BlendMode.Additive:
+						templateMaterial = additiveTemplate;
+						break;
+				}
+				if (templateMaterial == null) continue;
+
+				foreach (var attachment in attachmentBuffer) {
+					var renderableAttachment = attachment as IHasRendererObject;
+					if (renderableAttachment != null) {
+						renderableAttachment.RendererObject = AtlasRegionCloneWithMaterial((AtlasRegion)renderableAttachment.RendererObject, templateMaterial, atlasPageMaterialCache);
+					}
+				}
+			}
+			//atlasPageMaterialCache.Clear();
+			//attachmentBuffer.Clear();
+		}
+
+		static AtlasRegion AtlasRegionCloneWithMaterial (AtlasRegion originalRegion, Material materialTemplate, Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage> cache) {
+			var newRegion = originalRegion.Clone();
+			newRegion.page = GetAtlasPageWithMaterial(originalRegion.page, materialTemplate, cache);
+			return newRegion;
+		}
+
+		static AtlasPage GetAtlasPageWithMaterial (AtlasPage originalPage, Material materialTemplate, Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage> cache) {
+			if (originalPage == null) throw new ArgumentNullException("originalPage");
+
+			AtlasPage newPage = null;
+			var key = new KeyValuePair<AtlasPage, Material>(originalPage, materialTemplate);
+			cache.TryGetValue(key, out newPage);
+
+			if (newPage == null) {
+				newPage = originalPage.Clone();
+				var originalMaterial = originalPage.rendererObject as Material;
+				newPage.rendererObject = new Material(materialTemplate) {
+					name = originalMaterial.name + " " + materialTemplate.name,
+					mainTexture = originalMaterial.mainTexture
+				};
+				cache.Add(key, newPage);
+			}
+
+			return newPage;
+		}
+	
+	}
+
+}

+ 18 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/BlendModeMaterialsAsset.cs.meta

@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: 12b0b98acbcda44468a7ae4e35000abe
+timeCreated: 1536404384
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences:
+  - multiplyMaterialTemplate: {fileID: 2100000, guid: 53bf0ab317d032d418cf1252d68f51df,
+      type: 2}
+  - screenMaterialTemplate: {fileID: 2100000, guid: 73f0f46d3177c614baf0fa48d646a9be,
+      type: 2}
+  - additiveMaterialTemplate: {fileID: 2100000, guid: 4deba332d47209e4780b3c5fcf0e3745,
+      type: 2}
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs

@@ -31,6 +31,7 @@
 using System;
 using System;
 using System.IO;
 using System.IO;
 using UnityEngine;
 using UnityEngine;
+
 using Spine;
 using Spine;
 
 
 namespace Spine.Unity {
 namespace Spine.Unity {
@@ -39,6 +40,8 @@ namespace Spine.Unity {
 	public class SkeletonDataAsset : ScriptableObject {
 	public class SkeletonDataAsset : ScriptableObject {
 		#region Inspector
 		#region Inspector
 		public AtlasAssetBase[] atlasAssets = new AtlasAssetBase[0];
 		public AtlasAssetBase[] atlasAssets = new AtlasAssetBase[0];
+		public BlendModeMaterialsAsset blendModeMaterials;
+
 		#if SPINE_TK2D
 		#if SPINE_TK2D
 		public tk2dSpriteCollectionData spriteCollection;
 		public tk2dSpriteCollectionData spriteCollection;
 		public float scale = 1f;
 		public float scale = 1f;
@@ -87,6 +90,7 @@ namespace Spine.Unity {
 		}
 		}
 		#endregion
 		#endregion
 
 
+		/// <summary>Clears the loaded SkeletonData and AnimationStateData. Use this to force a reload for the next time GetSkeletonData is called.</summary>
 		public void Clear () {
 		public void Clear () {
 			skeletonData = null;
 			skeletonData = null;
 			stateData = null;
 			stateData = null;
@@ -161,6 +165,9 @@ namespace Spine.Unity {
 
 
 			}
 			}
 
 
+			if (blendModeMaterials != null)
+				blendModeMaterials.Apply(loadedSkeletonData);
+
 			this.InitializeWithData(loadedSkeletonData);
 			this.InitializeWithData(loadedSkeletonData);
 
 
 			return skeletonData;
 			return skeletonData;
@@ -218,6 +225,7 @@ namespace Spine.Unity {
 			GetSkeletonData(false);
 			GetSkeletonData(false);
 			return stateData;
 			return stateData;
 		}
 		}
+
 	}
 	}
 
 
 }
 }

+ 8 - 8
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs

@@ -69,7 +69,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 
 
 		/// <summary>Sets the region (image) of a RegionAttachment</summary>
 		/// <summary>Sets the region (image) of a RegionAttachment</summary>
 		public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) {
 		public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) {
-			if (region == null) throw new System.ArgumentNullException("region");
+			if (region == null) throw new System.ArgumentNullException("region"); 
 
 
 			// (AtlasAttachmentLoader.cs)
 			// (AtlasAttachmentLoader.cs)
 			attachment.RendererObject = region;
 			attachment.RendererObject = region;
@@ -86,7 +86,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 
 
 		/// <summary>Sets the region (image) of a MeshAttachment</summary>
 		/// <summary>Sets the region (image) of a MeshAttachment</summary>
 		public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) {
 		public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) {
-			if (region == null) throw new System.ArgumentNullException("region");
+			if (region == null) throw new System.ArgumentNullException("region"); 
 
 
 			// (AtlasAttachmentLoader.cs)
 			// (AtlasAttachmentLoader.cs)
 			attachment.RendererObject = region;
 			attachment.RendererObject = region;
@@ -395,7 +395,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 		/// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments, but mapped to a new single texture using the same material.</summary>
 		/// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments, but mapped to a new single texture using the same material.</summary>
 		/// <param name="sourceAttachments">The list of attachments to be repacked.</param>
 		/// <param name="sourceAttachments">The list of attachments to be repacked.</param>
 		/// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param>
 		/// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param>
-		///
+		/// 
 		/// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param>
 		/// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param>
 		public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) {
 		public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) {
 			if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
 			if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
@@ -413,7 +413,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 			int newRegionIndex = 0;
 			int newRegionIndex = 0;
 			for (int i = 0, n = sourceAttachments.Count; i < n; i++) {
 			for (int i = 0, n = sourceAttachments.Count; i < n; i++) {
 				var originalAttachment = sourceAttachments[i];
 				var originalAttachment = sourceAttachments[i];
-
+				
 				if (IsRenderable(originalAttachment)) {
 				if (IsRenderable(originalAttachment)) {
 					var newAttachment = originalAttachment.GetClone(true);
 					var newAttachment = originalAttachment.GetClone(true);
 					var region = newAttachment.GetRegion();
 					var region = newAttachment.GetRegion();
@@ -524,7 +524,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 					newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, newAttachment);
 					newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, newAttachment);
 				} else {
 				} else {
 					newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true));
 					newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true));
-				}
+				}	
 			}
 			}
 
 
 			// Fill a new texture with the collected attachment textures.
 			// Fill a new texture with the collected attachment textures.
@@ -657,7 +657,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 		/// Returns a Rect of the AtlasRegion according to Spine texture coordinates. (x-right, y-down)</summary>
 		/// Returns a Rect of the AtlasRegion according to Spine texture coordinates. (x-right, y-down)</summary>
 		static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) {
 		static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) {
 			if (includeRotate && region.rotate)
 			if (includeRotate && region.rotate)
-				return new Rect(region.x, region.y, region.height, region.width);
+				return new Rect(region.x, region.y, region.height, region.width);				
 			else
 			else
 				return new Rect(region.x, region.y, region.width, region.height);
 				return new Rect(region.x, region.y, region.width, region.height);
 		}
 		}
@@ -684,7 +684,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 
 
 		/// <summary>
 		/// <summary>
 		/// Creates a new Spine AtlasRegion according to a Unity UV Rect (x-right, y-up, uv-normalized).</summary>
 		/// Creates a new Spine AtlasRegion according to a Unity UV Rect (x-right, y-up, uv-normalized).</summary>
-		static AtlasRegion UVRectToAtlasRegion (Rect uvRect, string name, AtlasPage page, float offsetX, float offsetY, bool rotate) {
+		static AtlasRegion UVRectToAtlasRegion (Rect uvRect, string name, AtlasPage page, float offsetX, float offsetY, bool rotate) {			
 			var tr  = UVRectToTextureRect(uvRect, page.width, page.height);
 			var tr  = UVRectToTextureRect(uvRect, page.width, page.height);
 			var rr = tr.SpineUnityFlipRect(page.height);
 			var rr = tr.SpineUnityFlipRect(page.height);
 
 
@@ -875,7 +875,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 		public static Attachment GetClone (this Attachment o, bool cloneMeshesAsLinked) {
 		public static Attachment GetClone (this Attachment o, bool cloneMeshesAsLinked) {
 			var regionAttachment = o as RegionAttachment;
 			var regionAttachment = o as RegionAttachment;
 			if (regionAttachment != null)
 			if (regionAttachment != null)
-				return regionAttachment.GetClone();
+				return regionAttachment.GetClone();			
 
 
 			var meshAttachment = o as MeshAttachment;
 			var meshAttachment = o as MeshAttachment;
 			if (meshAttachment != null)
 			if (meshAttachment != null)

+ 9 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: baf1d09e18b500d41a714f6207ddda2d
+folderAsset: yes
+timeCreated: 1536402197
+licenseType: Pro
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Default BlendModeMaterials.asset


+ 9 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Default BlendModeMaterials.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 22c0225612a65ee4fb15bad49f644762
+timeCreated: 1536404361
+licenseType: Pro
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAAdditive.mat


+ 9 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAAdditive.mat.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4deba332d47209e4780b3c5fcf0e3745
+timeCreated: 1496447909
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 0 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAMultiply.mat


+ 0 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat.meta → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAMultiply.mat.meta


+ 0 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAScreen.mat


+ 0 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat.meta → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/SkeletonPMAScreen.mat.meta


+ 106 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader

@@ -0,0 +1,106 @@
+// Spine/Skeleton PMA Screen
+// - single color multiply tint
+// - unlit
+// - Premultiplied alpha Multiply blending
+// - No depth, no backface culling, no fog.
+// - ShadowCaster pass
+
+Shader "Spine/Blend Modes/Skeleton PMA Additive" {
+	Properties {
+		_Color ("Tint Color", Color) = (1,1,1,1)
+		[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
+		[Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
+		_Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1
+	}
+
+	SubShader {
+		Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
+		LOD 100
+
+		Fog { Mode Off }
+		Cull Off
+		ZWrite Off
+		Blend One One
+		Lighting Off
+
+		Pass {
+			CGPROGRAM
+			#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
+			#pragma vertex vert
+			#pragma fragment frag
+			#include "UnityCG.cginc"
+			uniform sampler2D _MainTex;
+			uniform float4 _Color;
+
+			struct VertexInput {
+				float4 vertex : POSITION;
+				float2 uv : TEXCOORD0;
+				float4 vertexColor : COLOR;
+			};
+
+			struct VertexOutput {
+				float4 pos : SV_POSITION;
+				float2 uv : TEXCOORD0;
+				float4 vertexColor : COLOR;
+			};
+
+			VertexOutput vert (VertexInput v) {
+				VertexOutput o;
+				o.pos = UnityObjectToClipPos(v.vertex);
+				o.uv = v.uv;
+				o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+				return o;
+			}
+
+			float4 frag (VertexOutput i) : COLOR {
+				float4 texColor = tex2D(_MainTex, i.uv);
+
+				#if defined(_STRAIGHT_ALPHA_INPUT)
+				texColor.rgb *= texColor.a;
+				#endif
+
+				return (texColor * i.vertexColor);
+			}
+			ENDCG
+		}
+
+		Pass {
+			Name "Caster"
+			Tags { "LightMode"="ShadowCaster" }
+			Offset 1, 1
+
+			ZWrite On
+			ZTest LEqual
+
+			CGPROGRAM
+			#pragma vertex vert
+			#pragma fragment frag
+			#pragma multi_compile_shadowcaster
+			#pragma fragmentoption ARB_precision_hint_fastest
+			#include "UnityCG.cginc"
+			struct v2f { 
+				V2F_SHADOW_CASTER;
+				float2 uv : TEXCOORD1;
+			};
+
+			uniform float4 _MainTex_ST;
+
+			v2f vert (appdata_base v) {
+				v2f o;
+				TRANSFER_SHADOW_CASTER(o)
+				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
+				return o;
+			}
+
+			uniform sampler2D _MainTex;
+			uniform fixed _Cutoff;
+
+			float4 frag (v2f i) : COLOR {
+				fixed4 texcol = tex2D(_MainTex, i.uv);
+				clip(texcol.a - _Cutoff);
+				SHADOW_CASTER_FRAGMENT(i)
+			}
+			ENDCG
+		}
+	}
+}

+ 9 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 53efa1d97f5d9f74285d4330cda14e36
+timeCreated: 1496446742
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 2 - 4
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader

@@ -1,13 +1,11 @@
-// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
-
-// Spine/Skeleton PMA Multiply
+// Spine/Skeleton PMA Multiply
 // - single color multiply tint
 // - single color multiply tint
 // - unlit
 // - unlit
 // - Premultiplied alpha Multiply blending
 // - Premultiplied alpha Multiply blending
 // - No depth, no backface culling, no fog.
 // - No depth, no backface culling, no fog.
 // - ShadowCaster pass
 // - ShadowCaster pass
 
 
-Shader "Spine/Skeleton PMA Multiply" {
+Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
 	Properties {
 	Properties {
 		_Color ("Tint Color", Color) = (1,1,1,1)
 		_Color ("Tint Color", Color) = (1,1,1,1)
 		[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
 		[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}

+ 0 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader.meta → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader.meta


+ 2 - 2
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader

@@ -1,11 +1,11 @@
-// Spine/Skeleton PMA Multiply
+// Spine/Skeleton PMA Screen
 // - single color multiply tint
 // - single color multiply tint
 // - unlit
 // - unlit
 // - Premultiplied alpha Multiply blending
 // - Premultiplied alpha Multiply blending
 // - No depth, no backface culling, no fog.
 // - No depth, no backface culling, no fog.
 // - ShadowCaster pass
 // - ShadowCaster pass
 
 
-Shader "Spine/Skeleton PMA Screen" {
+Shader "Spine/Blend Modes/Skeleton PMA Screen" {
 	Properties {
 	Properties {
 		_Color ("Tint Color", Color) = (1,1,1,1)
 		_Color ("Tint Color", Color) = (1,1,1,1)
 		[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
 		[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}

+ 0 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader.meta → spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader.meta