Shader Outline scale problem since U5

Hello all,

Since Unity 5 I have a problem in with my ‘outline diffuse’ shader.

So, the problem:
it seems like the outline is unproportionally scaled to the size of an object.
See example bellow: these are twice the exact same object with the same shader/material. But the small one is scaled on xyz to .2 of its original size.
42425-outlinediffusescale.png

Would any of you know how to correct this?

PS: Let me admit that I try my best learning everything I can to develop a game, but shader code is still chineese to me… :frowning:

Here is the shader code used:

//credits: http://wiki.unity3d.com/index.php/Outlined_Diffuse_3
//credits bis: http://answers.unity3d.com/questions/742645/shader-outlined-diffuse-with-vertex-color.html

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"

	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" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			//Offset 50,50

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			half4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}

	SubShader {
		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

		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha

			CGPROGRAM
			#pragma vertex vert
			#pragma exclude_renderers gles xbox360 ps3
			ENDCG
			SetTexture [_MainTex] { combine primary }
		}
	}

	Fallback "Diffuse"
}

Thank you for your help & happy coding!

I was having the same problem with the same shader.

It seems that in Unity 5 they changed the way they “process” the scale of an object.

http://docs.unity3d.com/Manual/UpgradeGuide5-Shaders.html

In Unity 5.0, non-uniform meshes are not “prescaled” on the CPU anymore. This means that normal & tangent vectors can be non-normalized in the vertex shader.

To solve your problem, in line 33 of the shader, change it to:

float3 norm = normalize(mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal));