-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathUltimateOutline.shader
143 lines (112 loc) · 3.55 KB
/
UltimateOutline.shader
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//This version of the shader does not support shadows, but it does support transparent outlines
Shader "Outlined/UltimateOutline"
{
Properties
{
_Color("Main Color", Color) = (0.5,0.5,0.5,1)
_MainTex("Texture", 2D) = "white" {}
_FirstOutlineColor("Outline color", Color) = (1,0,0,0.5)
_FirstOutlineWidth("Outlines width", Range(0.0, 2.0)) = 0.15
_SecondOutlineColor("Outline color", Color) = (0,0,1,1)
_SecondOutlineWidth("Outlines width", Range(0.0, 2.0)) = 0.025
_Angle("Switch shader on angle", Range(0.0, 180.0)) = 89
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float4 normal : NORMAL;
};
uniform float4 _FirstOutlineColor;
uniform float _FirstOutlineWidth;
uniform float4 _SecondOutlineColor;
uniform float _SecondOutlineWidth;
uniform sampler2D _MainTex;
uniform float4 _Color;
uniform float _Angle;
ENDCG
SubShader{
//First outline
Pass{
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Back
CGPROGRAM
struct v2f {
float4 pos : SV_POSITION;
};
#pragma vertex vert
#pragma fragment frag
v2f vert(appdata v) {
appdata original = v;
float3 scaleDir = normalize(v.vertex.xyz - float4(0,0,0,1));
//This shader consists of 2 ways of generating outline that are dynamically switched based on demiliter angle
//If vertex normal is pointed away from object origin then custom outline generation is used (based on scaling along the origin-vertex vector)
//Otherwise the old-school normal vector scaling is used
//This way prevents weird artifacts from being created when using either of the methods
if (degrees(acos(dot(scaleDir.xyz, v.normal.xyz))) > _Angle) {
v.vertex.xyz += normalize(v.normal.xyz) * _FirstOutlineWidth;
}else {
v.vertex.xyz += scaleDir * _FirstOutlineWidth;
}
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : COLOR{
return _FirstOutlineColor;
}
ENDCG
}
//Second outline
Pass{
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Back
CGPROGRAM
struct v2f {
float4 pos : SV_POSITION;
};
#pragma vertex vert
#pragma fragment frag
v2f vert(appdata v) {
appdata original = v;
float3 scaleDir = normalize(v.vertex.xyz - float4(0,0,0,1));
//This shader consists of 2 ways of generating outline that are dynamically switched based on demiliter angle
//If vertex normal is pointed away from object origin then custom outline generation is used (based on scaling along the origin-vertex vector)
//Otherwise the old-school normal vector scaling is used
//This way prevents weird artifacts from being created when using either of the methods
if (degrees(acos(dot(scaleDir.xyz, v.normal.xyz))) > _Angle) {
v.vertex.xyz += normalize(v.normal.xyz) * _SecondOutlineWidth;
}
else {
v.vertex.xyz += scaleDir * _SecondOutlineWidth;
}
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : COLOR{
return _SecondOutlineColor;
}
ENDCG
}
//Surface shader
Tags{ "Queue" = "Transparent" }
CGPROGRAM
#pragma surface surf Lambert noshadow
struct Input {
float2 uv_MainTex;
float4 color : COLOR;
};
void surf(Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Diffuse"
}