mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-19 08:16:41 +08:00
[unity] BlendModeMaterials Asset.
This commit is contained in:
parent
514450f3a5
commit
7b631b2961
@ -51,6 +51,7 @@ namespace Spine.Unity.Editor {
|
||||
internal static bool showAttachments = false;
|
||||
|
||||
SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
|
||||
SerializedProperty blendModeMaterials;
|
||||
#if SPINE_TK2D
|
||||
SerializedProperty spriteCollection;
|
||||
#endif
|
||||
@ -100,6 +101,8 @@ namespace Spine.Unity.Editor {
|
||||
duration = serializedObject.FindProperty("duration");
|
||||
defaultMix = serializedObject.FindProperty("defaultMix");
|
||||
|
||||
blendModeMaterials = serializedObject.FindProperty("blendModeMaterials");
|
||||
|
||||
#if SPINE_SKELETON_MECANIM
|
||||
controller = serializedObject.FindProperty("controller");
|
||||
#endif
|
||||
@ -315,6 +318,8 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
if (atlasAssets.arraySize == 0)
|
||||
EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
|
||||
|
||||
EditorGUILayout.PropertyField(blendModeMaterials);
|
||||
}
|
||||
|
||||
void HandleAtlasAssetsNulls () {
|
||||
|
||||
@ -179,7 +179,7 @@ namespace Spine.Unity.Editor {
|
||||
static void Initialize () {
|
||||
Preferences.Load();
|
||||
|
||||
DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
|
||||
var rootDir = new DirectoryInfo(Application.dataPath);
|
||||
FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
|
||||
editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
|
||||
editorGUIPath = editorPath + "/GUI";
|
||||
@ -194,15 +194,27 @@ namespace Spine.Unity.Editor {
|
||||
EditorApplication.hierarchyWindowItemOnGUI += HierarchyHandler.HandleDragAndDrop;
|
||||
|
||||
// Hierarchy Icons
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
EditorApplication.playModeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
|
||||
EditorApplication.playModeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
|
||||
HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
|
||||
#else
|
||||
#else
|
||||
EditorApplication.playmodeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
|
||||
EditorApplication.playmodeStateChanged += 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;
|
||||
}
|
||||
@ -214,11 +226,11 @@ namespace Spine.Unity.Editor {
|
||||
#endregion
|
||||
|
||||
public static class Preferences {
|
||||
#if SPINE_TK2D
|
||||
#if SPINE_TK2D
|
||||
const float DEFAULT_DEFAULT_SCALE = 1f;
|
||||
#else
|
||||
#else
|
||||
const float DEFAULT_DEFAULT_SCALE = 0.01f;
|
||||
#endif
|
||||
#endif
|
||||
const string DEFAULT_SCALE_KEY = "SPINE_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);
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons);
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
|
||||
#else
|
||||
#else
|
||||
HierarchyHandler.IconsOnPlaymodeStateChanged();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
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 const string SkeletonDataSuffix = "_SkeletonData";
|
||||
public const string AtlasSuffix = "_Atlas";
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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:
|
||||
@ -31,6 +31,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
using Spine;
|
||||
|
||||
namespace Spine.Unity {
|
||||
@ -39,6 +40,8 @@ namespace Spine.Unity {
|
||||
public class SkeletonDataAsset : ScriptableObject {
|
||||
#region Inspector
|
||||
public AtlasAssetBase[] atlasAssets = new AtlasAssetBase[0];
|
||||
public BlendModeMaterialsAsset blendModeMaterials;
|
||||
|
||||
#if SPINE_TK2D
|
||||
public tk2dSpriteCollectionData spriteCollection;
|
||||
public float scale = 1f;
|
||||
@ -87,6 +90,7 @@ namespace Spine.Unity {
|
||||
}
|
||||
#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 () {
|
||||
skeletonData = null;
|
||||
stateData = null;
|
||||
@ -161,6 +165,9 @@ namespace Spine.Unity {
|
||||
|
||||
}
|
||||
|
||||
if (blendModeMaterials != null)
|
||||
blendModeMaterials.Apply(loadedSkeletonData);
|
||||
|
||||
this.InitializeWithData(loadedSkeletonData);
|
||||
|
||||
return skeletonData;
|
||||
@ -218,6 +225,7 @@ namespace Spine.Unity {
|
||||
GetSkeletonData(false);
|
||||
return stateData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
|
||||
|
||||
/// <summary>Sets the region (image) of a RegionAttachment</summary>
|
||||
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)
|
||||
attachment.RendererObject = region;
|
||||
@ -86,7 +86,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
|
||||
|
||||
/// <summary>Sets the region (image) of a MeshAttachment</summary>
|
||||
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)
|
||||
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>
|
||||
/// <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="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) {
|
||||
if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
|
||||
@ -413,7 +413,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
|
||||
int newRegionIndex = 0;
|
||||
for (int i = 0, n = sourceAttachments.Count; i < n; i++) {
|
||||
var originalAttachment = sourceAttachments[i];
|
||||
|
||||
|
||||
if (IsRenderable(originalAttachment)) {
|
||||
var newAttachment = originalAttachment.GetClone(true);
|
||||
var region = newAttachment.GetRegion();
|
||||
@ -524,7 +524,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
|
||||
newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, newAttachment);
|
||||
} else {
|
||||
newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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>
|
||||
static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) {
|
||||
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
|
||||
return new Rect(region.x, region.y, region.width, region.height);
|
||||
}
|
||||
@ -684,7 +684,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
|
||||
|
||||
/// <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 rr = tr.SpineUnityFlipRect(page.height);
|
||||
|
||||
@ -875,7 +875,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
|
||||
public static Attachment GetClone (this Attachment o, bool cloneMeshesAsLinked) {
|
||||
var regionAttachment = o as RegionAttachment;
|
||||
if (regionAttachment != null)
|
||||
return regionAttachment.GetClone();
|
||||
return regionAttachment.GetClone();
|
||||
|
||||
var meshAttachment = o as MeshAttachment;
|
||||
if (meshAttachment != null)
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: baf1d09e18b500d41a714f6207ddda2d
|
||||
folderAsset: yes
|
||||
timeCreated: 1536402197
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22c0225612a65ee4fb15bad49f644762
|
||||
timeCreated: 1536404361
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4deba332d47209e4780b3c5fcf0e3745
|
||||
timeCreated: 1496447909
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53efa1d97f5d9f74285d4330cda14e36
|
||||
timeCreated: 1496446742
|
||||
licenseType: Free
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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
|
||||
// - unlit
|
||||
// - Premultiplied alpha Multiply blending
|
||||
// - No depth, no backface culling, no fog.
|
||||
// - ShadowCaster pass
|
||||
|
||||
Shader "Spine/Skeleton PMA Multiply" {
|
||||
Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
|
||||
Properties {
|
||||
_Color ("Tint Color", Color) = (1,1,1,1)
|
||||
[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
|
||||
@ -1,11 +1,11 @@
|
||||
// Spine/Skeleton PMA Multiply
|
||||
// Spine/Skeleton PMA Screen
|
||||
// - single color multiply tint
|
||||
// - unlit
|
||||
// - Premultiplied alpha Multiply blending
|
||||
// - No depth, no backface culling, no fog.
|
||||
// - ShadowCaster pass
|
||||
|
||||
Shader "Spine/Skeleton PMA Screen" {
|
||||
Shader "Spine/Blend Modes/Skeleton PMA Screen" {
|
||||
Properties {
|
||||
_Color ("Tint Color", Color) = (1,1,1,1)
|
||||
[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
|
||||
Loading…
x
Reference in New Issue
Block a user