Calling Material.setPass with custom shader breaks GL

Here is my shader, which replaces one color with another:

 Shader "Custom/SwapColors"
  {
     Properties
     {
       _MainTex("Texture",2D)="white"{}
       swap_from("Swap From",COLOR)=(1,1,1,1)
       swap_to("Swap To",COLOR)=(1,1,1,1)
       threshold("Threshold",Float)=0.00001
     }
     SubShader
     {
       Tags
       {
         "Queue"="Transparent"
       }
       Pass
       {
         Blend SrcAlpha OneMinusSrcAlpha
         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
       
         sampler2D _MainTex;
         float4 swap_from;
         float4 swap_to;
         float threshold;
       
         struct VertexInput
         {
           float4 pos:POSITION;
           float2 uv:TEXCOORD0;
         };
         struct FragmentInput
         {
           float4 pos:SV_POSITION;
           float2 uv:TEXCOORD0;
         };
       
         FragmentInput vert(VertexInput data)
         {
           FragmentInput res;
           res.pos=mul(UNITY_MATRIX_MVP,data.pos);
           res.uv=data.uv;
           return res;
         }
         bool eq(fixed f,fixed s)
         {
           return abs(f-s)<threshold;
         }
         float4 frag(FragmentInput data):COLOR
         {
           float4 res=tex2D(_MainTex,data.uv.xy).rgba;
           if(eq(res.r,swap_from.r)&&eq(res.g,swap_from.g)&&eq(res.b,swap_from.b))
             res.rgb=swap_to.rgb;
           return res;
         }
         ENDCG
       }
     }
     Fallback "Diffuse"
  }

Here is a Test script attached to gameobject which contains main camera. In it I try to render a line and a textured quad.

mat is assigned with SwapColors with a texture.

sprite_mat is assigned with default sprite shader with the same texture.

  using UnityEngine;
  using System.Collections;
 
  public class Test : MonoBehaviour
  {
     [SerializeField]
     Material mat;
     [SerializeField]
     Material sprite_mat;
     void OnPostRender()
     {
     
     
       GL.PushMatrix();
       GL.LoadProjectionMatrix(Camera.main.projectionMatrix);
       GL.modelview=Camera.main.worldToCameraMatrix;
     
       GL.Begin(GL.LINES);
       sprite_mat.SetPass(0);
       GL.Vertex(new Vector3(0,0));
       GL.Vertex(new Vector3(5,0));
       GL.End();
     
     
       GL.Begin(GL.QUADS);
       sprite_mat.SetPass(0);
     
       mat.SetPass(0);//<------------------------------------ PROBLEM
     
       GL.TexCoord(new Vector3(0,0));
       GL.Vertex(new Vector2(0,0));
     
       GL.TexCoord(new Vector3(1,0));
       GL.Vertex(new Vector2(1,0));
     
       GL.TexCoord(new Vector3(1,1));
       GL.Vertex(new Vector2(1,1));
     
       GL.TexCoord(new Vector3(0,1));
       GL.Vertex(new Vector2(0,1));
       GL.End();
     
     
       GL.PopMatrix();
     }
  }

When I render the quad with sprite_mat, everything is ok.

When I use mat, not only the quad disappear, but the line too, despite it’s rendered with sprite_mat.

If I create another quad in editor and set its material to mat, it’s rendered correctly.

My main question is how can setPass affect geometry rendered after another unrelated setPass.

Example project is linked below

2106999–138105–ErrorGL.7z (68.6 KB)

I found a default Unity sprite shader and compared it with my. The quad disappeared because it faced opposite direction from the camera. It’s fixed by “Cull Off”

If I add line

float4 color:COLOR;

to VertexInput structure, material with my shader stops affecting geometry with other materials. I don’t understand what is happening.