dli_arc.fsh
3.24 KB
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
#version 300 es
#ifdef HIGHP
precision highp float;
#else
precision mediump float;
#endif
#define ROUND_STARTCAP 0x1
#define ROUND_ENDCAP 0x2
#define SQUARE_STARTCAP 0x4
#define SQUARE_ENDCAP 0x8
precision mediump float;
in vec2 vUV;
uniform vec4 uColor;
uniform int antiAliasing;
uniform float radius;
uniform vec2 startAngle;
uniform vec2 endAngle;
uniform int arcCaps;
out vec4 FragColor;
void main()
{
////////////////////
//Inputs
float radius1 = 1.0;
float uvPixel = length( dFdx( vUV ) ) * 2.0;
float dx = mix( 0.0001, uvPixel, antiAliasing > 0 );
float radius2 = mix( 1.0 - radius * uvPixel - dx , -radius , step( 0.0, -radius ) );
////////////////////
float alpha = 0.0;
float circle = 0.0;
vec2 uv = fract(vUV) * 2.0 - 1.0;
float ang_img = endAngle.y * startAngle.x - endAngle.x * startAngle.y;
float half1 = uv.x * startAngle.x - uv.y * startAngle.y;
float half2 = uv.y * endAngle.y - uv.x * endAngle.x;
float len = length(uv);
float equalAngles = step(0.99999, dot(endAngle, startAngle));
float right_side = step(0.0, ang_img);
vec2 uv_norm = normalize(uv);
float cap_radius = -0.5 + radius2 / 2.0;
float square_cap;
float sq_plane;
/******************************************
* Equivalent to:
* if( len > radius1 || len < radius2 )
*/
circle = alpha = smoothstep( len, len + dx, radius1 ) * smoothstep( -len, -len + dx, -radius2 );
float half1_step = smoothstep( -dx, 0.0, half1 );
float half2_step = smoothstep( -dx, 0.0, half2 );
float neg_angimg = max( half1_step, half2_step );
float pos_angimg = min( half1_step, half2_step );
/******************************************
* Equivalent to:
if(ang_img < 0.0)
{
alpha *= max(smoothstep( 0.0, dx, half1 ), smoothstep( 0.0, dx, half2));
}
else
{
alpha *= min(smoothstep( 0.0, dx, half1 ) , smoothstep( 0.0, dx, half2 ));
}
*/
alpha *= mix( neg_angimg, pos_angimg, step(0.0, ang_img) );
alpha = mix( alpha, mix( circle, 0.0, right_side ), equalAngles );
if((arcCaps & ROUND_STARTCAP) > 0)
{
len = length(uv - normalize( vec2( startAngle.y, startAngle.x )) * (1.0 + cap_radius));
alpha = max(alpha, smoothstep(cap_radius, cap_radius + dx, -len) );
}
if((arcCaps & ROUND_ENDCAP) > 0)
{
len = length(uv - normalize( vec2( endAngle.y, endAngle.x )) * (1.0 + cap_radius));
alpha = max(alpha, smoothstep(cap_radius, cap_radius + dx, -len) );
}
if((arcCaps & SQUARE_STARTCAP) > 0)
{
sq_plane = -uv.x * startAngle.y - uv.y * startAngle.x;
square_cap = min(step( 0.0, -half1 ), smoothstep( cap_radius, cap_radius + dx, half1 ));
square_cap = min(square_cap, smoothstep( radius2, radius2 + dx, -sq_plane ));
square_cap = min(square_cap, smoothstep( -1.0, -1.0 + dx, sq_plane ));
alpha = max(square_cap, alpha);
}
if((arcCaps & SQUARE_ENDCAP) > 0)
{
sq_plane = -uv.x * endAngle.y - uv.y * endAngle.x;
square_cap = min(step( 0.0, -half2 ), smoothstep( cap_radius, cap_radius + dx, half2 ));
square_cap = min(square_cap, smoothstep( radius2, radius2 + dx, -sq_plane ));
square_cap = min(square_cap, smoothstep( -1.0, -1.0 + dx, sq_plane ));
alpha = max(square_cap, alpha);
}
if( alpha == 0.0 )
{
discard;
}
FragColor = vec4(vec3(uColor), uColor.a * alpha);
}