-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbspline.frag
127 lines (110 loc) · 3.5 KB
/
bspline.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
120
121
122
123
124
125
126
127
# version 300 es
#define MAX_POINTS 32
precision mediump float;
layout(std140) uniform Points {
//vec4 is 16 bytes, GPU screws up vec2
//and the half of our points magically disappear
vec4 points[MAX_POINTS];
};
uniform vec2 resolution;
uniform vec2 mouse;
uniform float time;
uniform float splineprecision;//amount of points to draw spline
//spline points length
uniform int count;
//index of selected point
uniform int mouseover;
out vec4 fragColor;
const float PI = 3.1415926535897932384626433832795;
vec3 hsv2rgb(float h, float s, float v) {
float f = mod(h / 60.0, 6.0);
float p = v * (1.0 - s);
float q = v * (1.0 - s * (f - floor(f)));
float t = v * (1.0 - s * (1.0 - (f - floor(f))));
if (f < 1.0) return vec3(v, t, p);
else if (f < 2.0) return vec3(q, v, p);
else if (f < 3.0) return vec3(p, v, t);
else if (f < 4.0) return vec3(p, q, v);
else if (f < 5.0) return vec3(t, p, v);
else return vec3(v, p, q);
}
vec4 ablend(vec4 a, vec4 b) {
return vec4(a.rgb + b.rgb * (1.0 - a.a), a.a + b.a * (1.0 - a.a));
}
void drawcircle(vec2 uv, vec2 pos, bool selected) {
float pixel = 1.0 / resolution.x;
vec2 delta = uv - pos;
float R = length(delta);
vec3 color = vec3(0, 0, 0);
if (selected == true) color = vec3(1, 0, 0);
if (R < pixel*15.0 && R > pixel*8.0)
fragColor = ablend(vec4(color, 1.0-R*70.0),fragColor);
}
void drawsquare(vec2 uv, vec2 pos, bool selected) {
float pixel = 1.0 / resolution.x;
vec2 delta = uv - pos;
bool R = abs(delta.x) < pixel*15.0 && abs(delta.y) < pixel*15.0;
R = R && !(abs(delta.x) < pixel*8.0 && abs(delta.y) < pixel*8.0);
vec3 color = vec3(0, 0, 0);
if (selected == true) color = vec3(1, 0, 0);
if (R == true)
fragColor = vec4(color, 1.0);
}
void drawline(vec2 uv, vec2 p0, vec2 p1, vec3 color) {
float pixel = 1.0 / resolution.x;
vec2 delta = uv - p0;
vec2 delta2 = p1 - p0;
float dotprod = dot(delta, delta2);
float seglen = dot(delta2, delta2);
if (dotprod >= 0.0 && dotprod <= seglen) {
float R = abs(delta.x * delta2.y - delta.y * delta2.x) / length(delta2);
float a = abs(R / pixel);
if (R < pixel*5.0)
fragColor = mix(vec4(color, 1.0),fragColor, a*.2);
}
}
vec2 bspline(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) {
vec2 q0 = mix(p0, p1, t);
vec2 q1 = mix(p1, p2, t);
vec2 q2 = mix(p2, p3, t);
vec2 r0 = mix(q0, q1, t);
vec2 r1 = mix(q1, q2, t);
return mix(r0, r1, t);
}
//get point from points array
vec2 getPoint(int index){
if(index < 0) return points[0].xy;
//4d to 2d lol
int halfindex = index/2;
//even - xy, odd - zw
if(index%2 == 0)
return points[halfindex].xy;
else
return points[halfindex].zw;
}
void main(){
// uv - current "texture" coordinate
vec2 uv = gl_FragCoord.xy / resolution.xy;
//hsv gradient background :)
vec2 center = vec2(0.5, 0.5);
vec2 delta = uv - center;
float r = length(delta);
float theta = atan(delta.y, delta.x);
float h = theta / (2.0 * PI) * 360.0;
float s = r*2.0;
float v = 1.0;
vec3 color = hsv2rgb(h, s, v);
fragColor = vec4(color, 1.0);
//mouse circle
drawcircle(uv, mouse, false);
//draw points
vec2 prev = points[0].xy;
for(int i=0;i<MAX_POINTS;i++){
//no more points
if(i>=count) break;
vec2 point = getPoint(i);
drawcircle(uv, point, i==i);
drawline(uv, prev, point, vec3(0,0,0));
prev = point;
}
}