-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrid.vert
134 lines (114 loc) · 3.42 KB
/
grid.vert
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
#version 460 core
out float alpha;
uniform mat4 mvp;
uniform int axis;
uniform float viewX;
uniform float viewZ;
uniform float radius;
uniform float radiusFadeStart;
uniform float invR1;
uniform float invR2MinusInvR1;
uniform float lineInfo[6];
uniform int bodiesSize;
struct Body {
int type;
float radius;
vec4 pos;
};
layout(std430, binding = 0) buffer Bodies
{
Body bodies[];
};
// The inverse of the integral(x, d) function in Grid.c. This is NOT the derivative.
// After we linearly interpolate between the integral1 and integral2 initial values,
// we use this function to transform the integral value to a positional value. This
// will cause the positions to be arranged with a density of 1/sqrt(x^2+d^2).
float inverseIntegral(float x) {
const float distance = lineInfo[3];
return distance * sinh(x);
}
float planetWarp(float x2, float r) {
r *= 3.0;
float r2 = r * r;
x2 /= r2;
float x4 = x2 * x2;
float sr = 1.2 * r;
if (abs(x2) < 1.0) {
return sr * (0.5 * (1.0 / (x2 + 1.0) + 1.0 / (x4 + 1.0)) + 0.25) * 0.8;
} else {
return sr * 6.0 / (5.0 * (x2 + 1.0));
}
}
float starWarp(float x2, float r) {
r *= 3.0;
float r2 = r * r;
x2 /= r2;
float x4 = x2 * x2;
float sr = 1.2 * r;
if (abs(x2) < 1.0) {
return sr * (0.5 * (1.0 / (x2 + 1.0) + 1.0 / (x4 + 1.0)) + 0.25) * 0.8;
} else {
return sr * 6.0 / (5.0 * (x2 + 1.0));
}
}
float blackHoleWarp(float x2, float r) {
r *= 15.0;
float r2 = r * r;
x2 /= r2;
return r / x2;
}
float warp(vec2 pos) {
float sum = 0.0;
for (int i = 0; i < bodiesSize; i++) {
Body body = bodies[i];
vec2 diff = pos - body.pos.xz;
float x2 = dot(diff, diff);
switch (body.type) {
case 0:
sum -= planetWarp(x2, body.radius);
break;
case 1:
sum -= starWarp(x2, body.radius);
break;
case 2:
sum -= blackHoleWarp(x2, body.radius);
break;
}
}
return sum;
}
void main() {
const float pos = lineInfo[0];
const float integral1 = lineInfo[1];
const float integral21 = lineInfo[2];
const float distance = lineInfo[3];
const float oneOverN = lineInfo[4];
const float lineAlpha = lineInfo[5];
// Interpolate linearly between integral1 and integral2, where integral21 is (integral2 - integral1)
// Then, take the inverse of the integral to get vertex positions. This results in the vertices being
// denser when they are closer to the camera.
float value = inverseIntegral(integral1 + integral21 * gl_VertexID * oneOverN);
vec3 vPos = vec3(0.0, 0.0, 0.0);
switch (axis) {
case 0: // X axis
value += viewX;
vPos.x = value;
vPos.z = pos;
break;
case 1: // Z axis
value += viewZ;
vPos.x = pos;
vPos.z = value;
break;
}
vPos.y = warp(vec2(vPos.x, vPos.z));
float vAlpha = 1.0;
float distToView = length(vec2(viewX - vPos.x, viewZ - vPos.z));
if (distToView > radiusFadeStart) {
float frac = (1.0 / distToView - invR1) / invR2MinusInvR1;
vAlpha = smoothstep(1.0, 0.0, frac);
}
vAlpha *= lineAlpha;
gl_Position = mvp * vec4(vPos, 1.0);
alpha = vAlpha;
}