mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-05-25 15:10:17 +09:00
1326 lines
32 KiB
GLSL
1326 lines
32 KiB
GLSL
#version 300 es
|
|
#define E (2.71828182846)
|
|
#define pi (3.14159265358979323844)
|
|
#define NUM_OCTAVES (4)
|
|
|
|
precision highp float;
|
|
|
|
struct ColoredSDF {
|
|
float distance;
|
|
vec4 color;
|
|
};
|
|
|
|
struct SDFArgs {
|
|
vec2 st;
|
|
float amount;
|
|
float duration;
|
|
float time;
|
|
float mainRadius;
|
|
};
|
|
|
|
float triangle(float t, float p) {
|
|
return 2.0 * abs(t / p - floor(t / p + 0.5));
|
|
}
|
|
|
|
float spring(float t, float d) {
|
|
return 1.0 - exp(-E * 2.0 * t) * cos((1.0 - d) * 115.0 * t);
|
|
}
|
|
|
|
float silkySmooth(float t, float k) {
|
|
return atan(k * sin((t - 0.5) * pi)) / atan(k) * 0.5 + 0.5;
|
|
}
|
|
|
|
float scaled(float edge0, float edge1, float x) {
|
|
return clamp((x - edge0) / (edge1 - edge0), float(0), float(1));
|
|
}
|
|
|
|
float fixedSpring(float t, float d) {
|
|
float s = mix(
|
|
1.0 - exp(-E * 2.0 * t) * cos((1.0 - d) * 115.0 * t),
|
|
1.0,
|
|
scaled(0.0, 1.0, t)
|
|
);
|
|
return s * (1.0 - t) + t;
|
|
}
|
|
|
|
float bounce(float t, float d) {
|
|
return -sin(pi * (1.0 - d) * t) *
|
|
(1.0 - t) *
|
|
exp(-2.71828182846 * 2.0 * t) *
|
|
t *
|
|
10.0;
|
|
}
|
|
|
|
float random(vec2 st) {
|
|
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
|
|
}
|
|
|
|
float random(ivec2 st) {
|
|
return random(vec2(st));
|
|
}
|
|
|
|
float random(float p) {
|
|
return random(vec2(p));
|
|
}
|
|
|
|
float opSmoothUnion(float d1, float d2, float k) {
|
|
if (k <= 0.0) {
|
|
k = 0.000001;
|
|
}
|
|
float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
|
|
return mix(d2, d1, h) - k * h * (1.0 - h);
|
|
}
|
|
|
|
float opSmoothSubtraction(float d1, float d2, float k) {
|
|
if (k <= 0.0) {
|
|
k = 0.000001;
|
|
}
|
|
float h = clamp(0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0);
|
|
return mix(d2, -d1, h) + k * h * (1.0 - h);
|
|
}
|
|
|
|
float opSmoothIntersection(float d1, float d2, float k) {
|
|
if (k <= 0.0) {
|
|
k = 0.000001;
|
|
}
|
|
float h = clamp(0.5 - 0.5 * (d2 - d1) / k, 0.0, 1.0);
|
|
return mix(d2, d1, h) + k * h * (1.0 - h);
|
|
}
|
|
|
|
float sdRoundedBox(vec2 p, vec2 b, vec4 r) {
|
|
r.xy = p.x > 0.0 ? r.xy : r.zw;
|
|
r.x = p.y > 0.0 ? r.x : r.y;
|
|
vec2 q = abs(p) - b + r.x;
|
|
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
|
|
}
|
|
|
|
float sdSegment(vec2 p, vec2 a, vec2 b) {
|
|
vec2 pa = p - a;
|
|
vec2 ba = b - a;
|
|
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
|
return length(pa - ba * h);
|
|
}
|
|
|
|
float sdArc(vec2 p, vec2 sca, vec2 scb, float ra, float rb) {
|
|
p *= mat2(sca.x, sca.y, -sca.y, sca.x);
|
|
p.x = abs(p.x);
|
|
return scb.y * p.x > scb.x * p.y
|
|
? length(p - ra * scb) - rb
|
|
: abs(length(p) - ra) - rb;
|
|
}
|
|
|
|
float arc(vec2 st, float startAngle, float length, float radius, float width) {
|
|
return sdArc(
|
|
st,
|
|
vec2(sin(startAngle), cos(startAngle)),
|
|
vec2(sin(length), cos(length)),
|
|
radius,
|
|
width
|
|
);
|
|
}
|
|
|
|
vec2 rotate(vec2 v, float a) {
|
|
float s = sin(a);
|
|
float c = cos(a);
|
|
mat2 m = mat2(c, s, -s, c);
|
|
return m * v;
|
|
}
|
|
|
|
vec3 blendLinearBurn_13_5(vec3 base, vec3 blend) {
|
|
|
|
return max(base + blend - vec3(1.0), vec3(0.0));
|
|
}
|
|
|
|
vec3 blendLinearBurn_13_5(vec3 base, vec3 blend, float opacity) {
|
|
return blendLinearBurn_13_5(base, blend) * opacity + base * (1.0 - opacity);
|
|
}
|
|
|
|
float blendScreen_21_19(float base, float blend) {
|
|
return 1.0 - (1.0 - base) * (1.0 - blend);
|
|
}
|
|
|
|
vec3 blendScreen_21_19(vec3 base, vec3 blend) {
|
|
return vec3(
|
|
blendScreen_21_19(base.r, blend.r),
|
|
blendScreen_21_19(base.g, blend.g),
|
|
blendScreen_21_19(base.b, blend.b)
|
|
);
|
|
}
|
|
|
|
vec3 blendScreen_21_19(vec3 base, vec3 blend, float opacity) {
|
|
return blendScreen_21_19(base, blend) * opacity + base * (1.0 - opacity);
|
|
}
|
|
|
|
vec4 permute(vec4 x) {
|
|
return mod((x * 34.0 + 1.0) * x, 289.0);
|
|
}
|
|
vec4 taylorInvSqrt(vec4 r) {
|
|
return 1.79284291400159 - 0.85373472095314 * r;
|
|
}
|
|
vec3 fade(vec3 t) {
|
|
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
|
}
|
|
|
|
float cnoise(vec3 P) {
|
|
vec3 Pi0 = floor(P);
|
|
vec3 Pi1 = Pi0 + vec3(1.0);
|
|
Pi0 = mod(Pi0, 289.0);
|
|
Pi1 = mod(Pi1, 289.0);
|
|
vec3 Pf0 = fract(P);
|
|
vec3 Pf1 = Pf0 - vec3(1.0);
|
|
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
|
|
vec4 iy = vec4(Pi0.yy, Pi1.yy);
|
|
vec4 iz0 = vec4(Pi0.z);
|
|
vec4 iz1 = vec4(Pi1.z);
|
|
|
|
vec4 ixy = permute(permute(ix) + iy);
|
|
vec4 ixy0 = permute(ixy + iz0);
|
|
vec4 ixy1 = permute(ixy + iz1);
|
|
|
|
vec4 gx0 = ixy0 / 7.0;
|
|
vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;
|
|
gx0 = fract(gx0);
|
|
vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
|
|
vec4 sz0 = step(gz0, vec4(0.0));
|
|
gx0 -= sz0 * (step(vec4(0.0), gx0) - 0.5);
|
|
gy0 -= sz0 * (step(vec4(0.0), gy0) - 0.5);
|
|
|
|
vec4 gx1 = ixy1 / 7.0;
|
|
vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;
|
|
gx1 = fract(gx1);
|
|
vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
|
|
vec4 sz1 = step(gz1, vec4(0.0));
|
|
gx1 -= sz1 * (step(vec4(0.0), gx1) - 0.5);
|
|
gy1 -= sz1 * (step(vec4(0.0), gy1) - 0.5);
|
|
|
|
vec3 g000 = vec3(gx0.x, gy0.x, gz0.x);
|
|
vec3 g100 = vec3(gx0.y, gy0.y, gz0.y);
|
|
vec3 g010 = vec3(gx0.z, gy0.z, gz0.z);
|
|
vec3 g110 = vec3(gx0.w, gy0.w, gz0.w);
|
|
vec3 g001 = vec3(gx1.x, gy1.x, gz1.x);
|
|
vec3 g101 = vec3(gx1.y, gy1.y, gz1.y);
|
|
vec3 g011 = vec3(gx1.z, gy1.z, gz1.z);
|
|
vec3 g111 = vec3(gx1.w, gy1.w, gz1.w);
|
|
|
|
vec4 norm0 = taylorInvSqrt(
|
|
vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))
|
|
);
|
|
g000 *= norm0.x;
|
|
g010 *= norm0.y;
|
|
g100 *= norm0.z;
|
|
g110 *= norm0.w;
|
|
vec4 norm1 = taylorInvSqrt(
|
|
vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))
|
|
);
|
|
g001 *= norm1.x;
|
|
g011 *= norm1.y;
|
|
g101 *= norm1.z;
|
|
g111 *= norm1.w;
|
|
|
|
float n000 = dot(g000, Pf0);
|
|
float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
|
|
float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
|
|
float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
|
|
float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
|
|
float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
|
|
float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
|
|
float n111 = dot(g111, Pf1);
|
|
|
|
vec3 fade_xyz = fade(Pf0);
|
|
vec4 n_z = mix(
|
|
vec4(n000, n100, n010, n110),
|
|
vec4(n001, n101, n011, n111),
|
|
fade_xyz.z
|
|
);
|
|
vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
|
|
float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
|
|
return 2.2 * n_xyz;
|
|
}
|
|
|
|
float rand(vec2 n) {
|
|
return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
|
|
}
|
|
|
|
float noise(vec2 p) {
|
|
vec2 ip = floor(p);
|
|
vec2 u = fract(p);
|
|
u = u * u * (3.0 - 2.0 * u);
|
|
|
|
float res = mix(
|
|
mix(rand(ip), rand(ip + vec2(1.0, 0.0)), u.x),
|
|
mix(rand(ip + vec2(0.0, 1.0)), rand(ip + vec2(1.0, 1.0)), u.x),
|
|
u.y
|
|
);
|
|
return res * res;
|
|
}
|
|
|
|
float fbm(vec2 x) {
|
|
float v = 0.0;
|
|
float a = 0.5;
|
|
vec2 shift = vec2(100.0);
|
|
|
|
mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.5));
|
|
for (int i = 0; i < NUM_OCTAVES; ++i) {
|
|
v += a * noise(x);
|
|
x = rot * x * 2.0 + shift;
|
|
a *= 0.5;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
#define HASHSCALE1 (0.1031)
|
|
#define HASHSCALE3 (vec3(0.1031, 0.103, 0.0973))
|
|
#define HASHSCALE4 (vec3(0.1031, 0.103, 0.0973, 0.1099))
|
|
|
|
float Hash11(float p) {
|
|
vec3 p3 = fract(vec3(p) * HASHSCALE1);
|
|
p3 += dot(p3, p3.yzx + 19.19);
|
|
return fract((p3.x + p3.y) * p3.z);
|
|
}
|
|
|
|
vec2 Hash22(vec2 p) {
|
|
vec3 p3 = fract(vec3(p.xyx) * HASHSCALE3);
|
|
p3 += dot(p3, p3.yzx + 19.19);
|
|
return fract((p3.xx + p3.yz) * p3.zy);
|
|
}
|
|
|
|
vec2 Rand22(vec2 co) {
|
|
float x = fract(sin(dot(co.xy, vec2(122.9898, 783.233))) * 43758.5453);
|
|
float y = fract(sin(dot(co.xy, vec2(457.6537, 537.2793))) * 37573.5913);
|
|
return vec2(x, y);
|
|
}
|
|
|
|
vec3 SnowSingleLayer(
|
|
vec2 uv,
|
|
float layer,
|
|
vec2 speed,
|
|
vec4 uCumulativeAudio,
|
|
float uTime
|
|
) {
|
|
uv = uv * (1.5 + layer);
|
|
float size = 0.01;
|
|
|
|
float xOffset =
|
|
uv.y * (((Hash11(layer) * 2.0 - 1.0) * 0.5 + 1.0) * speed.x) +
|
|
sin(
|
|
layer * 2963.0 + uCumulativeAudio.y * 0.05625 + uCumulativeAudio.z * 0.075
|
|
);
|
|
float yOffset =
|
|
speed.y + uTime * 1.75 + uCumulativeAudio.x * 0.07125 + cos(uTime) * 0.1;
|
|
xOffset += sin(uTime * 2.0 + uv.x + layer * 2938.0) * 0.25;
|
|
uv += vec2(xOffset, yOffset);
|
|
|
|
vec2 rgrid = Hash22(floor(uv) + 31.1759 * layer);
|
|
uv = fract(uv);
|
|
uv -= (rgrid * 2.0 - 1.0) * 0.35;
|
|
uv -= 0.5;
|
|
|
|
float r = length(uv);
|
|
|
|
float circleSize = 0.05 * (1.0 + 0.2 * sin(uTime * size + layer));
|
|
float val = smoothstep(circleSize, -circleSize, r);
|
|
val = smoothstep(0.0, 0.2, val);
|
|
|
|
vec3 col = vec3(val, val, val) * rgrid.x;
|
|
return col;
|
|
|
|
}
|
|
|
|
/**
|
|
* End new code for colored orb
|
|
*/
|
|
|
|
ColoredSDF applyIdleState(
|
|
ColoredSDF sdf,
|
|
SDFArgs args,
|
|
bool isDarkMode /**
|
|
* new bool
|
|
*/
|
|
) {
|
|
float midRadius = 0.12;
|
|
float maxRadius = 0.3;
|
|
float t1 = 1.0;
|
|
float gamma = 3.0;
|
|
float omega = pi / 2.0;
|
|
|
|
|
|
float k = exp(-gamma) * omega;
|
|
|
|
float radius;
|
|
if (args.time <= t1) {
|
|
|
|
float t_prime = args.time / t1;
|
|
|
|
float springValue = 1.0 - exp(-gamma * t_prime) * cos(omega * t_prime);
|
|
radius = midRadius * springValue;
|
|
} else {
|
|
|
|
float adjustedTime = args.time - t1;
|
|
|
|
radius =
|
|
midRadius + (maxRadius - midRadius) * (1.0 - exp(-k * adjustedTime));
|
|
}
|
|
|
|
|
|
float distance = length(args.st) - radius;
|
|
|
|
|
|
sdf.distance = mix(sdf.distance, distance, args.amount);
|
|
|
|
|
|
|
|
float alpha = sin(pi / 0.7 * args.time) * 0.3 + 0.7;
|
|
vec4 color = vec4(isDarkMode ? vec3(1.0) : vec3(0.0), alpha);
|
|
|
|
|
|
sdf.color = mix(sdf.color, color, args.amount);
|
|
|
|
return sdf;
|
|
}
|
|
|
|
ColoredSDF applyIdleStateLegacy(ColoredSDF sdf, SDFArgs args, bool isDarkMode) {
|
|
float connectedLinearAnimation = scaled(0.0, 2.0, args.duration);
|
|
float connectedAnimation = fixedSpring(connectedLinearAnimation, 0.96);
|
|
float circleSize =
|
|
mix(
|
|
pow(scaled(0.0, 3.0, args.time), 2.0) * 0.75 + 0.1,
|
|
1.0,
|
|
connectedAnimation
|
|
) *
|
|
0.33;
|
|
vec2 rotatedCoords = rotate(
|
|
args.st,
|
|
-args.time * pi -
|
|
connectedAnimation * pi * 2.0 -
|
|
pi * 2.0 * 5.0 * silkySmooth(scaled(0.0, 5.0, args.time), 2.0)
|
|
);
|
|
|
|
float strokeWidth = mix(circleSize / 2.0, circleSize, connectedAnimation);
|
|
float connecting = abs(length(args.st) - circleSize) - strokeWidth;
|
|
|
|
float connected = length(args.st) - circleSize;
|
|
float idleDist = mix(connecting, connected, connectedAnimation);
|
|
|
|
float d = min(sdf.distance, idleDist);
|
|
sdf.distance = mix(sdf.distance, d, args.amount);
|
|
float angle = atan(rotatedCoords.y, rotatedCoords.x);
|
|
float alpha = mix(
|
|
min(1.0, scaled(-pi, pi, angle)),
|
|
1.0,
|
|
connectedLinearAnimation
|
|
);
|
|
|
|
float spinningCircleDist =
|
|
length(
|
|
rotatedCoords -
|
|
vec2(-mix(circleSize, strokeWidth, connectedAnimation), 0.0)
|
|
) -
|
|
strokeWidth;
|
|
|
|
alpha = min(
|
|
1.0,
|
|
max(
|
|
alpha,
|
|
smoothstep(0.005, 0.0, spinningCircleDist) + connectedAnimation * 4.0
|
|
)
|
|
);
|
|
|
|
sdf.color = mix(
|
|
sdf.color,
|
|
vec4(isDarkMode ? vec3(1.0) : vec3(0.0), alpha),
|
|
args.amount
|
|
);
|
|
return sdf;
|
|
}
|
|
|
|
ColoredSDF applyListenState(
|
|
ColoredSDF sdf,
|
|
SDFArgs args,
|
|
float micLevel,
|
|
float listenTimestamp, /* new */
|
|
float touchDownTimestamp, /* new */
|
|
float touchUpTimestamp, /* new */
|
|
bool fadeBloopWhileListening /* new */
|
|
) {
|
|
float breathingSequence = sin(args.time) * 0.5 + 0.5;
|
|
float entryAnimation = fixedSpring(scaled(0.0, 3.0, args.duration), 0.9);
|
|
|
|
float touch =
|
|
fixedSpring(scaled(0.0, 1.0, args.time - touchDownTimestamp), 0.99) -
|
|
fixedSpring(scaled(0.0, 0.8, args.time - touchUpTimestamp), 1.0);
|
|
|
|
float listenAnimation = clamp(
|
|
spring(scaled(0.0, 0.9, args.duration), 1.0),
|
|
0.0,
|
|
1.0
|
|
);
|
|
float radius = 0.0;
|
|
float smoothlevel = micLevel;
|
|
float l1 = smoothlevel;
|
|
radius = 0.38 + l1 * 0.05 + breathingSequence * 0.03;
|
|
radius *= 1.0 - (1.0 - entryAnimation) * 0.25;
|
|
|
|
float ring = 10000.0;
|
|
|
|
|
|
if (touch > 0.0) {
|
|
touch = min(touch, listenAnimation);
|
|
float arcWidth = radius * 0.1;
|
|
|
|
|
|
radius -= touch * arcWidth * 2.3;
|
|
|
|
radius = min(
|
|
radius,
|
|
mix(radius, args.mainRadius - arcWidth * 2.3 - l1 * 0.01, touch)
|
|
);
|
|
|
|
float startAngle = 0.0;
|
|
float arcLengthTouch =
|
|
smoothstep(0.04, 1.0, touch) * pi * (1.0 - arcWidth / 3.0 / radius);
|
|
|
|
float arcLength = 0.0;
|
|
float radiusTouch =
|
|
radius * fixedSpring(scaled(0.0, 1.0, args.duration), 1.0) * args.amount +
|
|
l1 * 0.01;
|
|
|
|
radiusTouch +=
|
|
arcWidth * 1.3 * mix(-1.0, 1.0, smoothstep(0.0, 0.12, touch));
|
|
|
|
float ringRadius = 0.0;
|
|
arcLength = arcLengthTouch;
|
|
ringRadius = radiusTouch;
|
|
startAngle = pi / 2.0 - (args.time - touchDownTimestamp) / 2.0;
|
|
|
|
ring = arc(args.st, startAngle, arcLength, ringRadius, arcWidth);
|
|
}
|
|
|
|
float d = length(args.st) - radius;
|
|
|
|
d = min(d, ring);
|
|
|
|
sdf.distance = mix(sdf.distance, d, args.amount);
|
|
|
|
if (fadeBloopWhileListening) {
|
|
|
|
sdf.color.a = mix(
|
|
sdf.color.a,
|
|
mix(1.0, 1.0 - l1 * 0.6, listenAnimation),
|
|
args.amount
|
|
);
|
|
} else {
|
|
sdf.color.a = 1.0;
|
|
}
|
|
|
|
return sdf;
|
|
}
|
|
|
|
ColoredSDF applyThinkState(ColoredSDF sdf, SDFArgs args) {
|
|
float d = 1000.0;
|
|
int count = 5;
|
|
float entryAnimation = spring(scaled(0.0, 1.0, args.duration), 1.0);
|
|
|
|
float thinkingDotEntryAnimation = spring(
|
|
scaled(0.1, 1.1, args.duration),
|
|
1.0
|
|
);
|
|
float thinkingDotRadius =
|
|
mix(0.2, 0.06, thinkingDotEntryAnimation) * args.amount;
|
|
|
|
|
|
args.st.x -= thinkingDotRadius * 0.5 * thinkingDotEntryAnimation;
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
float f = float(float(i) + 0.5) / float(count);
|
|
float a =
|
|
-f * pi * 2.0 +
|
|
args.time / 3.0 +
|
|
spring(scaled(0.0, 10.0, args.duration), 1.0) * pi / 2.0;
|
|
float ringRadi = args.mainRadius * 0.45 * entryAnimation;
|
|
|
|
|
|
ringRadi -=
|
|
(sin(
|
|
entryAnimation * pi * 4.0 +
|
|
a * pi * 2.0 +
|
|
args.time * 3.0 -
|
|
silkySmooth(args.time / 4.0, 2.0) * pi * 1.0
|
|
) *
|
|
0.5 +
|
|
0.5) *
|
|
args.mainRadius *
|
|
0.1;
|
|
|
|
vec2 pos = vec2(cos(a), sin(a)) * ringRadi;
|
|
float dd = length(args.st - pos) - args.mainRadius * 0.5;
|
|
|
|
|
|
d = opSmoothUnion(
|
|
d,
|
|
dd,
|
|
0.03 * scaled(0.0, 10.0, args.duration) + 0.8 * (1.0 - entryAnimation)
|
|
);
|
|
|
|
|
|
float dotAngle = f * pi * 2.0;
|
|
float dotRingRadius =
|
|
(sin(
|
|
thinkingDotEntryAnimation * pi * 4.0 +
|
|
a * pi * 2.0 +
|
|
args.time * 0.1 * pi * 4.0
|
|
) *
|
|
0.5 +
|
|
0.5) *
|
|
thinkingDotRadius *
|
|
0.3;
|
|
vec2 dotPos =
|
|
vec2(-args.mainRadius, args.mainRadius) * 0.8 * thinkingDotEntryAnimation;
|
|
vec2 dotOffset =
|
|
vec2(cos(dotAngle + args.time), sin(dotAngle + args.time)) *
|
|
dotRingRadius;
|
|
float dotD = length(args.st - dotPos - dotOffset) - thinkingDotRadius * 0.8;
|
|
d = opSmoothUnion(
|
|
d,
|
|
dotD,
|
|
(1.0 - min(thinkingDotEntryAnimation, args.amount)) * thinkingDotRadius
|
|
);
|
|
}
|
|
sdf.distance = mix(sdf.distance, d, args.amount);
|
|
sdf.color.a = 1.0;
|
|
return sdf;
|
|
}
|
|
|
|
ColoredSDF applySpeakState(
|
|
ColoredSDF sdf,
|
|
SDFArgs args,
|
|
vec4 avgMag,
|
|
float silenceAmount,
|
|
float silenceDuration
|
|
) {
|
|
float d = 1000.0;
|
|
int barCount = 4;
|
|
for (int i = 0; i < barCount; i++) {
|
|
float f = float(float(i) + 0.5) / float(barCount);
|
|
|
|
|
|
float w = 1.0 / float(barCount) * 0.44;
|
|
float h = w;
|
|
|
|
|
|
float wave = sin(f * pi * 0.8 + args.time) * 0.5 + 0.5;
|
|
float entryAnimation = spring(
|
|
scaled(0.1 + wave * 0.4, 1.0 + wave * 0.4, args.duration),
|
|
0.98
|
|
);
|
|
vec2 pos = vec2(f - 0.5, 0.0) * args.mainRadius * 1.9;
|
|
pos.y = 0.25 * (1.0 - entryAnimation);
|
|
|
|
|
|
if (silenceAmount > 0.0) {
|
|
float bounceStagger = f / 5.0;
|
|
float bounceDelay = 0.6;
|
|
float bounceTimer = scaled(
|
|
bounceDelay,
|
|
bounceDelay + 1.0,
|
|
fract((silenceDuration + bounceStagger) / 2.0) * 2.0
|
|
);
|
|
pos.y +=
|
|
bounce(bounceTimer, 6.0) *
|
|
w *
|
|
0.25 *
|
|
silenceAmount *
|
|
pow(entryAnimation, 4.0) *
|
|
pow(args.amount, 4.0);
|
|
}
|
|
|
|
|
|
h += avgMag[i] * (0.1 + (1.0 - abs(f - 0.5) * 2.0) * 0.1);
|
|
|
|
float dd = sdRoundedBox(args.st - pos, vec2(w, h), vec4(w));
|
|
d = opSmoothUnion(d, dd, 0.2 * (1.0 - args.amount));
|
|
|
|
}
|
|
|
|
sdf.distance = mix(sdf.distance, d, args.amount);
|
|
sdf.color.a = 1.0;
|
|
return sdf;
|
|
}
|
|
|
|
ColoredSDF applyListenAndSpeakState(
|
|
ColoredSDF sdf,
|
|
SDFArgs args,
|
|
float micLevel,
|
|
vec4 avgMag,
|
|
vec4 cumulativeAudio,
|
|
int binCount,
|
|
vec3 bloopColorMain,
|
|
vec3 bloopColorLow,
|
|
vec3 bloopColorMid,
|
|
vec3 bloopColorHigh,
|
|
sampler2D uTextureNoise,
|
|
bool listening,
|
|
bool isAdvancedBloop,
|
|
float xmassMode
|
|
) {
|
|
float entryAnimation = fixedSpring(scaled(0.0, 2.0, args.duration), 0.92);
|
|
|
|
|
|
|
|
float radius =
|
|
(listening ? 0.37 : 0.43) * (1.0 - (1.0 - entryAnimation) * 0.25) +
|
|
micLevel * 0.065;
|
|
|
|
|
|
|
|
|
|
float maxDisplacement = 0.01;
|
|
|
|
|
|
float oscillationPeriod = 4.0;
|
|
|
|
float displacementOffset =
|
|
maxDisplacement * sin(2.0 * pi / oscillationPeriod * args.time);
|
|
|
|
vec2 adjusted_st = args.st - vec2(0.0, displacementOffset);
|
|
|
|
|
|
if (!isAdvancedBloop) {
|
|
sdf.color = mix(sdf.color, vec4(bloopColorMain, 1.0), args.amount);
|
|
sdf.distance = mix(sdf.distance, length(adjusted_st) - radius, args.amount);
|
|
return sdf;
|
|
}
|
|
|
|
|
|
|
|
vec4 uAudioAverage = avgMag;
|
|
vec4 uCumulativeAudio = cumulativeAudio;
|
|
|
|
|
|
float scaleFactor = 1.0 / (2.0 * radius);
|
|
vec2 uv = adjusted_st * scaleFactor + 0.5;
|
|
uv.y = 1.0 - uv.y;
|
|
vec3 color;
|
|
|
|
|
|
float noiseScale = 1.25;
|
|
float windSpeed = 0.075;
|
|
float warpPower = 0.19;
|
|
float waterColorNoiseScale = 18.0;
|
|
float waterColorNoiseStrength = 0.01;
|
|
float textureNoiseScale = 1.0;
|
|
float textureNoiseStrength = 0.08;
|
|
float verticalOffset = 0.09;
|
|
float waveSpread = 1.0;
|
|
float layer1Amplitude = 1.0;
|
|
float layer1Frequency = 1.0;
|
|
float layer2Amplitude = 1.0;
|
|
float layer2Frequency = 1.0;
|
|
float layer3Amplitude = 1.0;
|
|
float layer3Frequency = 1.0;
|
|
float fbmStrength = 1.0;
|
|
float fbmPowerDamping = 0.55;
|
|
float overallSoundScale = 1.0;
|
|
float blurRadius = 1.0;
|
|
float timescale = 1.0;
|
|
|
|
|
|
float time = args.time * timescale * 0.85;
|
|
|
|
|
|
noiseScale = mix(1.25, 2.0, xmassMode);
|
|
waterColorNoiseStrength = mix(0.01, 0.005, xmassMode);
|
|
textureNoiseStrength = mix(0.03, 0.01, xmassMode);
|
|
blurRadius = mix(0.9, 0.7, xmassMode);
|
|
verticalOffset = mix(0.09, 0.0, xmassMode);
|
|
layer1Amplitude = mix(1.0, 0.5, xmassMode);
|
|
layer1Frequency = mix(1.0, 0.5, xmassMode);
|
|
layer2Amplitude = mix(1.0, 0.5, xmassMode);
|
|
layer2Frequency = mix(1.0, 0.5, xmassMode);
|
|
layer3Amplitude = mix(1.0, 0.5, xmassMode);
|
|
layer3Frequency = mix(1.0, 0.5, xmassMode);
|
|
waveSpread = mix(1.0, 0.25, xmassMode);
|
|
overallSoundScale = mix(1.0, 1.2, xmassMode);
|
|
|
|
vec3 sinOffsets = vec3(
|
|
uCumulativeAudio.x * 0.15 * overallSoundScale,
|
|
-uCumulativeAudio.y * 0.5 * overallSoundScale,
|
|
uCumulativeAudio.z * 1.5 * overallSoundScale
|
|
);
|
|
verticalOffset += 1.0 - waveSpread;
|
|
|
|
|
|
vec3 sinOffsetsXmass = vec3(
|
|
uCumulativeAudio.x * 0.15 * overallSoundScale * 0.9,
|
|
-uCumulativeAudio.y * 0.5 * overallSoundScale * 0.1875,
|
|
uCumulativeAudio.z * 1.5 * overallSoundScale * 0.45
|
|
);
|
|
sinOffsets = mix(sinOffsets, sinOffsetsXmass, xmassMode);
|
|
|
|
|
|
float noiseX = cnoise(
|
|
vec3(
|
|
uv * 1.0 + vec2(0.0, 74.8572),
|
|
(time + uCumulativeAudio.x * 0.05 * overallSoundScale) * 0.3
|
|
)
|
|
);
|
|
float noiseY = cnoise(
|
|
vec3(
|
|
uv * 1.0 + vec2(203.91282, 10.0),
|
|
(time + uCumulativeAudio.z * 0.05 * overallSoundScale) * 0.3
|
|
)
|
|
);
|
|
|
|
vec2 uvBis = uv + vec2(noiseX * 2.0, noiseY) * warpPower * 0.25;
|
|
uv += vec2(noiseX * 2.0, noiseY) * warpPower;
|
|
|
|
|
|
float noiseA =
|
|
cnoise(vec3(uv * waterColorNoiseScale + vec2(344.91282, 0.0), time * 0.3)) +
|
|
cnoise(
|
|
vec3(uv * waterColorNoiseScale * 2.2 + vec2(723.937, 0.0), time * 0.4)
|
|
) *
|
|
0.5;
|
|
uv += noiseA * waterColorNoiseStrength;
|
|
uv.y -= verticalOffset;
|
|
|
|
|
|
vec2 textureUv = uv * textureNoiseScale;
|
|
float textureSampleR0 = texture(uTextureNoise, textureUv).r;
|
|
float textureSampleG0 = texture(
|
|
uTextureNoise,
|
|
vec2(textureUv.x, 1.0 - textureUv.y)
|
|
).g;
|
|
float textureNoiseDisp0 =
|
|
mix(
|
|
textureSampleR0 - 0.5,
|
|
textureSampleG0 - 0.5,
|
|
(sin(time + uCumulativeAudio.a * 2.0) + 1.0) * 0.5
|
|
) *
|
|
textureNoiseStrength;
|
|
textureUv += vec2(63.861 + uCumulativeAudio.x * 0.05, 368.937);
|
|
float textureSampleR1 = texture(uTextureNoise, textureUv).r;
|
|
float textureSampleG1 = texture(
|
|
uTextureNoise,
|
|
vec2(textureUv.x, 1.0 - textureUv.y)
|
|
).g;
|
|
float textureNoiseDisp1 =
|
|
mix(
|
|
textureSampleR1 - 0.5,
|
|
textureSampleG1 - 0.5,
|
|
(sin(time + uCumulativeAudio.a * 2.0) + 1.0) * 0.5
|
|
) *
|
|
textureNoiseStrength;
|
|
textureUv += vec2(272.861, 829.937 + uCumulativeAudio.y * 0.1);
|
|
textureUv += vec2(180.302 - uCumulativeAudio.z * 0.1, 819.871);
|
|
float textureSampleR3 = texture(uTextureNoise, textureUv).r;
|
|
float textureSampleG3 = texture(
|
|
uTextureNoise,
|
|
vec2(textureUv.x, 1.0 - textureUv.y)
|
|
).g;
|
|
float textureNoiseDisp3 =
|
|
mix(
|
|
textureSampleR3 - 0.5,
|
|
textureSampleG3 - 0.5,
|
|
(sin(time + uCumulativeAudio.a * 2.0) + 1.0) * 0.5
|
|
) *
|
|
textureNoiseStrength;
|
|
uv += textureNoiseDisp0;
|
|
|
|
|
|
vec2 st = uv * noiseScale;
|
|
|
|
vec2 q = vec2(0.0);
|
|
q.x = fbm(
|
|
st * 0.5 +
|
|
windSpeed * (time + uCumulativeAudio.a * 0.175 * overallSoundScale)
|
|
);
|
|
q.y = fbm(
|
|
st * 0.5 +
|
|
windSpeed * (time + uCumulativeAudio.x * 0.136 * overallSoundScale)
|
|
);
|
|
|
|
vec2 r = vec2(0.0);
|
|
r.x = fbm(
|
|
st +
|
|
1.0 * q +
|
|
vec2(0.3, 9.2) +
|
|
0.15 * (time + uCumulativeAudio.y * 0.234 * overallSoundScale)
|
|
);
|
|
r.y = fbm(
|
|
st +
|
|
1.0 * q +
|
|
vec2(8.3, 0.8) +
|
|
0.126 * (time + uCumulativeAudio.z * 0.165 * overallSoundScale)
|
|
);
|
|
|
|
float f = fbm(st + r - q);
|
|
float fullFbm = (f + 0.6 * f * f + 0.7 * f + 0.5) * 0.5;
|
|
fullFbm = pow(fullFbm, fbmPowerDamping);
|
|
fullFbm *= fbmStrength;
|
|
|
|
|
|
blurRadius = blurRadius * 1.5;
|
|
vec2 snUv =
|
|
(uv + vec2((fullFbm - 0.5) * 1.2) + vec2(0.0, 0.025) + textureNoiseDisp0) *
|
|
vec2(layer1Frequency, 1.0);
|
|
float sn =
|
|
noise(
|
|
snUv * 2.0 + vec2(sin(sinOffsets.x * 0.25), time * 0.5 + sinOffsets.x)
|
|
) *
|
|
2.0 *
|
|
layer1Amplitude;
|
|
float sn2 = smoothstep(
|
|
sn - 1.2 * blurRadius,
|
|
sn + 1.2 * blurRadius,
|
|
(snUv.y - 0.5 * waveSpread) *
|
|
(5.0 - uAudioAverage.x * 0.1 * overallSoundScale * 0.5) +
|
|
0.5
|
|
);
|
|
|
|
vec2 snUvBis =
|
|
(uv + vec2((fullFbm - 0.5) * 0.85) + vec2(0.0, 0.025) + textureNoiseDisp1) *
|
|
vec2(layer2Frequency, 1.0);
|
|
float snBis =
|
|
noise(
|
|
snUvBis * 4.0 +
|
|
vec2(
|
|
sin(sinOffsets.y * 0.15) * 2.4 + 293.0,
|
|
time * 1.0 + sinOffsets.y * 0.5
|
|
)
|
|
) *
|
|
2.0 *
|
|
layer2Amplitude;
|
|
float sn2Bis = smoothstep(
|
|
snBis - (0.9 + uAudioAverage.y * 0.4 * overallSoundScale) * blurRadius,
|
|
snBis + (0.9 + uAudioAverage.y * 0.8 * overallSoundScale) * blurRadius,
|
|
(snUvBis.y - 0.6 * waveSpread) * (5.0 - uAudioAverage.y * 0.75) + 0.5
|
|
);
|
|
|
|
vec2 snUvThird =
|
|
(uv + vec2((fullFbm - 0.5) * 1.1) + textureNoiseDisp3) *
|
|
vec2(layer3Frequency, 1.0);
|
|
float snThird =
|
|
noise(
|
|
snUvThird * 6.0 +
|
|
vec2(
|
|
sin(sinOffsets.z * 0.1) * 2.4 + 153.0,
|
|
time * 1.2 + sinOffsets.z * 0.8
|
|
)
|
|
) *
|
|
2.0 *
|
|
layer3Amplitude;
|
|
float sn2Third = smoothstep(
|
|
snThird - 0.7 * blurRadius,
|
|
snThird + 0.7 * blurRadius,
|
|
(snUvThird.y - 0.9 * waveSpread) * 6.0 + 0.5
|
|
);
|
|
|
|
sn2 = pow(sn2, 0.8);
|
|
sn2Bis = pow(sn2Bis, 0.9);
|
|
|
|
|
|
vec3 sinColor;
|
|
sinColor = blendLinearBurn_13_5(bloopColorMain, bloopColorLow, 1.0 - sn2);
|
|
sinColor = blendLinearBurn_13_5(
|
|
sinColor,
|
|
mix(bloopColorMain, bloopColorMid, 1.0 - sn2Bis),
|
|
sn2
|
|
);
|
|
sinColor = mix(
|
|
sinColor,
|
|
mix(bloopColorMain, bloopColorHigh, 1.0 - sn2Third),
|
|
sn2 * sn2Bis
|
|
);
|
|
|
|
|
|
color = sinColor;
|
|
|
|
|
|
float XSPEED = noise(vec2(time * 0.5, time * 0.1)) * 0.75;
|
|
float YSPEED = cos(time + uCumulativeAudio.y * 0.05) * 0.75;
|
|
|
|
vec2 wind = vec2(XSPEED, YSPEED);
|
|
|
|
vec3 acc = vec3(0, 0, 0);
|
|
for (float i = 0.0; i < 9.0; i++) {
|
|
acc += SnowSingleLayer(
|
|
uvBis,
|
|
i * 0.85 + 0.75,
|
|
wind,
|
|
uCumulativeAudio,
|
|
time
|
|
);
|
|
}
|
|
vec3 xmassColor;
|
|
xmassColor = mix(
|
|
vec3(0.004, 0.506, 0.996),
|
|
vec3(0.973, 0.984, 1.0),
|
|
1.0 - sn2
|
|
);
|
|
xmassColor = mix(
|
|
xmassColor,
|
|
mix(vec3(0.004, 0.506, 0.996), vec3(1.0), 1.0 - sn2Bis),
|
|
sn2
|
|
);
|
|
xmassColor = mix(
|
|
xmassColor,
|
|
mix(vec3(0.004, 0.506, 0.996), vec3(1.0), 1.0 - sn2Third),
|
|
sn2 * sn2Bis
|
|
);
|
|
xmassColor = mix(xmassColor, vec3(1.0), acc);
|
|
|
|
|
|
color.rgb = mix(color, xmassColor, xmassMode);
|
|
|
|
|
|
sdf.color = mix(sdf.color, vec4(color, 1), args.amount);
|
|
|
|
|
|
sdf.distance = mix(sdf.distance, length(adjusted_st) - radius, args.amount);
|
|
|
|
return sdf;
|
|
}
|
|
|
|
float micSdf(vec2 st, float muted) {
|
|
float d = 100.0;
|
|
float strokeWidth = 0.03;
|
|
vec2 elementSize = vec2(0.12, 0.26);
|
|
vec2 elementPos = vec2(0.0, elementSize.y * 0.585);
|
|
float element = sdRoundedBox(
|
|
st - elementPos,
|
|
elementSize,
|
|
vec4(min(elementSize.x, elementSize.y))
|
|
);
|
|
element = element - strokeWidth;
|
|
d = min(d, element);
|
|
|
|
vec2 standSize = elementSize * 2.2;
|
|
vec2 standPos = vec2(elementPos.x, elementPos.y - 0.05);
|
|
st.y += 0.08;
|
|
float ta = -pi / 2.0;
|
|
float tb = pi / 2.0;
|
|
float w = 0.0;
|
|
float stand = sdArc(
|
|
st - standPos,
|
|
vec2(sin(ta), cos(ta)),
|
|
vec2(sin(tb), cos(tb)),
|
|
standSize.x,
|
|
w
|
|
);
|
|
stand = min(
|
|
stand,
|
|
sdSegment(st - standPos, vec2(standSize.x, 0.06), vec2(standSize.x, 0.0))
|
|
);
|
|
stand = min(
|
|
stand,
|
|
sdSegment(st - standPos, vec2(-standSize.x, 0.06), vec2(-standSize.x, 0.0))
|
|
);
|
|
|
|
float foot = sdSegment(
|
|
st - standPos,
|
|
vec2(0.0, -standSize.x),
|
|
vec2(0.0, -standSize.x * 1.66)
|
|
);
|
|
foot = min(
|
|
foot,
|
|
sdSegment(
|
|
st - standPos,
|
|
vec2(-standSize.x * 0.68, -standSize.x * 1.66),
|
|
vec2(standSize.x * 0.68, -standSize.x * 1.66)
|
|
)
|
|
);
|
|
stand = min(stand, foot);
|
|
|
|
d = min(d, abs(stand) - strokeWidth);
|
|
|
|
return d;
|
|
}
|
|
|
|
ColoredSDF applyBottomAlignedBarsAndMicState(
|
|
ColoredSDF sdf,
|
|
SDFArgs args,
|
|
vec4 avgMag,
|
|
float micLevel,
|
|
bool isDarkMode
|
|
) {
|
|
float d = 1000.0;
|
|
int barCount = 5;
|
|
int loopCount = barCount;
|
|
if (args.amount == 0.0) {
|
|
loopCount = 1;
|
|
}
|
|
for (int i = 0; i < loopCount; i++) {
|
|
float f = float(float(i) + 0.5) / float(barCount);
|
|
|
|
|
|
float w = 1.0 / float(barCount) * 0.42;
|
|
float h = w;
|
|
|
|
|
|
float entryDuration = 1.8;
|
|
float entryAnimation =
|
|
fixedSpring(scaled(0.0, entryDuration, args.duration), 0.94) *
|
|
args.amount;
|
|
vec2 pos = vec2(f - 0.5, 0.0) * args.mainRadius * 1.9;
|
|
pos.x *= entryAnimation;
|
|
|
|
if (i == 0) {
|
|
float micScale = mix(6.0 - micLevel * 2.0, 6.0, args.amount);
|
|
float yOffset = w * 2.0;
|
|
d =
|
|
micSdf(
|
|
(args.st - pos + vec2(-w * 0.15 * args.amount, yOffset)) * micScale,
|
|
1.0 - args.amount
|
|
) /
|
|
micScale;
|
|
} else {
|
|
|
|
h += avgMag[i - 1] * (0.1 + (1.0 - abs(f - 0.5) * 2.0) * 0.1) * 0.7;
|
|
h = mix(w, h, smoothstep(0.8, 1.0, entryAnimation));
|
|
|
|
float bubbleInDur = 0.5;
|
|
float bubbleOutDur = 0.4;
|
|
|
|
|
|
float bubbleEffect =
|
|
fixedSpring(
|
|
scaled(
|
|
f / 4.0,
|
|
f / 4.0 + bubbleInDur,
|
|
args.duration - entryDuration / 8.0
|
|
),
|
|
1.0
|
|
) *
|
|
pow(
|
|
1.0 -
|
|
scaled(
|
|
f / 8.0 + bubbleInDur / 8.0,
|
|
f / 4.0 + bubbleInDur / 8.0 + bubbleOutDur,
|
|
args.duration - entryDuration / 8.0
|
|
),
|
|
2.0
|
|
);
|
|
|
|
h += bubbleEffect * min(h, w);
|
|
|
|
|
|
w *= args.amount;
|
|
h *= args.amount;
|
|
|
|
h = min(h, 0.23);
|
|
|
|
pos.y -= 0.25;
|
|
pos.y += h;
|
|
pos.y += bubbleEffect * w * 0.5;
|
|
|
|
float dd = sdRoundedBox(args.st - pos, vec2(w, h), vec4(w));
|
|
d = min(d, dd);
|
|
}
|
|
}
|
|
|
|
sdf.distance = d;
|
|
sdf.color = mix(
|
|
sdf.color,
|
|
isDarkMode
|
|
? vec4(1.0)
|
|
: vec4(0.0, 0.0, 0.0, 1.0),
|
|
args.amount
|
|
);
|
|
return sdf;
|
|
}
|
|
|
|
ColoredSDF applyHaltState(ColoredSDF sdf, SDFArgs args) {
|
|
|
|
float radius = mix(
|
|
0.4,
|
|
mix(0.4, 0.45, args.amount),
|
|
sin(args.time * 0.25) * 0.5 + 0.5
|
|
);
|
|
float strokeWidth = mix(radius / 2.0, 0.02, args.amount);
|
|
|
|
|
|
radius -= strokeWidth;
|
|
|
|
radius *= mix(0.7, 1.0, args.amount);
|
|
float circle = abs(length(args.st) - radius) - strokeWidth;
|
|
|
|
sdf.distance = mix(sdf.distance, circle, args.amount);
|
|
sdf.color.a = mix(sdf.color.a, pow(0.8, 2.2), scaled(0.5, 1.0, args.amount));
|
|
return sdf;
|
|
}
|
|
|
|
vec3 blendNormal(vec3 base, vec3 blend) {
|
|
return blend;
|
|
}
|
|
|
|
vec3 blendNormal(vec3 base, vec3 blend, float opacity) {
|
|
return blendNormal(base, blend) * opacity + base * (1.0 - opacity);
|
|
}
|
|
|
|
in vec2 out_uv;
|
|
out vec4 fragColor;
|
|
|
|
layout(std140) uniform BlorbUniformsObject {
|
|
float time;
|
|
float micLevel;
|
|
float touchDownTimestamp;
|
|
float touchUpTimestamp;
|
|
float stateListen;
|
|
float listenTimestamp;
|
|
float stateThink;
|
|
float thinkTimestamp;
|
|
float stateSpeak;
|
|
float speakTimestamp;
|
|
float readyTimestamp;
|
|
float stateHalt;
|
|
float haltTimestamp;
|
|
float stateFailedToConnect;
|
|
float failedToConnectTimestamp;
|
|
vec4 avgMag;
|
|
vec4 cumulativeAudio;
|
|
vec2 viewport;
|
|
float screenScaleFactor;
|
|
float silenceAmount;
|
|
float silenceTimestamp;
|
|
float xmassMode;
|
|
bool isDarkMode;
|
|
bool fadeBloopWhileListening;
|
|
bool isNewBloop;
|
|
bool isAdvancedBloop;
|
|
vec3 bloopColorMain;
|
|
vec3 bloopColorLow;
|
|
vec3 bloopColorMid;
|
|
vec3 bloopColorHigh;
|
|
} ubo;
|
|
|
|
uniform sampler2D uTextureNoise;
|
|
|
|
void main() {
|
|
vec2 st = out_uv - 0.5;
|
|
float viewRatio = ubo.viewport.y / ubo.viewport.x;
|
|
st.y *= viewRatio;
|
|
|
|
ColoredSDF sdf;
|
|
sdf.distance = 1000.0;
|
|
sdf.color = vec4(1.0);
|
|
|
|
SDFArgs args;
|
|
args.st = st;
|
|
args.time = ubo.time;
|
|
args.mainRadius = 0.49;
|
|
|
|
SDFArgs idleArgs = args;
|
|
SDFArgs listenArgs = args;
|
|
SDFArgs thinkArgs = args;
|
|
SDFArgs speakArgs = args;
|
|
SDFArgs haltArgs = args;
|
|
SDFArgs failedToConnectArgs = args;
|
|
|
|
idleArgs.amount = 1.0;
|
|
listenArgs.amount = ubo.stateListen;
|
|
thinkArgs.amount = ubo.stateThink;
|
|
speakArgs.amount = ubo.stateSpeak;
|
|
haltArgs.amount = ubo.stateHalt;
|
|
failedToConnectArgs.amount = ubo.stateFailedToConnect;
|
|
|
|
idleArgs.duration = ubo.time - ubo.readyTimestamp;
|
|
listenArgs.duration = ubo.time - ubo.listenTimestamp;
|
|
thinkArgs.duration = ubo.time - ubo.thinkTimestamp;
|
|
speakArgs.duration = ubo.time - ubo.speakTimestamp;
|
|
haltArgs.duration = ubo.time - ubo.haltTimestamp;
|
|
failedToConnectArgs.duration = ubo.time - ubo.failedToConnectTimestamp;
|
|
|
|
if (ubo.isNewBloop) {
|
|
sdf = applyIdleState(sdf, idleArgs, ubo.isDarkMode);
|
|
} else {
|
|
sdf = applyIdleStateLegacy(sdf, idleArgs, ubo.isDarkMode);
|
|
}
|
|
|
|
if (failedToConnectArgs.amount > 0.0) {
|
|
sdf = applyHaltState(sdf, failedToConnectArgs);
|
|
}
|
|
|
|
if (listenArgs.amount > 0.0) {
|
|
if (ubo.isAdvancedBloop) {
|
|
if (speakArgs.amount > 0.0) {
|
|
listenArgs.amount = 1.0;
|
|
}
|
|
|
|
|
|
int binCount = 1;
|
|
sdf = applyListenAndSpeakState(
|
|
sdf,
|
|
listenArgs,
|
|
ubo.micLevel,
|
|
ubo.avgMag,
|
|
ubo.cumulativeAudio,
|
|
binCount,
|
|
ubo.bloopColorMain,
|
|
ubo.bloopColorLow,
|
|
ubo.bloopColorMid,
|
|
ubo.bloopColorHigh,
|
|
uTextureNoise,
|
|
true,
|
|
ubo.isAdvancedBloop,
|
|
ubo.xmassMode
|
|
);
|
|
} else {
|
|
sdf = applyListenState(
|
|
sdf,
|
|
listenArgs,
|
|
ubo.micLevel,
|
|
ubo.listenTimestamp,
|
|
ubo.touchDownTimestamp,
|
|
ubo.touchUpTimestamp,
|
|
ubo.fadeBloopWhileListening
|
|
);
|
|
}
|
|
}
|
|
|
|
if (thinkArgs.amount > 0.0) {
|
|
sdf = applyThinkState(sdf, thinkArgs);
|
|
}
|
|
|
|
if (speakArgs.amount > 0.0) {
|
|
if (ubo.isAdvancedBloop) {
|
|
int binCount = 1;
|
|
sdf = applyListenAndSpeakState(
|
|
sdf,
|
|
speakArgs,
|
|
ubo.micLevel,
|
|
ubo.avgMag,
|
|
ubo.cumulativeAudio,
|
|
binCount,
|
|
ubo.bloopColorMain,
|
|
ubo.bloopColorLow,
|
|
ubo.bloopColorMid,
|
|
ubo.bloopColorHigh,
|
|
uTextureNoise,
|
|
false,
|
|
ubo.isAdvancedBloop,
|
|
ubo.xmassMode
|
|
);
|
|
} else {
|
|
float silenceDuration = ubo.time - ubo.silenceTimestamp;
|
|
sdf = applySpeakState(
|
|
sdf,
|
|
speakArgs,
|
|
ubo.avgMag,
|
|
ubo.silenceAmount,
|
|
silenceDuration
|
|
);
|
|
}
|
|
}
|
|
|
|
if (haltArgs.amount > 0.0) {
|
|
sdf = applyHaltState(sdf, haltArgs);
|
|
}
|
|
|
|
float clampingTolerance = 0.0075 / ubo.screenScaleFactor;
|
|
float clampedShape = smoothstep(clampingTolerance, 0.0, sdf.distance);
|
|
float alpha = sdf.color.a * clampedShape;
|
|
if (!ubo.isNewBloop) {
|
|
alpha *= scaled(0.0, 1.0, ubo.time);
|
|
}
|
|
fragColor = vec4(sdf.color.rgb * alpha, alpha);
|
|
} |