I'm assuming you mean having multiple objects with the same skeleton data/material/ atlas asset on which I do have. If not I would have just used the shared material and reset it to a 'start state' at the end of each run of the game.
The main reason why I need this capability is because of a flipping issue, I need the characters to face either left or right depending on the direction they are moving. Flip x on the skeleton utility has many problems with not flipping some Ik's and some animations correctly so I went back to my original solution which was rotating 180 degrees in the y axis but the normals are the wrong way round. So In my shader I have a flip normals tick box. Without each character instance having a non shared material I cannot use this solution.
Also the ability to alter shader variables in runtime could be useful.
edit:
I currently have another issue that I have been meaning to ask about, the way that has been suggested on the forums to change the transparency of a character is to change the Skeleton.a value.
This works if I use one of the supplied spine shaders but not If I use my custom one, here is the shader I am using:
Shader "Custom/Inverse-NormalMap-Specular" {
Properties{
_ColourTint ("Colour Tint", Color) =(1.0,1.0,1.0,1.0)
_MainTex ("Diffuse Texture", 2D) = "white" {}
_BumpTex ("Normal Map", 2D) = "bump" {}
_BumpDepth ("Bump Depth", Range(-2.0, 2.0)) = 1.0
_SpecColour ("Specular Colour", Color) = (1.0,1.0,1.0,1.0)
_Shininess ("Shininess", float) = 10
[MaterialToggle] _IsInverted ("IsInverted", float) = 0
_Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1
}
SubShader{
Tags{"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 100
Cull Off
AlphaTest Greater 0.1 //This is stopping the low alpha spots from appearing
Pass{
Tags{"LightMode" = "ForwardBase"}
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
uniform sampler2D _BumpTex;
uniform half4 _MainTex_ST;
uniform half4 _BumpTex_ST;
uniform fixed4 _ColourTint;
uniform fixed4 _SpecColour;
uniform half _Shininess;
uniform fixed _BumpDepth;
uniform fixed _IsInverted;
uniform half4 _LightColor0;
struct vertexInput{
half4 vertex : POSITION;
half3 normal : NORMAL;
half4 texcoord : TEXCOORD;
half4 tangent : TANGENT;
};
struct vertexOutput{
half4 pos : SV_POSITION;
half4 tex : TEXCOORD0;
fixed4 lightDirectionAtten : TEXCOORD1;
fixed3 viewDirection : TEXCOORD2;
fixed3 normalWorld : TEXCOORD3;
fixed3 tangentWorld : TEXCOORD4;
fixed3 binormalWorld : TEXCOORD5;
};
vertexOutput vert(vertexInput v){
vertexOutput o;
half4 posWorld = mul(_Object2World, v.vertex);
o.normalWorld = normalize(mul(half4(v.normal, 0.0), _World2Object).xyz);
o.tangentWorld = normalize(mul(_Object2World, v.tangent).xyz);
o.binormalWorld = normalize(cross(o.normalWorld, o.tangentWorld) * v.tangent.w);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
o.viewDirection= normalize(_WorldSpaceCameraPos.xyz - posWorld.xyz);;
if(_IsInverted != 0)
o.viewDirection = -o.viewDirection;
half3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
o.lightDirectionAtten = fixed4(normalize( lerp(_WorldSpaceLightPos0.xyz, fragmentToLightSource, _WorldSpaceLightPos0.w)),
lerp(1.0, 1.0/length(fragmentToLightSource),_WorldSpaceLightPos0.w));
return o;
}
float4 frag(vertexOutput i) : COLOR
{
fixed4 texN = tex2D(_BumpTex, i.tex.xy * _BumpTex_ST.xy + _BumpTex_ST.zw);
fixed4 tex = tex2D(_MainTex, i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
fixed3 localCoords = float3(2.0 * texN.ag - float2(1.0, 1.0), _BumpDepth);
fixed3x3 local2WorldTranspose = fixed3x3(
i.tangentWorld,
i.binormalWorld,
i.normalWorld
);
fixed3 normalDirection = normalize( mul( localCoords, local2WorldTranspose) );
if(_IsInverted != 0)
normalDirection = -normalDirection;
fixed3 diffuseReflection = i.lightDirectionAtten.w * _LightColor0.xyz * max(0.0, dot(normalDirection, i.lightDirectionAtten.xyz));
fixed3 specularReflection = diffuseReflection * _SpecColour.xyz * pow(max(0.0, dot( reflect(-i.lightDirectionAtten.xyz, normalDirection), i.viewDirection)) , _Shininess);
fixed3 lightFinal = diffuseReflection + UNITY_LIGHTMODEL_AMBIENT + specularReflection;
return fixed4(tex.xyz * lightFinal * _ColourTint.rgb, _ColourTint.a*tex.a );
};
ENDCG
}
Pass{
Tags{"LightMode" = "ForwardAdd"}
Blend SrcAlpha One // additive blending
ZWrite Off
ZTest Equal
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
uniform sampler2D _BumpTex;
uniform half4 _MainTex_ST;
uniform half4 _BumpTex_ST;
uniform fixed4 _ColourTint;
uniform fixed4 _SpecColour;
uniform half _Shininess;
uniform fixed _BumpDepth;
uniform fixed _IsInverted;
uniform half4 _LightColor0;
struct vertexInput{
half4 vertex : POSITION;
half3 normal : NORMAL;
half4 texcoord : TEXCOORD;
half4 tangent : TANGENT;
};
struct vertexOutput{
half4 pos : SV_POSITION;
half4 tex : TEXCOORD0;
fixed4 lightDirectionAtten : TEXCOORD1;
fixed3 viewDirection : TEXCOORD2;
fixed3 normalWorld : TEXCOORD3;
fixed3 tangentWorld : TEXCOORD4;
fixed3 binormalWorld : TEXCOORD5;
};
vertexOutput vert(vertexInput v){
vertexOutput o;
half4 posWorld = mul(_Object2World, v.vertex);
o.normalWorld = normalize(mul(half4(v.normal, 0.0), _World2Object).xyz);
o.tangentWorld = normalize(mul(_Object2World, v.tangent).xyz);
o.binormalWorld = normalize(cross(o.normalWorld, o.tangentWorld) * v.tangent.w);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
o.viewDirection= normalize(_WorldSpaceCameraPos.xyz - posWorld.xyz);;
if(_IsInverted != 0)
o.viewDirection = -o.viewDirection;
half3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
o.lightDirectionAtten = fixed4(normalize( lerp(_WorldSpaceLightPos0.xyz, fragmentToLightSource, _WorldSpaceLightPos0.w)),
lerp(1.0, 1.0/length(fragmentToLightSource),_WorldSpaceLightPos0.w));
return o;
}
float4 frag(vertexOutput i) : COLOR
{
fixed4 texN = tex2D(_BumpTex, i.tex.xy * _BumpTex_ST.xy + _BumpTex_ST.zw);
fixed4 tex = tex2D(_MainTex, i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
fixed3 localCoords = float3(2.0 * texN.ag - float2(1.0, 1.0), _BumpDepth);
fixed3x3 local2WorldTranspose = fixed3x3(
i.tangentWorld,
i.binormalWorld,
i.normalWorld
);
fixed3 normalDirection = normalize( mul( localCoords, local2WorldTranspose) );
if(_IsInverted != 0)
normalDirection = -normalDirection;
fixed3 diffuseReflection = i.lightDirectionAtten.w * _LightColor0.xyz * max(0.0, dot(normalDirection, i.lightDirectionAtten.xyz));
fixed3 specularReflection = diffuseReflection * _SpecColour.xyz * pow(max(0.0, dot( reflect(-i.lightDirectionAtten.xyz, normalDirection), i.viewDirection)) , _Shininess);
fixed3 lightFinal = diffuseReflection + specularReflection;
return float4( lightFinal * tex.rgb * _ColourTint.rgb , _ColourTint.a*tex.a);
};
ENDCG
}
//this next pass is copied from "Skeleton.shader"
Pass {
Name "Caster"
Tags { "LightMode"="ShadowCaster" }
Offset 1, 1
Fog { Mode Off }
ZWrite On
ZTest LEqual
Cull Off
Lighting Off
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;
half2 uv : TEXCOORD1;
};
uniform half4 _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
}
}
//Fallback "Specular"
}
I am unsure how the change in alpha gets to the shader, there must be a way to incorporate it in to mine.
Any help on either of these issues would be much appreciated.