Files

75 lines
2.1 KiB
Plaintext
Raw Permalink Normal View History

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
}
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)
Pass
{
Name "OUTLINE"
Cull Front
2026-07-12 20:34:49 +08:00
ZTest Always
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;
return o;
}
fixed4 frag(v2f i) : SV_Target { return _OutlineColor; }
ENDCG
}
2026-07-12 20:34:49 +08:00
// Pass 2: inner fill
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
}
}
}