Always on top shader help

Hi all.

I created the shader below to render a first person arms on top of everything. It is working fine for this purpose however I am getting weird overlaps within the model itself:
5264570--526742--AlwaysOnTop.png

Shader:

Shader "Custom/AlwaysOnTop" {
    Properties{
        _Color("Main Color", Color) = (1,1,1,1)
        _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
    }

        SubShader
        {
            Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "IgnoreProjector" = "True" }
            LOD 200
            ZTest Always

            Pass
            {
                ZWrite On
                ColorMask 0

                CGPROGRAM

                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"

                struct v2f
                {
                    float4 pos : SV_POSITION;
                };

                v2f vert(appdata_base v)
                {
                    v2f o;
                    o.pos = UnityObjectToClipPos(v.vertex);
                    return o;
                }

                half4 frag(v2f i) : COLOR
                {
                    return half4(0,0,0,0);
                }

                ENDCG
            }

            CGPROGRAM

            #pragma surface surf Standard

            sampler2D _MainTex;
            fixed4 _Color;

            struct Input
            {
                float2 uv_MainTex;
            };

            void surf(Input IN, inout SurfaceOutputStandard o)
            {
                fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
                o.Albedo = c.rgb;
                o.Alpha = c.a;
            }

            ENDCG
        }

        Fallback "Standard"
}

Can someone please shed some light on how I can fix these overlaps?

Thanks in advance

Those artifacts are directly caused by the use of ZTest Always. You can’t use that setting on 3D meshes any more complex than a sphere and expect anything usable. The depth buffer (what ZTest and ZWrite control the shader’s usage of) is used to ensure proper sorting against opaque objects. As soon as you set ZTest Always it ignores the depth buffer and it’s purely down the the render order of the triangles in the mesh. Since Unity doesn’t do per triangle sorting, the draw order comes down to the order they exist in the mesh’s triangle list.

If you want the hands to draw on top, you’ll need to use a custom matrix to draw the hands. There are a couple of threads on drawing weapons that show how to do this.
https://discussions.unity.com/t/625853

Another alternative would be to use two materials, one that renders a special depth only pass to clear the depth buffer where the hands will be rendered, then render them normally afterward.

Hi, i will look into this thread to see if it fits my case, thanks. In regards to using two materials I actually dont mind 2 draw calls since this is an important element. I will search the threads for any lights on this, but if you know it at the top of your head would you please indicate it to me? thank you

I can’t think of any threads on exactly the two material technique. I’ve posted about similar setups when using stencils for things like portals and stuff. It has the unfortunate side effect of not working with a lot of Unity’s systems (like shadows and any post processing that uses the depth buffer will be messed up).

thanks. after exploring the options i will just stick to scaling the arms down. this will give me good results without messing around with shaders. the custom matrix solution pointed above doesnt seem to be working with the latest unity version, by the way. also, using a two layered camera approach doesnt seem to be working properly with cinemachine and post processing effects. regards