
/*
====================================================================================================

    Copyright (C) 2025 Pyvtron VX Shaders - Pyvton

    All Rights Reserved unless otherwise explicitly stated.

    Before You Do Something With Pyvtron VX Shaders, You MUST Read This:

    You Must Read The License: https://pyvton.pages.dev/minecraft-shaders/pyvtron-shaders-license
    And Read The Agreement: https://pyvton.pages.dev/minecraft-shaders/pyvtron-shaders-agreement

====================================================================================================
*/

mat2 mm2(in float b) {
    float d = cos(b);
    float e = sin(b);
    return mat2(d, e, -e, d);
}

const mat2 m2 = mat2(.95534, .29552, -.29552, .95534);

float tri(in float f) {
    return clamp(abs(fract(f) - .5), .01, .49);
}

vec2 tri2(in vec2 g) {
    return vec2(tri(g.x) + tri(g.y), tri(g.y + tri(g.x)));
}

float triNoise2d(in vec2 h, float j) {
    float k = 1.8;
    float l = 2.5;
    float m = .0;

    h *= mm2(h.x * .06);
    vec2 o = h;

    for (float q = .0; q < AURORA_RESOLUTION; q++) {
        vec2 r = tri2(o * 3.85) * .75;
        r *= mm2(frameTimeCounter * j);
        h -= r / l;

        o *= 1.3;
        l *= .45;
        k *= .42;

        float s = tri(h.x + tri(h.y));
        m += s * k;

        h *= 1.21 - .002;
        h *= -m2;
    }
    return clamp(1. / pow(m * 29., 1.3), .0, .55);
}


float hash21(in vec2 t) {
    return fract(sin(dot(t, vec2(12.9898, 4.1414))) * 43758.5453);
}

vec4 aurora(vec3 u, vec3 v) {
    vec4 w = vec4(.0);
    vec4 z = vec4(.0);
    float A = hash21(gl_FragCoord.xy);
    for (float B = .0; B < AURORA_LENGTH; B++) {
        float C = smoothstep(.0, 15., B);
        float D = .006 * A * C;
        float E = ((AURORA_DISTANCE + pow(B, 1.4) * .002) - u.y) / (v.y * 2. + .4);
        E -= D;
        vec3 F = u + E * v;
        vec2 G = F.zx;
        float H = triNoise2d(G, .1883);
        float I = B * .1 + frameTimeCounter * .5;
        vec4 J = vec4(
            .5 + .5 * sin(I),
            .5 + .5 * sin(I + 2.094),
            .5 + .5 * sin(I + 4.188),
            H
        );
        J.rgb *= H;
        z = mix(z, J, .5);
        w += z * exp2(-B * .065 - 2.5) * smoothstep(.0, 5., B);
    }
    w *= clamp(v.y * 15. + .4, .0, 1.);
    return w * AURORA_INTENSITY;
}

uniform float isCold;

void NightAurora(inout vec3 K, vec3 L) {
    vec3 M = normalize(L);
    float N = dot(M, upVector);
    vec3 O = normalize(upPosition);
    vec3 P = (gbufferModelViewInverse * vec4(L, 1.)).xyz;

    vec3 Q = normalize(P);
    vec3 R = Q * (50. / Q.y);
    R *= mix(1., N, .70 - N);

    R.xz = R.xz * 40. + 5. * N * R.xz;
    vec3 S = (gbufferModelView * vec4(R, 1.)).xyz;
    float T = max(dot(normalize(S), O), .0);

    float U = dot(normalize(L), upPosition);
    float V = max(1. - abs(U) * .03, .0);
    float W = min((1. - clamp(U + length(U), .0, 1.)) + V, 1.);

    vec3 X = vec3(.0);
    vec3 Y = vec3(.0);
    vec3 Z = R / 12392.;
    float ab = smoothstep(.0, .01, abs(Z.y)) * .1 + .9;

    vec4 cb = smoothstep(.0, 1.5, aurora(Y, Z)) * ab;

    X = X * (1. - cb.a) + cb.rgb * pow(T, .18) * (1. - W);

    X = pow(X, vec3(1.5)) * 2.;

    float eb = 1.;
    #ifdef AURORA_ONLY_IN_SNOW_BIOME
        eb = isCold;
    #endif

    K += X * .4 * AURORA_STRENGTH * timeMidnight * (1. - wetness * .75) * eb;
}
