-
Notifications
You must be signed in to change notification settings - Fork 2
/
outline.shader
228 lines (193 loc) · 6.09 KB
/
outline.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
Shader "Unite-2019/Outline"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
Tags{ "RenderType" = "Opaque" }
LOD 200
ZTest Always
ZWrite Off
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _OutlineSource;
struct v2f
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_img v)
{
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float _LineThicknessX;
float _LineThicknessY;
int _FlipY;
uniform float4 _MainTex_TexelSize;
half4 frag(v2f input) : COLOR
{
float2 uv = input.uv;
if (_FlipY == 1)
uv.y = uv.y;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1 - uv.y;
#endif
//half4 originalPixel = tex2D(_MainTex,input.uv, UnityStereoScreenSpaceUVAdjust(input.uv, _MainTex_ST));
half4 outlineSource = tex2D(_OutlineSource, UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST));
const float h = .95f;
half4 sample1 = tex2D(_OutlineSource, uv + float2(_LineThicknessX,0.0));
half4 sample2 = tex2D(_OutlineSource, uv + float2(-_LineThicknessX,0.0));
half4 sample3 = tex2D(_OutlineSource, uv + float2(.0,_LineThicknessY));
half4 sample4 = tex2D(_OutlineSource, uv + float2(.0,-_LineThicknessY));
bool red = sample1.r > h || sample2.r > h || sample3.r > h || sample4.r > h;
bool green = sample1.g > h || sample2.g > h || sample3.g > h || sample4.g > h;
bool blue = sample1.b > h || sample2.b > h || sample3.b > h || sample4.b > h;
if ((red && blue) || (green && blue) || (red && green))
return float4(0,0,0,0);
else
return outlineSource;
}
ENDCG
}
Pass
{
Tags { "RenderType"="Opaque" }
LOD 200
ZTest Always
ZWrite Off
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _OutlineSource;
struct v2f {
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_img v)
{
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float _LineThicknessX;
float _LineThicknessY;
float _LineIntensity;
half4 _LineColor1;
half4 _LineColor2;
half4 _LineColor3;
int _FlipY;
int _Dark;
float _FillAmount;
int _CornerOutlines;
uniform float4 _MainTex_TexelSize;
half4 frag (v2f input) : COLOR
{
float2 uv = input.uv;
if (_FlipY == 1)
uv.y = 1 - uv.y;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1 - uv.y;
#endif
half4 originalPixel = tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(input.uv, _MainTex_ST));
half4 outlineSource = tex2D(_OutlineSource, UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST));
const float h = .95f;
half4 outline = 0;
bool hasOutline = false;
half4 sample1 = tex2D(_OutlineSource, uv + float2(_LineThicknessX,0.0));
half4 sample2 = tex2D(_OutlineSource, uv + float2(-_LineThicknessX,0.0));
half4 sample3 = tex2D(_OutlineSource, uv + float2(.0,_LineThicknessY));
half4 sample4 = tex2D(_OutlineSource, uv + float2(.0,-_LineThicknessY));
bool outside = outlineSource.a < h;
bool outsideDark = outside && _Dark;
if (_CornerOutlines)
{
// TODO: Conditional compile
half4 sample5 = tex2D(_OutlineSource, uv + float2(_LineThicknessX, _LineThicknessY));
half4 sample6 = tex2D(_OutlineSource, uv + float2(-_LineThicknessX, -_LineThicknessY));
half4 sample7 = tex2D(_OutlineSource, uv + float2(_LineThicknessX, -_LineThicknessY));
half4 sample8 = tex2D(_OutlineSource, uv + float2(-_LineThicknessX, _LineThicknessY));
if (sample1.r > h || sample2.r > h || sample3.r > h || sample4.r > h ||
sample5.r > h || sample6.r > h || sample7.r > h || sample8.r > h)
{
outline = _LineColor1 * _LineIntensity * _LineColor1.a;
if (outsideDark)
originalPixel *= 1 - _LineColor1.a;
hasOutline = true;
}
else if (sample1.g > h || sample2.g > h || sample3.g > h || sample4.g > h ||
sample5.g > h || sample6.g > h || sample7.g > h || sample8.g > h)
{
outline = _LineColor2 * _LineIntensity * _LineColor2.a;
if (outsideDark)
originalPixel *= 1 - _LineColor2.a;
hasOutline = true;
}
else if (sample1.b > h || sample2.b > h || sample3.b > h || sample4.b > h ||
sample5.b > h || sample6.b > h || sample7.b > h || sample8.b > h)
{
outline = _LineColor3 * _LineIntensity * _LineColor3.a;
if (outsideDark)
originalPixel *= 1 - _LineColor3.a;
hasOutline = true;
}
if (!outside)
outline *= _FillAmount;
}
else
{
if (sample1.r > h || sample2.r > h || sample3.r > h || sample4.r > h)
{
outline = _LineColor1 * _LineIntensity * _LineColor1.a;
if (outsideDark)
originalPixel *= 1 - _LineColor1.a;
hasOutline = true;
}
else if (sample1.g > h || sample2.g > h || sample3.g > h || sample4.g > h)
{
outline = _LineColor2 * _LineIntensity * _LineColor2.a;
if (outsideDark)
originalPixel *= 1 - _LineColor2.a;
hasOutline = true;
}
else if (sample1.b > h || sample2.b > h || sample3.b > h || sample4.b > h)
{
outline = _LineColor3 * _LineIntensity * _LineColor3.a;
if (outsideDark)
originalPixel *= 1 - _LineColor3.a;
hasOutline = true;
}
if (!outside)
outline *= _FillAmount;
}
//return outlineSource;
if (hasOutline)
return lerp(originalPixel + outline, outline, _FillAmount);
else
return originalPixel;
}
ENDCG
}
}
FallBack "Diffuse"
}