forked from lettier/3d-game-shaders-for-beginners
-
Notifications
You must be signed in to change notification settings - Fork 1
/
outline.frag
119 lines (89 loc) · 2.7 KB
/
outline.frag
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
/*
(C) 2019 David Lettier
lettier.com
*/
#version 150
uniform vec2 gamma;
uniform sampler2D positionTexture;
uniform sampler2D colorTexture;
uniform sampler2D noiseTexture;
uniform sampler2D depthOfFieldTexture;
uniform sampler2D fogTexture;
uniform vec2 nearFar;
uniform vec2 enabled;
out vec4 fragColor;
void main() {
float minSeparation = 1.0;
float maxSeparation = 1.0;
float minDistance = 1.5;
float maxDistance = 2.0;
float noiseScale = 1.0;
int size = 1;
vec3 colorModifier = vec3(0.522, 0.431, 0.349);
colorModifier = pow(colorModifier, vec3(gamma.x));
float near = nearFar.x;
float far = nearFar.y;
vec2 fragCoord = gl_FragCoord.xy;
vec2 texSize = textureSize(colorTexture, 0).xy;
vec2 texCoord = fragCoord / texSize;
vec4 color = texture(colorTexture, texCoord);
float depthOfField = texture(depthOfFieldTexture, texCoord).r;
float fog = texture(fogTexture, texCoord).a;
if (enabled.x != 1) { fragColor = color; return; }
fragColor = vec4(0.0);
vec2 noise = texture(noiseTexture, fragCoord / textureSize(noiseTexture, 0).xy).rb;
noise = noise * 2.0 - 1.0;
noise *= noiseScale;
texCoord = (fragCoord - noise) / texSize;
vec4 position = texture(positionTexture, texCoord);
vec4 positionTemp = position;
if (position.a <= 0.0) { position.y = far; }
float depth =
clamp
( 1.0
- ( (far - position.y)
/ (far - near)
)
, 0.0
, 1.0
);
float separation = mix(maxSeparation, minSeparation, depth);
float count = 1.0;
float mx = 0.0;
for (int i = -size; i <= size; ++i) {
for (int j = -size; j <= size; ++j) {
texCoord =
(vec2(i, j) * separation + (fragCoord + noise))
/ texSize;
positionTemp =
texture
( positionTexture
, texCoord
);
if (positionTemp.y <= 0.0) { positionTemp.y = far; }
mx = max(mx, abs(position.y - positionTemp.y));
depthOfField =
max
( texture
( depthOfFieldTexture
, texCoord
).r
, depthOfField
);
fog +=
texture
( fogTexture
, texCoord
).a;
count += 1.0;
}
}
depthOfField = 1.0 - clamp(depthOfField, 0.0, 1.0);
fog = 1.0 - clamp(fog / count, 0.0, 1.0);
float diff = smoothstep(minDistance, maxDistance, mx) * depthOfField * fog;
texCoord = fragCoord / texSize;
vec3 lineColor = texture(colorTexture, texCoord).rgb;
lineColor *= colorModifier;
fragColor.rgb = mix(color.rgb, lineColor, clamp(diff, 0.0, 1.0));
fragColor.a = 1.0;
}