diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs index 43d368d05..72ba273ce 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs @@ -35,12 +35,26 @@ using UnityEditor; using SpineInspectorUtility = Spine.Unity.Editor.SpineInspectorUtility; public class SpineSpriteShaderGUI : ShaderGUI { - static readonly string kShaderVertexLit = "Spine/Sprite/Vertex Lit"; - static readonly string kShaderPixelLit = "Spine/Sprite/Pixel Lit"; - static readonly string kShaderUnlit = "Spine/Sprite/Unlit"; - static readonly int kSolidQueue = 2000; - static readonly int kAlphaTestQueue = 2450; - static readonly int kTransparentQueue = 3000; + + #region Constants + const string ShaderVertexLit = "Spine/Sprite/Vertex Lit"; + const string ShaderPixelLit = "Spine/Sprite/Pixel Lit"; + const string ShaderUnlit = "Spine/Sprite/Unlit"; + + const int SolidQueue = 2000; + const int AlphaTestQueue = 2450; + const int TransparentQueue = 3000; + + const string PremultipledAlpha = "_ALPHAPREMULTIPLY_ON"; + const string Multiply = "_MULTIPLYBLEND"; + const string Multiply2x = "_MULTIPLYBLEND_X2"; + const string Additive = "_ADDITIVEBLEND"; + const string SoftAdditive = "_ADDITIVEBLEND_SOFT"; + + const string _FIXED_NORMALS = "_FIXED_NORMALS"; + const string _FIXED_NORMALS_BACK_RENDERING = "_FIXED_NORMALS_BACK_RENDERING"; + + const string _SPHERICAL_HARMONICS = "_SPHERICAL_HARMONICS"; enum eBlendMode { PreMultipliedAlpha, @@ -59,10 +73,10 @@ public class SpineSpriteShaderGUI : ShaderGUI { Back = 2, Front = 1, } + #endregion MaterialProperty _mainTexture = null; MaterialProperty _color = null; - MaterialProperty _blendMode = null; MaterialProperty _emissionMap = null; MaterialProperty _emissionColor = null; @@ -116,16 +130,21 @@ public class SpineSpriteShaderGUI : ShaderGUI { public override void AssignNewShaderToMaterial (Material material, Shader oldShader, Shader newShader) { base.AssignNewShaderToMaterial(material, oldShader, newShader); + + if (!(oldShader == Shader.Find(ShaderPixelLit) || oldShader == Shader.Find(ShaderVertexLit) || oldShader == Shader.Find(ShaderUnlit))) + SetDefaultSpriteKeywords(material, newShader); + SetMaterialKeywords(material); SetLightModeFromShader(material); } + + #endregion #region Virtual Interface protected virtual void FindProperties (MaterialProperty[] props) { _mainTexture = FindProperty("_MainTex", props); _color = FindProperty("_Color", props); - _blendMode = FindProperty("_BlendMode", props); _emissionMap = FindProperty("_EmissionMap", props, false); _emissionColor = FindProperty("_EmissionColor", props, false); @@ -184,6 +203,16 @@ public class SpineSpriteShaderGUI : ShaderGUI { EditorGUI.BeginChangeCheck(); bool fog = EditorGUILayout.Toggle("Use fog", material.IsKeywordEnabled("_FOG")); if (EditorGUI.EndChangeCheck()) SetKeyword(material, "_FOG", fog); + + EditorGUI.BeginChangeCheck(); + bool enabled = EditorGUILayout.Toggle( + new GUIContent( + "Use Spherical Harmonics", + "Enable to use spherical harmonics to calculate ambient light / light probes. In vertex-lit mode this will be approximated from scenes ambient trilight settings."), + material.IsKeywordEnabled(_SPHERICAL_HARMONICS) + ); + if (EditorGUI.EndChangeCheck()) + SetKeyword(material, _SPHERICAL_HARMONICS, enabled); } using (new SpineInspectorUtility.BoxScope()) @@ -220,13 +249,13 @@ public class SpineSpriteShaderGUI : ShaderGUI { EditorGUI.BeginChangeCheck(); if (showAdvanced) { backRendering = EditorGUILayout.Toggle(new GUIContent("Fixed Normal Back Rendering", "Tick only if you are going to rotate the sprite to face away from the camera, the fixed normal will be flipped to compensate."), - material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING")); + material.IsKeywordEnabled(_FIXED_NORMALS_BACK_RENDERING)); } else { - backRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING"); + backRendering = material.IsKeywordEnabled(_FIXED_NORMALS_BACK_RENDERING); } if (EditorGUI.EndChangeCheck()) { - SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", backRendering); - SetKeyword(material, "_FIXED_NORMALS", !backRendering); + SetKeyword(material, _FIXED_NORMALS_BACK_RENDERING, backRendering); + SetKeyword(material, _FIXED_NORMALS, !backRendering); } } } @@ -259,8 +288,7 @@ public class SpineSpriteShaderGUI : ShaderGUI { } } if (EditorGUI.EndChangeCheck()) { - foreach (var obj in _blendMode.targets) - MaterialChanged((Material)obj); + MaterialChanged(material); } } @@ -293,13 +321,13 @@ public class SpineSpriteShaderGUI : ShaderGUI { bool UseMeshNormalsCheckbox (Material material) { EditorGUI.BeginChangeCheck(); - bool fixedNormals = material.IsKeywordEnabled("_FIXED_NORMALS"); - bool fixedNormalsBackRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING"); + bool fixedNormals = material.IsKeywordEnabled(_FIXED_NORMALS); + bool fixedNormalsBackRendering = material.IsKeywordEnabled(_FIXED_NORMALS_BACK_RENDERING); bool meshNormals = EditorGUILayout.Toggle(new GUIContent("Use Mesh Normals", "If this is unticked, a Fixed Normal value will be used instead of the vertex normals on the mesh. Using a fixed normal is better for performance and can result in better looking lighting effects on 2d objects."), !fixedNormals && !fixedNormalsBackRendering); if (EditorGUI.EndChangeCheck()) { - SetKeyword(material, "_FIXED_NORMALS", meshNormals ? false : fixedNormalsBackRendering ? false : true); - SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", meshNormals ? false : fixedNormalsBackRendering); + SetKeyword(material, _FIXED_NORMALS, meshNormals ? false : fixedNormalsBackRendering ? false : true); + SetKeyword(material, _FIXED_NORMALS_BACK_RENDERING, meshNormals ? false : fixedNormalsBackRendering); } return meshNormals; } @@ -331,20 +359,37 @@ public class SpineSpriteShaderGUI : ShaderGUI { } #endregion + static void SetDefaultSpriteKeywords (Material material, Shader shader) { + SetKeyword(material, "_EMISSION", false); // Disabled. standard shader sets this on by default. + SetKeyword(material, PremultipledAlpha, true); // PMA by default + SetKeyword(material, _FIXED_NORMALS, true); // Fixed normals by default, best for Spine. + SetKeyword(material, _SPHERICAL_HARMONICS, true); + } + void SetLightModeFromShader (Material material) { - if (material.shader.name == kShaderPixelLit) + if (material.shader.name == ShaderPixelLit) _lightMode = eLightMode.PixelLit; - else if (material.shader.name == kShaderUnlit) + else if (material.shader.name == ShaderUnlit) _lightMode = eLightMode.Unlit; else _lightMode = eLightMode.VertexLit; } - static void SetMaterialKeywords (Material material) { - eBlendMode blendMode = (eBlendMode)material.GetFloat("_BlendMode"); + static void SetRenderQueue (Material material, string queue) { + bool meshNormal = true; + if (material.HasProperty("_FixedNormal")) { + bool fixedNormals = material.IsKeywordEnabled(_FIXED_NORMALS); + bool fixedNormalsBackRendering = material.IsKeywordEnabled(_FIXED_NORMALS_BACK_RENDERING); + meshNormal = !fixedNormals && !fixedNormalsBackRendering; + } + + material.SetOverrideTag("RenderType", meshNormal ? queue : "Sprite"); + } + + static void SetMaterialKeywords (Material material) { bool normalMap = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null; - SetKeyword (material, "_NORMALMAP", normalMap); + SetKeyword(material, "_NORMALMAP", normalMap); bool zWrite = material.GetFloat("_ZWrite") > 0.0f; bool clipAlpha = zWrite && material.GetFloat("_Cutoff") > 0.0f; @@ -356,11 +401,41 @@ public class SpineSpriteShaderGUI : ShaderGUI { bool blendTexture = material.HasProperty("_BlendTex") && material.GetTexture("_BlendTex") != null; SetKeyword(material, "_TEXTURE_BLEND", blendTexture); - SetKeyword(material, "_ALPHAPREMULTIPLY_ON", blendMode == eBlendMode.PreMultipliedAlpha); - SetKeyword(material, "_MULTIPLYBLEND", blendMode == eBlendMode.Multiply); - SetKeyword(material, "_MULTIPLYBLEND_X2", blendMode == eBlendMode.Multiplyx2); - SetKeyword(material, "_ADDITIVEBLEND", blendMode == eBlendMode.Additive); - SetKeyword(material, "_ADDITIVEBLEND_SOFT", blendMode == eBlendMode.SoftAdditive); + eBlendMode blendMode = GetMaterialBlendMode(material); + SetBlendMode(material, blendMode); + } + + static eBlendMode GetMaterialBlendMode (Material material) { + if (material.IsKeywordEnabled(PremultipledAlpha)) + return eBlendMode.PreMultipliedAlpha; + if (material.IsKeywordEnabled(Multiply)) + return eBlendMode.Multiply; + if (material.IsKeywordEnabled(Multiply2x)) + return eBlendMode.Multiplyx2; + if (material.IsKeywordEnabled(Additive)) + return eBlendMode.Additive; + if (material.IsKeywordEnabled(SoftAdditive)) + return eBlendMode.SoftAdditive; + + return eBlendMode.StandardAlpha; + } + + void BlendModePopup () { + var material = _materialEditor.target as Material; + eBlendMode blendMode = GetMaterialBlendMode(material); + EditorGUI.BeginChangeCheck(); + blendMode = (eBlendMode)EditorGUILayout.Popup("Blend Mode", (int)blendMode, Enum.GetNames(typeof(eBlendMode))); + + if (EditorGUI.EndChangeCheck()) + SetBlendMode(material, blendMode); + } + + static void SetBlendMode (Material material, eBlendMode blendMode) { + SetKeyword(material, PremultipledAlpha, blendMode == eBlendMode.PreMultipliedAlpha); + SetKeyword(material, Multiply, blendMode == eBlendMode.Multiply); + SetKeyword(material, Multiply2x, blendMode == eBlendMode.Multiplyx2); + SetKeyword(material, Additive, blendMode == eBlendMode.Additive); + SetKeyword(material, SoftAdditive, blendMode == eBlendMode.SoftAdditive); int renderQueue; @@ -369,50 +444,51 @@ public class SpineSpriteShaderGUI : ShaderGUI { { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetOverrideTag("RenderType", "Opaque"); - renderQueue = kSolidQueue; + SetRenderQueue(material, "Opaque"); + renderQueue = SolidQueue; } break; case eBlendMode.Additive: { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetOverrideTag("RenderType", "Transparent"); - renderQueue = kTransparentQueue; + SetRenderQueue(material, "Transparent"); + renderQueue = TransparentQueue; } break; case eBlendMode.SoftAdditive: { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcColor); - material.SetOverrideTag("RenderType", "Transparent"); - renderQueue = kTransparentQueue; + SetRenderQueue(material, "Transparent"); + renderQueue = TransparentQueue; } break; case eBlendMode.Multiply: { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor); - material.SetOverrideTag("RenderType", "Transparent"); - renderQueue = kTransparentQueue; + SetRenderQueue(material, "Transparent"); + renderQueue = TransparentQueue; } break; case eBlendMode.Multiplyx2: { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor); - material.SetOverrideTag("RenderType", "Transparent"); - renderQueue = kTransparentQueue; + SetRenderQueue(material, "Transparent"); + renderQueue = TransparentQueue; } break; case eBlendMode.PreMultipliedAlpha: case eBlendMode.StandardAlpha: default: { + bool zWrite = material.GetFloat("_ZWrite") > 0.0f; material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetOverrideTag("RenderType", zWrite ? "TransparentCutout" : "Transparent"); - renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue; + SetRenderQueue(material, zWrite ? "TransparentCutout" : "Transparent"); + renderQueue = zWrite ? AlphaTestQueue : TransparentQueue; } break; } @@ -459,16 +535,16 @@ public class SpineSpriteShaderGUI : ShaderGUI { switch (_lightMode) { case eLightMode.VertexLit: - if (material.shader.name != kShaderVertexLit) - _materialEditor.SetShader(Shader.Find(kShaderVertexLit), false); + if (material.shader.name != ShaderVertexLit) + _materialEditor.SetShader(Shader.Find(ShaderVertexLit), false); break; case eLightMode.PixelLit: - if (material.shader.name != kShaderPixelLit) - _materialEditor.SetShader(Shader.Find(kShaderPixelLit), false); + if (material.shader.name != ShaderPixelLit) + _materialEditor.SetShader(Shader.Find(ShaderPixelLit), false); break; case eLightMode.Unlit: - if (material.shader.name != kShaderUnlit) - _materialEditor.SetShader(Shader.Find(kShaderUnlit), false); + if (material.shader.name != ShaderUnlit) + _materialEditor.SetShader(Shader.Find(ShaderUnlit), false); break; } @@ -476,13 +552,5 @@ public class SpineSpriteShaderGUI : ShaderGUI { } } - void BlendModePopup () { - eBlendMode mode = (eBlendMode)_blendMode.floatValue; - EditorGUI.BeginChangeCheck(); - mode = (eBlendMode)EditorGUILayout.Popup("Blend Mode", (int)mode, Enum.GetNames(typeof(eBlendMode))); - if (EditorGUI.EndChangeCheck()) { - _materialEditor.RegisterPropertyChangeUndo("Blend Mode"); - _blendMode.floatValue = (float)mode; - } - } + } diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader new file mode 100644 index 000000000..8f77a1fee --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader @@ -0,0 +1,446 @@ +Shader "Hidden/Internal-SpriteDepthNormalsTexture" { + +// Use this shader to render a DepthNormals texture for a camera with correct sprite normals (using camera.RenderWithShader) + +Properties { + _MainTex ("", 2D) = "white" {} + _Cutoff ("", Float) = 0.5 + _Color ("", Color) = (1,1,1,1) +} + +SubShader { + Tags { "RenderType"="Sprite" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +uniform float4 _FixedNormal; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.nz.xyz = _FixedNormal.xyz; +#if UNITY_REVERSED_Z + o.nz.z = -o.nz.z; +#endif + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + } + +SubShader { + Tags { "RenderType"="Opaque" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TransparentCutout" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +uniform float4 _MainTex_ST; +v2f vert( appdata_base v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +uniform fixed4 _Color; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a*_Color.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeBark" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertBark(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag( v2f i ) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeLeaf" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "Lighting.cginc" +#include "UnityBuiltin3xTreeLibrary.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert( appdata_full v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TreeVertLeaf(v); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag( v2f i ) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeOpaque" "DisableBatching"="True" } + Pass { +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float4 nz : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + UNITY_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +fixed4 frag(v2f i) : SV_Target { + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="TreeTransparentCutout" "DisableBatching"="True" } + Pass { + Cull Back +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + half alpha = tex2D(_MainTex, i.uv).a; + + clip (alpha - _Cutoff); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + Pass { + Cull Front +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +struct appdata { + float4 vertex : POSITION; + float3 normal : NORMAL; + fixed4 color : COLOR; + float4 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; +v2f vert( appdata v ) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainAnimateTree(v.vertex, v.color.w); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = -COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } + +} + +SubShader { + Tags { "RenderType"="TreeBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; +v2f vert (appdata_tree_billboard v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y); + o.pos = UnityObjectToClipPos(v.vertex); + o.uv.x = v.texcoord.x; + o.uv.y = v.texcoord.y > 0; + o.nz.xyz = float3(0,0,1); + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + clip( texcol.a - 0.001 ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="GrassBillboard" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" + +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassBillboardVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +SubShader { + Tags { "RenderType"="Grass" } + Pass { + Cull Off +CGPROGRAM +#pragma target 3.0 +#pragma vertex vert +#pragma fragment frag +#include "UnityCG.cginc" +#include "TerrainEngine.cginc" +struct v2f { + float4 pos : SV_POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + float4 nz : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +v2f vert (appdata_full v) { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + WavingGrassVert (v); + o.color = v.color; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + o.nz.xyz = COMPUTE_VIEW_NORMAL; + o.nz.w = COMPUTE_DEPTH_01; + return o; +} +uniform sampler2D _MainTex; +uniform fixed _Cutoff; +fixed4 frag(v2f i) : SV_Target { + fixed4 texcol = tex2D( _MainTex, i.uv ); + fixed alpha = texcol.a * i.color.a; + clip( alpha - _Cutoff ); + return EncodeDepthNormal (i.nz.w, i.nz.xyz); +} +ENDCG + } +} + +Fallback Off +} diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta new file mode 100644 index 000000000..72904677a --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: abbda12fddbb0b048a842a3835470d30 +timeCreated: 1480325971 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc index 7e80e75cb..15a27c988 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc @@ -1,5 +1,3 @@ -// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' - #ifndef SPRITE_LIGHTING_INCLUDED #define SPRITE_LIGHTING_INCLUDED diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc index aa0331fba..55d010dac 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc @@ -9,9 +9,6 @@ // Defines // -//Define to use spherical harmonics for ambient lighting -#define TRI_COLOR_AMBIENT - //////////////////////////////////////// // Vertex output struct // @@ -94,7 +91,7 @@ fixed3 calculateVertexLighting(float3 posWorld, float3 normalWorld) fixed3 calculateAmbientLight(half3 normalWorld) { -#if defined(TRI_COLOR_AMBIENT) +#if defined(_SPHERICAL_HARMONICS) fixed3 ambient = ShadeSH9(half4(normalWorld, 1.0)) * 0.75f; #else fixed3 ambient = unity_AmbientSky.rgb * 0.75; diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc index cfb0ba75b..2c30e7221 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc @@ -9,8 +9,8 @@ // Defines // -//Define to use fake spherical harmonics for ambient lighting -#define TRI_COLOR_AMBIENT +//Define to use spot lights (more expensive) +#define SPOT_LIGHTS //Have to process lighting per pixel if using normal maps or a diffuse ramp or rim lighting #if defined(_NORMALMAP) || defined(_DIFFUSE_RAMP) || defined(_RIM_LIGHTING) @@ -126,7 +126,7 @@ struct VertexLightInfo fixed3 lightColor; #if defined(_DIFFUSE_RAMP) - float attenuation; + float attenuationSqrt; #endif // _DIFFUSE_RAMP }; @@ -135,24 +135,29 @@ inline VertexLightInfo getVertexLightAttenuatedInfo(int index, float3 viewPos) VertexLightInfo lightInfo; //For directional lights _WorldSpaceLightPos0.w is set to zero - lightInfo.lightDirection = unity_LightPosition[index].xyz - (viewPos.xyz * unity_LightPosition[index].w); + lightInfo.lightDirection = unity_LightPosition[index].xyz - viewPos.xyz * unity_LightPosition[index].w; float lengthSq = dot(lightInfo.lightDirection, lightInfo.lightDirection); + + // don't produce NaNs if some vertex position overlaps with the light + lengthSq = max(lengthSq, 0.000001); + lightInfo.lightDirection *= rsqrt(lengthSq); - float attenuation = 1.0 / (1.0 + lengthSq * unity_LightAtten[index].z); + float attenuation = 1.0 / (1.0 + lengthSq * unity_LightAtten[index].z); +#if defined(SPOT_LIGHTS) //Spot light attenuation - for non-spot lights unity_LightAtten.x is set to -1 and y is set to 1 - if (-1 != unity_LightAtten[index].x || 1 != unity_LightAtten[index].y) - { - float rho = dotClamped(lightInfo.lightDirection, unity_SpotDirection[index].xyz); + { + float rho = max (0, dot(lightInfo.lightDirection, unity_SpotDirection[index].xyz)); float spotAtt = (rho - unity_LightAtten[index].x) * unity_LightAtten[index].y; attenuation *= saturate(spotAtt); } - +#endif // SPOT_LIGHTS + //If using a diffuse ramp texture then need to pass through the lights attenuation, otherwise premultiply the light color with it #if defined(_DIFFUSE_RAMP) lightInfo.lightColor = unity_LightColor[index].rgb; - lightInfo.attenuation = sqrt(attenuation); + lightInfo.attenuationSqrt = sqrt(attenuation); #else lightInfo.lightColor = unity_LightColor[index].rgb * attenuation; #endif // _DIFFUSE_RAMP @@ -162,13 +167,13 @@ inline VertexLightInfo getVertexLightAttenuatedInfo(int index, float3 viewPos) fixed3 calculateAmbientLight(half3 normalWorld) { -#if defined(TRI_COLOR_AMBIENT) +#if defined(_SPHERICAL_HARMONICS) //Magic constants used to tweak ambient to approximate pixel shader spherical harmonics - fixed3 worldUp = fixed3(0,1,0); - float skyGroundDotMul = 2.5; - float minEquatorMix = 0.5; - float equatorColorBlur = 0.33; + static const fixed3 worldUp = fixed3(0,1,0); + static const float skyGroundDotMul = 2.5; + static const float minEquatorMix = 0.5; + static const float equatorColorBlur = 0.33; float upDot = dot(normalWorld, worldUp); @@ -191,13 +196,12 @@ fixed3 calculateAmbientLight(half3 normalWorld) //Mix the two colors together based on how bright the equator light is return lerp(skyGroundColor, equatorColor, saturate(equatorBright + minEquatorMix)) * 0.75; -#else +#else // !_SPHERICAL_HARMONICS //Flat ambient is just the sky color return unity_AmbientSky.rgb * 0.75; -#endif // TRI_COLOR_AMBIENT - +#endif // !_SPHERICAL_HARMONICS } //////////////////////////////////////// @@ -208,18 +212,18 @@ fixed3 calculateAmbientLight(half3 normalWorld) inline fixed3 calculateLightDiffuse(fixed3 lightColor, half3 normal, half3 lightDirection, float attenuation) { - float angleDot = dotClamped(normal, lightDirection); + float angleDot = max(0, dot(normal, lightDirection)); fixed3 diffuse = calculateRampedDiffuse(lightColor, attenuation, angleDot); - return diffuse * 0.75; + return diffuse; } #else inline fixed3 calculateLightDiffuse(fixed3 attenuatedLightColor, half3 normal, half3 lightDirection) { - float angleDot = dotClamped(normal, lightDirection); + float angleDot = max(0, dot(normal, lightDirection)); fixed3 diffuse = attenuatedLightColor * angleDot; - return diffuse * 0.75; + return diffuse; } #endif // _NORMALMAP @@ -273,7 +277,7 @@ inline VertexLightInfo getVertexLightAttenuatedInfoWorldSpace(int index, float3 #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo) \ { \ - output.LIGHT_DIFFUSE_ATTEN_##index = lightInfo.attenuation; \ + output.LIGHT_DIFFUSE_ATTEN_##index = lightInfo.attenuationSqrt; \ } #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, vertexLightColor, normalDirection, vertexLightDir) \ @@ -314,10 +318,8 @@ inline VertexLightInfo getVertexLightAttenuatedInfoWorldSpace(int index, float3 inline fixed3 calculateLightDiffuse(int index, float3 viewPos, half3 viewNormal) { VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos); - float angleDot = dotClamped(viewNormal, lightInfo.lightDirection); - - fixed3 diffuse = lightInfo.lightColor * angleDot; - return diffuse; + float diff = max (0, dot (viewNormal, lightInfo.lightDirection)); + return lightInfo.lightColor * diff; } #endif // !PER_PIXEL_LIGHTING @@ -368,7 +370,7 @@ VertexOutput vert(VertexInput input) diffuse += calculateLightDiffuse(2, viewPos, viewNormal); diffuse += calculateLightDiffuse(3, viewPos, viewNormal); - output.FullLighting = saturate(ambient + diffuse); + output.FullLighting = ambient + diffuse; #endif // !PER_PIXEL_LIGHTING @@ -408,7 +410,7 @@ fixed4 frag(VertexOutput input) : SV_Target ADD_VERTEX_LIGHT(2, input, normalWorld, diffuse) ADD_VERTEX_LIGHT(3, input, normalWorld, diffuse) - fixed3 lighting = saturate(ambient + diffuse); + fixed3 lighting = ambient + diffuse; APPLY_EMISSION(lighting, input.texcoord.xy) diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader index 4fbbbb40b..dcddb260f 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader @@ -27,8 +27,7 @@ Shader "Spine/Sprite/Pixel Lit" _BlendTex ("Blend Texture", 2D) = "white" {} _BlendAmount ("Blend", Range(0,1)) = 0.0 - - [HideInInspector] _BlendMode ("__mode", Float) = 0.0 + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 [HideInInspector] _DstBlend ("__dst", Float) = 0.0 [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 @@ -37,7 +36,7 @@ Shader "Spine/Sprite/Pixel Lit" SubShader { - Tags { "Queue"="Transparent" "RenderType"="Transparent" } + Tags { "Queue"="Transparent" "RenderType"="Sprite" } LOD 200 Pass @@ -61,10 +60,11 @@ Shader "Spine/Sprite/Pixel Lit" #pragma shader_feature _DIFFUSE_RAMP #pragma shader_feature _COLOR_ADJUST #pragma shader_feature _TEXTURE_BLEND + #pragma shader_feature _SPHERICAL_HARMONICS #pragma shader_feature _FOG #pragma multi_compile_fwdbase - #pragma fragmentoption ARB_precision_hint_fastest + #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile_fog #pragma vertex vert diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader index 83691151e..84fccc8aa 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader @@ -16,8 +16,7 @@ Shader "Spine/Sprite/Unlit" _BlendTex ("Blend Texture", 2D) = "white" {} _BlendAmount ("Blend", Range(0,1)) = 0.0 - - [HideInInspector] _BlendMode ("__mode", Float) = 0.0 + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 [HideInInspector] _DstBlend ("__dst", Float) = 0.0 [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 @@ -26,7 +25,7 @@ Shader "Spine/Sprite/Unlit" SubShader { - Tags { "Queue"="Transparent" "RenderType"="Transparent" } + Tags { "Queue"="Transparent" "RenderType"="Sprite" } LOD 100 Pass diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader index f34cc5d05..eedc73273 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader +++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader @@ -27,8 +27,7 @@ Shader "Spine/Sprite/Vertex Lit" _BlendTex ("Blend Texture", 2D) = "white" {} _BlendAmount ("Blend", Range(0,1)) = 0.0 - - [HideInInspector] _BlendMode ("__mode", Float) = 0.0 + [HideInInspector] _SrcBlend ("__src", Float) = 1.0 [HideInInspector] _DstBlend ("__dst", Float) = 0.0 [HideInInspector] _RenderQueue ("__queue", Float) = 0.0 @@ -37,7 +36,7 @@ Shader "Spine/Sprite/Vertex Lit" SubShader { - Tags { "Queue"="Transparent" "RenderType"="Transparent" } + Tags { "Queue"="Transparent" "RenderType"="Sprite" } LOD 150 Pass @@ -62,6 +61,7 @@ Shader "Spine/Sprite/Vertex Lit" #pragma shader_feature _COLOR_ADJUST #pragma shader_feature _RIM_LIGHTING #pragma shader_feature _TEXTURE_BLEND + #pragma shader_feature _SPHERICAL_HARMONICS #pragma shader_feature _FOG #pragma fragmentoption ARB_precision_hint_fastest