Files
Cool-shaders-and-stuff/shaders/pendulum.frag
2026-01-13 19:27:55 +00:00

75 lines
2.1 KiB
GLSL

#version 100
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
// Constants
#define PI 3.14159265359
#define G 9.81
#define L1 1.0
#define L2 1.0
#define M1 1.0
#define M2 1.0
#define DT 0.05
#define ITERATIONS 100
void main() {
// Map pixel to initial angles (-PI to PI)
vec2 uv = (gl_FragCoord.xy / u_resolution.xy) * 2.0 - 1.0;
float t1 = uv.x * PI;
float t2 = uv.y * PI;
// Initial velocities
float v1 = 0.0;
float v2 = 0.0;
// Previous angles for Verlet or just simple Euler/RK4
// Using semi-implicit Euler for stability/simplicity in shader
float flip_time = -1.0;
// Animate gravity to make it breathe? Or length?
float g = G + sin(u_time * 0.5) * 2.0;
for (int i = 0; i < ITERATIONS; i++) {
float num1 = -g * (2.0 * M1 + M2) * sin(t1);
float num2 = -M2 * g * sin(t1 - 2.0 * t2);
float num3 = -2.0 * sin(t1 - t2) * M2;
float num4 = v2 * v2 * L2 + v1 * v1 * L1 * cos(t1 - t2);
float den = L1 * (2.0 * M1 + M2 - M2 * cos(2.0 * t1 - 2.0 * t2));
float a1 = (num1 + num2 + num3 * num4) / den;
num1 = 2.0 * sin(t1 - t2);
num2 = (v1 * v1 * L1 * (M1 + M2));
num3 = g * (M1 + M2) * cos(t1);
num4 = v2 * v2 * L2 * M2 * cos(t1 - t2);
den = L2 * (2.0 * M1 + M2 - M2 * cos(2.0 * t1 - 2.0 * t2));
float a2 = (num1 * (num2 + num3 + num4)) / den;
v1 += a1 * DT;
v2 += a2 * DT;
t1 += v1 * DT;
t2 += v2 * DT;
// Dampening? No, chaotic system usually conservative (or we want to see chaos)
// Check for flip (crossing PI)
if (abs(t1) > PI || abs(t2) > PI) {
flip_time = float(i) / float(ITERATIONS);
break;
}
}
vec3 col = vec3(0.0);
if (flip_time > 0.0) {
// Did flip
col = vec3(0.2 + 0.8 * flip_time, 0.5 * flip_time, 1.0 - flip_time);
} else {
// Did not flip (stableish)
col = vec3(0.1, 0.1, 0.2);
}
gl_FragColor = vec4(col, 1.0);
}