@@ -15,44 +15,46 @@ uniform vec4 foregroundColor;
15
15
uniform float backgroundOpacity;
16
16
uniform float foregroundOpacity;
17
17
18
+ uniform float fade;
19
+
18
20
vec2 iResolution;
19
21
20
- float getAve(vec2 uv){
22
+ float getAve(vec2 uv) {
21
23
vec3 rgb = texture(tex0, uv).rgb;
22
24
vec3 lum = vec3 (0.299 , 0.587 , 0.114 );
23
25
return dot (lum, rgb);
24
26
}
25
27
26
28
// Detect edge.
27
- vec4 sobel(vec2 fragCoord, vec2 dir){
28
- vec2 uv = fragCoord/ iResolution.xy;
29
- vec2 texel = 1 ./ iResolution.xy;
30
- float np = getAve(uv + (vec2 (- 1 ,+ 1 ) + dir ) * texel * thickness);
31
- float zp = getAve(uv + (vec2 ( 0 , + 1 ) + dir ) * texel * thickness);
32
- float pp = getAve(uv + (vec2 (+ 1 , + 1 ) + dir ) * texel * thickness);
33
-
34
- float nz = getAve(uv + (vec2 (- 1 , 0 ) + dir ) * texel * thickness);
29
+ vec4 sobel(vec2 fragCoord, vec2 dir) {
30
+ vec2 uv = fragCoord / iResolution.xy;
31
+ vec2 texel = 1 . / iResolution.xy;
32
+ float np = getAve(uv + (vec2 (- 1 , + 1 ) + dir) * texel * thickness);
33
+ float zp = getAve(uv + (vec2 (0 , + 1 ) + dir) * texel * thickness);
34
+ float pp = getAve(uv + (vec2 (+ 1 , + 1 ) + dir) * texel * thickness);
35
+
36
+ float nz = getAve(uv + (vec2 (- 1 , 0 ) + dir) * texel * thickness);
35
37
// zz = 0
36
- float pz = getAve(uv + (vec2 (+ 1 , 0 ) + dir ) * texel * thickness);
38
+ float pz = getAve(uv + (vec2 (+ 1 , 0 ) + dir) * texel * thickness);
37
39
38
- float nn = getAve(uv + (vec2 (- 1 ,- 1 ) + dir ) * texel * thickness);
39
- float zn = getAve(uv + (vec2 ( 0 , - 1 ) + dir ) * texel * thickness);
40
- float pn = getAve(uv + (vec2 (+ 1 , - 1 ) + dir ) * texel * thickness);
40
+ float nn = getAve(uv + (vec2 (- 1 , - 1 ) + dir) * texel * thickness);
41
+ float zn = getAve(uv + (vec2 (0 , - 1 ) + dir) * texel * thickness);
42
+ float pn = getAve(uv + (vec2 (+ 1 , - 1 ) + dir) * texel * thickness);
41
43
42
44
// np zp pp
43
45
// nz zz pz
44
46
// nn zn pn
45
47
46
48
#if 0
47
- float gx = (np* -1 . + nz* -2 . + nn* -1 . + pp* 1 . + pz* 2 . + pn* 1 .);
48
- float gy = (np* -1 . + zp* -2 . + pp* -1 . + nn* 1 . + zn* 2 . + pn* 1 .);
49
+ float gx = (np * - 1 . + nz * - 2 . + nn * - 1 . + pp * 1 . + pz * 2 . + pn * 1 .);
50
+ float gy = (np * - 1 . + zp * - 2 . + pp * - 1 . + nn * 1 . + zn * 2 . + pn * 1 .);
49
51
#else
50
52
// https://www.shadertoy.com/view/Wds3Rl
51
- float gx = (np* -3 . + nz* -10 . + nn* -3 . + pp* 3 . + pz* 10 . + pn* 3 .);
52
- float gy = (np* -3 . + zp* -10 . + pp* -3 . + nn* 3 . + zn* 10 . + pn* 3 .);
53
+ float gx = (np * - 3 . + nz * - 10 . + nn * - 3 . + pp * 3 . + pz * 10 . + pn * 3 .);
54
+ float gy = (np * - 3 . + zp * - 10 . + pp * - 3 . + nn * 3 . + zn * 10 . + pn * 3 .);
53
55
#endif
54
56
55
- vec2 G = vec2 (gx,gy);
57
+ vec2 G = vec2 (gx, gy);
56
58
57
59
float grad = length (G);
58
60
@@ -62,49 +64,53 @@ vec4 sobel(vec2 fragCoord, vec2 dir){
62
64
}
63
65
64
66
// Make edge thinner.
65
- vec2 hysteresisThr(vec2 fragCoord, float mn, float mx){
67
+ vec2 hysteresisThr(vec2 fragCoord, float mn, float mx) {
66
68
67
69
vec4 edge = sobel(fragCoord, vec2 (0 ));
68
70
69
71
vec2 dir = vec2 (cos (edge.w), sin (edge.w));
70
- dir *= vec2 (- 1 ,1 ); // rotate 90 degrees.
72
+ dir *= vec2 (- 1 , 1 ); // rotate 90 degrees.
71
73
72
74
vec4 edgep = sobel(fragCoord, dir);
73
75
vec4 edgen = sobel(fragCoord, - dir);
74
76
75
- if (edge.z < edgep.z || edge.z < edgen.z ) edge.z = 0 .;
77
+ if (edge.z < edgep.z || edge.z < edgen.z) edge.z = 0 .;
76
78
77
79
return vec2 (
78
- (edge.z > mn) ? edge.z : 0 .,
79
- (edge.z > mx) ? edge.z : 0 .
80
+ (edge.z > mn) ? edge.z : 0 .,
81
+ (edge.z > mx) ? edge.z : 0 .
80
82
);
81
83
}
82
84
83
- float cannyEdge(vec2 fragCoord, float mn, float mx){
85
+ float cannyEdge(vec2 fragCoord, float mn, float mx) {
84
86
85
- vec2 np = hysteresisThr(fragCoord + vec2 (- 1 ,+ 1 ), mn, mx);
86
- vec2 zp = hysteresisThr(fragCoord + vec2 ( 0 , + 1 ), mn, mx);
87
- vec2 pp = hysteresisThr(fragCoord + vec2 (+ 1 , + 1 ), mn, mx);
87
+ vec2 np = hysteresisThr(fragCoord + vec2 (- 1 , + 1 ), mn, mx);
88
+ vec2 zp = hysteresisThr(fragCoord + vec2 (0 , + 1 ), mn, mx);
89
+ vec2 pp = hysteresisThr(fragCoord + vec2 (+ 1 , + 1 ), mn, mx);
88
90
89
91
vec2 nz = hysteresisThr(fragCoord + vec2 (- 1 , 0 ), mn, mx);
90
- vec2 zz = hysteresisThr(fragCoord + vec2 ( 0 , 0 ), mn, mx);
91
- vec2 pz = hysteresisThr(fragCoord + vec2 (+ 1 , 0 ), mn, mx);
92
+ vec2 zz = hysteresisThr(fragCoord + vec2 (0 , 0 ), mn, mx);
93
+ vec2 pz = hysteresisThr(fragCoord + vec2 (+ 1 , 0 ), mn, mx);
92
94
93
- vec2 nn = hysteresisThr(fragCoord + vec2 (- 1 ,- 1 ), mn, mx);
94
- vec2 zn = hysteresisThr(fragCoord + vec2 ( 0 , - 1 ), mn, mx);
95
- vec2 pn = hysteresisThr(fragCoord + vec2 (+ 1 , - 1 ), mn, mx);
95
+ vec2 nn = hysteresisThr(fragCoord + vec2 (- 1 , - 1 ), mn, mx);
96
+ vec2 zn = hysteresisThr(fragCoord + vec2 (0 , - 1 ), mn, mx);
97
+ vec2 pn = hysteresisThr(fragCoord + vec2 (+ 1 , - 1 ), mn, mx);
96
98
97
99
// np zp pp
98
100
// nz zz pz
99
101
// nn zn pn
100
102
// return min(1., step(1e-3, zz.x) * (zp.y + nz.y + pz.y + zn.y)*8.);
101
103
// return min(1., step(1e-3, zz.x) * (np.y + pp.y + nn.y + pn.y)*8.);
102
- return min (1 ., step (1e-2 , zz.x* 8 .) * smoothstep (.0 , .3 , np.y + zp.y + pp.y + nz.y + pz.y + nn.y + zn.y + pn.y)* 8 .);
104
+ return min (1 ., step (1e-2 , zz.x * 8 .) * smoothstep (.0 , .3 , np.y + zp.y + pp.y + nz.y + pz.y + nn.y + zn.y + pn.y) * 8 .);
103
105
}
104
106
105
- void main(){
107
+ void main() {
106
108
iResolution = vec2 (textureSize(tex0, 0 ));
109
+ vec4 original = texture(tex0, v_texCoord0);
107
110
vec2 fragCoord = v_texCoord0 * iResolution;
108
111
float edge = cannyEdge(fragCoord, threshold0, threshold1);
109
- o_output = mix (foregroundColor * foregroundOpacity, backgroundColor * backgroundOpacity, 1 .-edge);
112
+ o_output = mix (original,
113
+ mix (foregroundColor * foregroundOpacity,
114
+ backgroundColor * backgroundOpacity, 1 . - edge),
115
+ fade);
110
116
}
0 commit comments