How do I make a multipass shader that uses different queues?

So I’ve been trying to make a shader where the self-illuminated parts of the material render after blob shadow projectors (so that shadows don’t darken lights, as one would expect), so I wrote a multipass shader and tried to make the two passes have different queue tags so they would render before and after the shadow projector shader (which has a queue of “Transparent-2”)

However the queue thing doesn’t seem to work - the two passes seem to always render in the same queue despite the two different tag declarations (meaning either both passes cover the blob shadow or both passes are shadowed). Aside from that, the shaders behave right (i.e. both passes are running and behaving as desired), I’m just not getting the blob shadow to show up right.

Here’s the shader code:

Shader "Custom/Bump Reflect Illum" {
	Properties {
		_Color ("Main Color", Color) = (0.5,0.5,0.5,1)
		_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
		_BumpMap ("Normalmap", 2D) = "bump" {}
		_Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect }
		_ReflectColor ("Reflection Color", Color) = (0.5,0.5,0.5,1)

		_IllumColor ("Illum Color", Color) = (.5, 0.5, 0.5, 1)
		_Illum ("Illumin (A)", 2D) = "black" {}
		_IllumExponent ("Illumination Directionality", Range(0.0, 6)) = 2.0
		_BlowoutFactor ("Blowout to White", Range(0.0, 3)) = .3
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" "IgnoreProjector"="False" "Queue"="Geometry"}

		Name "Preshadow"
		LOD 400
		ZWrite On
		Blend Off

		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;
		sampler2D _BumpMap;
		samplerCUBE _Cube;
		fixed4 _Color;
		fixed4 _ReflectColor;

		struct Input {
			float2 uv_MainTex;
			float3 worldRefl;
			INTERNAL_DATA
		};

		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
			fixed4 c = tex * _Color * 2.0;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
			o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
			float3 worldRefl = WorldReflectionVector (IN, o.Normal);
			fixed4 reflcol = texCUBE(_Cube, worldRefl);
			o.Emission = _ReflectColor.rgb * reflcol.rgb * c.a;
		}
		ENDCG

		Tags { "RenderType"="Additive"  "Queue"="Transparent-1" "LightMode" = "Always" }
		Pass
		{
			Name "Self Illum"
			LOD 400
			ZWrite Off
			ZTest LEqual
			Blend One One
			CGPROGRAM
				// Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members viewDir)
				#pragma exclude_renderers xbox360
				#pragma vertex vert
				#pragma fragment frag
				#pragma fragmentoption ARB_precision_hint_fastest
				#include "UnityCG.cginc"

				struct v2f {
					float4 pos			: POSITION;
					float2 uv			: TEXCOORD1;
					float3 viewDir;
				};

				v2f vert (appdata_full v)
				{
					v2f o;
					o.pos = mul(UNITY_MATRIX_MVP, v.vertex);	
					o.uv = v.texcoord.xy;
					TANGENT_SPACE_ROTATION;
					o.viewDir = normalize(mul(rotation, normalize(ObjSpaceViewDir(v.vertex))));

					return o;
				}

				sampler2D _BumpMap;
				sampler2D _Illum;
				fixed4 _IllumColor;
				half _IllumExponent;
				half _BlowoutFactor;

				half4 frag( v2f i ) : COLOR
				{
					float3 normal = UnpackNormal(tex2D(_BumpMap, i.uv));
					half viewNormalParallelism = saturate(dot(normalize(i.viewDir), normal));
					fixed3 illum = _IllumColor.rgb * tex2D(_Illum, i.uv).rgb * pow(viewNormalParallelism, _IllumExponent) * 5.0;
					fixed blowout = max(illum.r - 1.0f, 0.0f) + max(illum.g - 1.0f, 0.0f) + max(illum.b - 1.0f, 0.0f);
					return half4(illum + blowout*_BlowoutFactor, 0);
				}
			ENDCG
		}
	}
	
	Fallback "Transparent/VertexLit"
}

thanks!

The reason the code above doesn’t work is that “tags” apply only to subshaders, whereas culling/depth testing options apply to passes. This is not made entirely obvious in the Unity documentation (it’s taken me most of the day to figure this out). Whereas you can have multiple passes in one shader, Shaderlab will pick the first compatible subshader, apply that and move on.

My guess would be that the only way to have multiple passes with different queues and rendertypes would be multiple materials, which is obviously not ideal.