2026-06-30 03:02:12 +08:00
|
|
|
Shader "Custom/OutlineUnlit"
|
|
|
|
|
{
|
|
|
|
|
Properties
|
|
|
|
|
{
|
|
|
|
|
_MainColor ("Main Color", Color) = (0.1, 0.3, 0.8, 0.3)
|
|
|
|
|
_OutlineColor ("Outline Color", Color) = (0.2, 0.5, 1, 1)
|
2026-07-12 20:34:49 +08:00
|
|
|
_OutlineWidth ("Outline Width", Range(0, 10)) = 2.0
|
2026-06-30 03:02:12 +08:00
|
|
|
}
|
|
|
|
|
SubShader
|
|
|
|
|
{
|
|
|
|
|
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
|
|
|
|
|
Blend SrcAlpha OneMinusSrcAlpha
|
|
|
|
|
ZWrite Off
|
|
|
|
|
|
2026-07-12 20:34:49 +08:00
|
|
|
// Pass 1: clip-space outline (screen-pixel width, scale-independent)
|
2026-06-30 03:02:12 +08:00
|
|
|
Pass
|
|
|
|
|
{
|
|
|
|
|
Name "OUTLINE"
|
|
|
|
|
Cull Front
|
2026-07-12 20:34:49 +08:00
|
|
|
ZTest Always
|
2026-06-30 03:02:12 +08:00
|
|
|
CGPROGRAM
|
|
|
|
|
#pragma vertex vert
|
|
|
|
|
#pragma fragment frag
|
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
|
|
|
|
|
|
float _OutlineWidth;
|
|
|
|
|
float4 _OutlineColor;
|
|
|
|
|
|
|
|
|
|
struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; };
|
|
|
|
|
struct v2f { float4 pos : SV_POSITION; };
|
|
|
|
|
|
|
|
|
|
v2f vert(appdata v)
|
|
|
|
|
{
|
|
|
|
|
v2f o;
|
|
|
|
|
o.pos = UnityObjectToClipPos(v.vertex);
|
2026-07-12 20:34:49 +08:00
|
|
|
|
|
|
|
|
// transform normal to clip space
|
|
|
|
|
float3 clipNormal = mul((float3x3)UNITY_MATRIX_VP, mul((float3x3)unity_ObjectToWorld, v.normal));
|
|
|
|
|
|
|
|
|
|
// offset in clip space by a fixed pixel width
|
|
|
|
|
float2 offset = normalize(clipNormal.xy) * _OutlineWidth * 0.001;
|
|
|
|
|
|
|
|
|
|
// aspect ratio correction
|
|
|
|
|
offset.x /= _ScreenParams.x / _ScreenParams.y;
|
|
|
|
|
|
|
|
|
|
o.pos.xy += offset * o.pos.w;
|
2026-06-30 03:02:12 +08:00
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fixed4 frag(v2f i) : SV_Target { return _OutlineColor; }
|
|
|
|
|
ENDCG
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-12 20:34:49 +08:00
|
|
|
// Pass 2: inner fill
|
2026-06-30 03:02:12 +08:00
|
|
|
Pass
|
|
|
|
|
{
|
|
|
|
|
Name "FILL"
|
|
|
|
|
Cull Back
|
|
|
|
|
CGPROGRAM
|
|
|
|
|
#pragma vertex vert
|
|
|
|
|
#pragma fragment frag
|
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
|
|
|
|
|
|
float4 _MainColor;
|
|
|
|
|
|
|
|
|
|
struct appdata { float4 vertex : POSITION; };
|
|
|
|
|
struct v2f { float4 pos : SV_POSITION; };
|
|
|
|
|
|
|
|
|
|
v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; }
|
|
|
|
|
fixed4 frag(v2f i) : SV_Target { return _MainColor; }
|
|
|
|
|
ENDCG
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|