I was inspired by a colleague to create this shader. So here it is. The shader uses an invisible plane to determine where the visibility line should be.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | Shader "Unlit/Ship" { 	Properties 	{ 		_MainTex ("Texture", 2D) = "white" {} 		_OutlinePosition ("Outline Position", VECTOR) = (0,0,0,0) 	} 	SubShader 	{ 		Tags { "Queue"="Transparent" } 		Pass 		{ 			Blend SrcAlpha OneMinusSrcAlpha 			CGPROGRAM 			#pragma vertex vert 			#pragma fragment frag 			#include "UnityCG.cginc" 			struct appdata 			{ 				float4 vertex : POSITION; 				float2 uv : TEXCOORD0; 			}; 			struct v2f 			{ 				float4 vertex : SV_POSITION; 				float2 uv : TEXCOORD0; 				float3 planeWorldPos : TEXCOORD1; 				float3 planeWorldNormal : TEXCOORD2; 				float3 worldPos : TEXCOORD3; 			}; 			sampler2D _MainTex; 			float4 _MainTex_ST; 			float4 _OutlinePosition; 			v2f vert (appdata v) 			{ 				v2f o; 				o.vertex = UnityObjectToClipPos(v.vertex); 				o.uv = TRANSFORM_TEX(v.uv, _MainTex); 				o.planeWorldPos = mul(unity_ObjectToWorld,  _OutlinePosition); 				o.planeWorldNormal = mul(unity_ObjectToWorld,  float3(0,0,1)); 				o.worldPos = mul(unity_ObjectToWorld, v.vertex); 				return o; 			} 			fixed4 frag (v2f i) : SV_Target 			{ 				float3 planeWorldNormal = normalize(i.planeWorldNormal); 				float d = dot(i.planeWorldPos, planeWorldNormal); 				float d1 = dot(i.worldPos, planeWorldNormal); 				float dDelta = d1 - d; 				float t = 1.0 - pow(abs(dDelta) * 1.0, 0.2); 				fixed4 outlineCol = saturate(float4(t * 2.0, t * 4.0, t * 8.0, 1.0)); 				fixed4 col = tex2D(_MainTex, i.uv) + outlineCol; 				col.a = step(0.0, dDelta); 				return col; 			} 			ENDCG 		} 	} } | 
