Skip to content

Instantly share code, notes, and snippets.

@hiepnd
Last active March 24, 2024 00:04
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiepnd/e00324106c6b8d4e6714 to your computer and use it in GitHub Desktop.
Save hiepnd/e00324106c6b8d4e6714 to your computer and use it in GitHub Desktop.
Unity Outline shader for transparent object
Shader "Screw/Alpha Outline" {
Properties {
_Color ("Main Color", Color) = (.5,.5,.5,1)
_OutlineColor ("Outline Color", Color) = (0,0,0,1)
_Outline ("Outline width", Range (0.0, 0.15)) = .005
_OutlineOffset ("Outline Offset", Vector) = (0, 0, 0)
_MainTex ("Base (RGB)", 2D) = "white" { }
_Alpha ("Alpha", Float) = 1
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata {
half4 vertex : POSITION;
half3 normal : NORMAL;
half2 texcoord : TEXCOORD0;
};
struct v2f {
half4 pos : POSITION;
half2 uv : TEXCOORD0;
half3 normalDir : NORMAL;
};
uniform half4 _Color;
uniform half _Outline;
uniform half4 _OutlineColor;
ENDCG
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
Name "STENCIL"
ZWrite Off
ZTest Always
ColorMask 0
Stencil {
Ref 2
Comp always
Pass replace
ZFail decrWrap
}
CGPROGRAM
#pragma vertex vert2
#pragma fragment frag
v2f vert2 (appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
half4 frag (v2f i) : COLOR
{
return _Color;
}
ENDCG
}
Pass {
Name "OUTLINE"
Tags { "LightMode" = "Always" }
Cull Off
ZWrite Off
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
Stencil {
Ref 2
Comp NotEqual
Pass replace
ZFail decrWrap
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half3 _OutlineOffset;
v2f vert(appdata v) {
v2f o;
half3 vertex = v.vertex.xyz;
vertex -= _OutlineOffset;
vertex.x *= _Outline+1;
vertex.y *= _Outline+1;
vertex.z *= _Outline+1;
vertex += _OutlineOffset;
o.pos = mul(UNITY_MATRIX_MVP, half4(vertex, v.vertex.w));
return o;
}
half _Alpha;
half4 frag(v2f i) :COLOR {
return half4(_OutlineColor.rgb, _Alpha);
}
ENDCG
}
Pass {
Name "BASE"
ZWrite On
ZTest LEqual
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert2
#pragma fragment frag
v2f vert2 (appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
o.normalDir = normalize(mul(half4(v.normal, 0), _World2Object).xyz);
return o;
}
uniform sampler2D _MainTex;
uniform half4 _LightColor0;
half _Alpha;
half4 frag (v2f i) : COLOR
{
half4 c = tex2D(_MainTex, i.uv) * _Color;
// c.a = _Color.a;
c.a = _Alpha;
return c;
half3 lightDirection = normalize(_WorldSpaceLightPos0.xyz );
half diffuse = max(0.4, dot(i.normalDir, lightDirection));
half3 tex = tex2D(_MainTex, i.uv).rgb;
half3 color = diffuse * _LightColor0.rgb * tex * _Color.rgb;
return half4(color, _Alpha);
}
ENDCG
}
}
Fallback Off
}
@ArcherLew
Copy link

请教下兄弟,第一个pass是干嘛用的呢?
what's the first pass doing ? thx :)

@hakanai
Copy link

hakanai commented Jun 8, 2018

Looks like it's just writing 2 into the stencil buffer for all the area covered by the model. The second pass is then pushing out the vertices along their normals and painting that as the outline, but not painting on the areas with stencil=2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment