Adding additional vertex light passes

I’m currently trying to get over a small problem with an outline shader. It’s job is to draw an outline around an object while leaving the rest of the objects shading as per the Diffuse shader.
It’s working great, the only issue is it only accepts 1 per-pixel directional light, where we have up to 4 additional per-vertex directional lights in the scene that need to be calculated too to make it match the default Diffuse shader. (I’m using Forward Rendering)
I have looked at this link, but adding that did nothing but add more issues, and I feel there must be a simpler solution(I may be wrong).

Here are screenshots illustrating the problem:
Normal lighting (no ambient in the scene, the lit underside is from 3-4 other directional lights in vertex-lit mode.
1429049--75720--$CorrectLighting.JPG

The Incorrect lighting on my shader (note the pretty much black underside).
1429049--75721--$IncorrectLighting.JPG

The shader code I have (Without the wikibooks multiple lights attempt):

Shader "Outlined Diffuse" {
	Properties {
		_Color ("Main Color", Color) = (.5,.5,.5,1)
		_OutlineColor ("Outline Color", Color) = (0,0,0,1)
		_Outline ("Outline width", Range (.002, 0.03)) = .005
		_MainTex ("Base (RGB)", 2D) = "white" { }
	}
	
CGINCLUDE
#include "UnityCG.cginc"
#include "AutoLight.cginc"

struct appdata {
	float4 vertex : POSITION;
	float3 normal : NORMAL;
};

struct v2f {
	float4 pos : POSITION;
	float4 color : COLOR;
};

uniform float _Outline;
uniform float4 _OutlineColor;

v2f vert(appdata v) {
	// just make a copy of incoming vertex data but scaled according to normal direction
	v2f o;
	o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

	float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
	float2 offset = TransformViewToProjection(norm.xy);

	o.pos.xy += offset * o.pos.z * _Outline;
	o.color = _OutlineColor;
	return o;
}
ENDCG

	SubShader {
		//Tags {"Queue" = "Geometry+100" }
CGPROGRAM
#pragma surface surf Lambert

sampler2D _MainTex;
fixed4 _Color;

struct Input {
	float2 uv_MainTex;
};

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

		// note that a vertex shader is specified here but its using the one above
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "ForwardBase" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			//Offset 50,50
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			float4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
		
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "ForwardAdd" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			//Offset 50,50
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			float4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}
	
	Fallback "Diffuse"
}

Any help you lovely folk could offer would be much appreciated, thank you!

No help for additional lighting passes?

Just bumping to see if anyone can help with this issue, it’s still a problem currently and I don’t know enough about shaders to know what the cause is. Any help?

I’m not entirely sure with multiple passes for surface shaders, but there is a multiple lights tutorial from CGCookie here which is pretty simple and might be able to help.

Thanks for the link, it didn’t directly help, but it did make me revisit the shader and I eventually managed to get a compromise that I’m ok with.

Multiple passes on a surface shader was a problem indeed, and I just ended up re-writing the ‘diffuse’ section to be vertex-lit. This has a couple of downsides, in that it cannot correctly receive the pixel-light’s lighting (though it does receive it in a per-vertex capacity) and also that I haven’t found a way to get it to receive the pixel-lights shadows. this might be correctable, but for now it’s workable.

Anyway, here’s the shader so far:

Shader "Outlined/OutlineDiffuse" {
    Properties {
       _Color ("Main Color", Color) = (.5,.5,.5,1)
       _OutlineColor ("Outline Color", Color) = (1,1,1,0)
       _Outline ("Outline width", Range (0.0, 0.03)) = .005
       _MainTex ("Base (RGB)", 2D) = "white" { }
    }
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct appdata {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
};
 
struct v2f {
    float4 pos : POSITION;
    float4 color : COLOR;
};
 
uniform float _Outline;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {
    // just make a copy of incoming vertex data but scaled according to normal direction
    v2f o;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 
    float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
    float2 offset = TransformViewToProjection(norm.xy);
 
    o.pos.xy += offset * o.pos.z * _Outline;
    o.color = _OutlineColor;
    return o;
}
ENDCG
 
    SubShader {
       Tags {"RenderType"="Opaque"}
	   
       // note that a vertex shader is specified here but its using the one above
       Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" "Queue" = "Transparent" "ForceNoShadowCasting" = "True"}
			Cull Front
			
			// you can choose what kind of blending mode you want for the outline
			Blend SrcAlpha Zero // Normal
			//Blend One One // Additive
			//Blend One OneMinusDstColor // Soft Additive
			//Blend DstColor Zero // Multiplicative
			//Blend DstColor SrcColor // 2x Multiplicative
 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			 
			half4 frag(v2f i) : COLOR {
				return i.color;
			}
			ENDCG 
		}
		
		Pass
		{
			Material {
				Diffuse [_Color]
				Ambient [_Color]
			}
			Lighting On
			SetTexture [_MainTex]{
				Combine texture * primary Double, texture * primary
			}
		}
    }
 
    Fallback "VertexLit"
}

I’ve been lerping the outlineColor alpha in code while the user hovers over an item, which works to an ok standard, in future I might try and sort the pixel-lighting issues on the diffuse pass, if at all possible.