// Neon psychedelic colors
vec3 NeonPsychedelicColor(float t) {
    return vec3(
        0.5 + 0.5 * sin(6.0 * t + 2.0),
        0.5 + 0.5 * sin(6.0 * t + 1.0),
        0.5 + 0.5 * sin(6.0 * t + 3.0)
    );
}

// Saw function
float saw(float x) {
    return mod(abs(x), 2.0) - 1.0;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy;
    vec3 p = vec3(uv, 0.0) * 2.0 - 1.0;
    p.z = (sqrt(2.0) - length(p.xy)) / sqrt(2.0);

    float audioInput = texture(iChannel0, vec2(0.5, 0.5)).r * 2.0 - 1.0;
    float rotation = audioInput * 0.5;
    float scaling = audioInput * 0.1 + 1.0;

    for (int i = 0; i < 8; i++) {
        p.xz = mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)) * p.xz;
        p.xy *= scaling;

        p = vec3(
            saw(p.x + iTime),
            saw(p.y + iTime),
            saw(p.z + iTime)
        );

        p = normalize(p) * length(p);
    }

    float time = iTime * 1.0 + audioInput * 0.5;
    float spread = sin(time) * 0.2;

    vec3 col = NeonPsychedelicColor(length(p + spread));
    fragColor = vec4(col, 1.0);
}
