[Solved] Shader not rendering model correctly

So i am working on a game which uses a cat model and i wanted to use a masked shader to only show the head of the cat instead of the whole body.
One ear always renders the top over all the other elements and the other always renders the bottom.

Right renders top
4693700--442811--upload_2019-6-28_10-3-22.png
Always renders bottom
4693700--442814--upload_2019-6-28_10-4-16.png

This is the masked shader im using, does anyone have any advice on how I could solve this issue?

Shader "Masked" {
    Properties {
        _MainTex ("Main", 2D) = "white" {}
        _MaskTex ("Mask", 2D) = "white" {}
    }

    SubShader {
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        ZWrite Off
        ZTest Off
        Blend SrcAlpha OneMinusSrcAlpha
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            uniform sampler2D _MaskTex;
            uniform float4 _MainTex_ST;
            uniform float4 _MaskTex_ST;

            struct app2vert
            {
                float4 position: POSITION;
                float2 texcoord: TEXCOORD0;
            };

            struct vert2frag
            {
                float4 position: POSITION;
                float2 texcoord: TEXCOORD0;
            };

            vert2frag vert(app2vert input)
            {
                vert2frag output;
                output.position = UnityObjectToClipPos(input.position);
                output.texcoord = TRANSFORM_TEX(input.texcoord, _MainTex);
                return output;
            }

            fixed4 frag(vert2frag input) : COLOR
            {
                fixed4 main_color = tex2D(_MainTex, input.texcoord);
                fixed4 mask_color = tex2D(_MaskTex, input.texcoord);
                return fixed4(main_color.r, main_color.g, main_color.b, main_color.a * (1.0f - mask_color.a));
            }
            ENDCG
        }
    }
}

Is there a reason this shader needs to be transparent? Transparency introduces render sorting issues since fragments can’t be properly depth sorted (at least not with the default method unity uses). If you don’t need semi-transparency, then change it to Tags {"Queue"="Geometry" "IgnoreProjector"="True" "RenderType"="Opaque"} , remove the ZWrite and ZTest lines, and in your frag() function, you can use clip(main_color.a * (1.0f - mask_color.a)) before the return line.

That seems to have done the trick!
Thank you for the fast reply, I am still as new as can be with shaders so i had no idea transparency would cause the render issues.

1 Like