Hi, I need help with "shader mask" for SkeletonAnimation in Unity bescause I don't know anything about shader 🙁

I have 2 types of plants in my project.
Type 1: is a static object, using the sprite renderer + sprite mask component to show the "white shadow" of the character when standing behind the tree.
Type 2: It is an animated tree, it uses SkeletonAnimation with a Skeleton Mask shader that I edited from Skeleton tint black so it has the same effect as type 1.
To edit the skeleton mask shader, I referred to this link:

esotericsoftware.com/forum/d/16082-animated-maskunity-help/7

and added this line of code as advised:

float4 frag (VertexOutput i) : SV_Target {
    float4 texColor = tex2D(_MainTex, i.uv);
    clip((texColor.a * i.vertexColor.a) - _Cutoff); // add this line

#if defined(_STRAIGHT_ALPHA_INPUT)
texColor.rgb *= texColor.a;
#endif

return (texColor * i.vertexColor);
}

But it seems ineffective. It still has the same problem as in the link I just mentioned, you can see 2 pictures illustrating my 2 types of plants

  • Tree (SkeletonAnimation) with shader Spine/Skeleton Mask. It is masked throughout the entire image area, even when the pixels are transparent.

  • Tree (Sprite Renderer) with Sprite Mask. It works fine.

Here is the shader code:

`Shader "Spine/Skeleton Mask" {
Properties{
_Color("Tint Color", Color) = (1,1,1,1)
_Black("Dark Color", Color) = (0,0,0,0)
[NoScaleOffset] MainTex("MainTex", 2D) = "black" {}
[Toggle(
STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
[Toggle(
DARK_COLOR_ALPHA_ADDITIVE)] _DarkColorAlphaAdditive("Additive DarkColor.A", Int) = 0
[HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0
[HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default
}

    SubShader{
        Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
        LOD 100

        Fog { Mode Off }
        Cull Off
        ZWrite Off
        Blend One OneMinusSrcAlpha
        Lighting Off

        Stencil {
            Ref[_StencilRef]
            Comp[_StencilComp]
            Pass Replace
        }

        Pass {
            Name "Normal"

            CGPROGRAM
            #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
            #pragma shader_feature _ _DARK_COLOR_ALPHA_ADDITIVE
            #define _ALPHA_CLIP                     
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _Color;
            float4 _Black;
            float2 _Cutoff;

            struct VertexInput {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float4 vertexColor : COLOR;
                float2 uv1 : TEXCOORD1;
                float2 uv2 : TEXCOORD2;
            };

            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                float4 vertexColor : COLOR;
                float3 darkColor : TEXCOORD1;
            };

            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);
                o.darkColor = float3(v.uv1.r, v.uv1.g, v.uv2.r);
                return o;
            }
            #include "CGIncludes/Spine-Skeleton-Tint-Common.cginc"
            float4 frag(VertexOutput i) : SV_Target
            {
                float4 texColor = tex2D(_MainTex, i.uv);
                #if defined(_STRAIGHT_ALPHA_INPUT)
                texColor.rgb *= texColor.a;
                #endif
                clip((texColor.a* i.vertexColor.a) - _Cutoff);
                return fragTintedColor(texColor, _Black.rgb + i.darkColor, i.vertexColor, _Color.a, _Black.a);
            }
            ENDCG
        }

        Pass {
            Name "Caster"
            Tags { "LightMode" = "ShadowCaster" }
            Offset 1, 1
            ZWrite On
            ZTest LEqual

            Fog { Mode Off }
            Cull Off
            Lighting Off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #pragma fragmentoption ARB_precision_hint_fastest
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            fixed _Cutoff;

            struct VertexOutput {
                V2F_SHADOW_CASTER;
                float4 uvAndAlpha : TEXCOORD1;
            };

            VertexOutput vert(appdata_base v, float4 vertexColor : COLOR) {
                VertexOutput o;
                o.uvAndAlpha = v.texcoord;
                o.uvAndAlpha.a = vertexColor.a;
                TRANSFER_SHADOW_CASTER(o)
                return o;
            }

            float4 frag(VertexOutput i) : SV_Target {
                fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
                clip(texcol.a* i.uvAndAlpha.a - _Cutoff);
                SHADOW_CASTER_FRAGMENT(i)
            }
            ENDCG
        }
}
    CustomEditor "SpineShaderWithOutlineGUI"

}`

Related Discussions
...

@notme1611 Sorry to hear that the issue persists. I can see nothing obviously wrong with your shader though.

At the SkeletonAnimation component, did you set up the Mask Interaction property the same (e.g. to Visible Outside Mask) as with your non-Spine Sprite?

If it is set up the same, could you please send us a minimal Unity project which still shows this issue? You can send it as a zip package to contact@esotericsoftware.com, briefly mentioning this forum thread so that we know the context. Then we can have a look at whats going wrong.

11일 후

@notme1611 Thanks for sending the reproduction project. The problem with your mask shader Spine-Skeleton-Mask.shader that in line 45 it incorrectly reads float2 _Cutoff; (a 2D vector) instead of float _Cutoff; which makes Unity not assign your configured Alpha Cutoff Inspector Material values at this shader property, and assigned 0 every time instead.

BTW: Since I saw you were using two identical SkeletonAnimation GameObjects for hero_2_visual and hero_2_visual_silhouette: Please note that you could use the RenderExistingMesh component to re-render an identical skeleton mesh with a different shader. While it might not be included in spine-unity 3.8, you should be able to just integrate the example component script taken from 4.1 into your project. You can find the source code here. If your setup was only for the reproduction project, please ignore the section above.

    Hey Harald, It's okay now 🙂 Thanks for the help.

    About my setup, yes, I setup the ‘main’ project like the reproduction project, so I think it’s not optimal. I added the ‘RenderExistingMesh’ component to the GameObject, but it has something wrong:

    @notme1611 The lines in the error messages neither match the code of the 4.1 nor the 4.2-beta repository, line 99 for example is an empty line on both branches:
    EsotericSoftware/spine-runtimesblob/4.1/spine-unity/Assets/Spine%20Examples/Scripts/Sample%20Components/RenderExistingMesh.cs#L99
    EsotericSoftware/spine-runtimesblob/4.2-beta/spine-unity/Assets/Spine%20Examples/Scripts/Sample%20Components/RenderExistingMesh.cs#L99
    Did you modify the RenderExistingMesh source code? If so, please share what code now lies on the mentioned lines of the error messages (lines 99, 133 and 150).