

#include "/lib/ssr/ssr_common.glsl"

#include "/lib/specular.glsl"
#if SSR_QUALITY == 1
const bool colortex6MipmapEnabled = true;
#endif
vec3 computeReflections(
    float skylight, float roughness, vec3 f0, vec3 albedo, float shading, vec3 normal, vec3 p3, vec3 scene)
{
    vec3 np3 = normalize(p3);
    // roughness = 0;
    // Determine if the material is metallic
    bool isMetal = (f0.y * 255.0) > 229.0;
    f0 = CalculateF0(f0, isMetal, int(f0.y * 255.0), albedo);

    // Compute specular term
    vec3 specular = shading * GGX2(normal, -np3, lightPos, roughness, f0) * pow(skylight, 3.0) * sunLight;
#if SSR_QUALITY == 1
    if (length(f0) == 0)
    {
        return scene + specular;
    }

    float lod = mix(3, 8.0, roughness);

    // Compute view direction
    vec3 tangent = max(normalize(vec3(-normal.y, normal.x, 0.0)), -1.0);
    vec3 bitangent = cross(normal, tangent);
    vec3 viewDir = normalize(vec3(
        dot(-np3, tangent),
        dot(-np3, bitangent),
        dot(-np3, normal)));

    // Compute reflected direction
    vec2 p2 = viewDir.xy * roughness;
    vec2 perp2 = vec2(-p2.y, p2.x) / length(p2);
    float dither = cos(6.2831 * R2_dither(gl_FragCoord.xy));
    vec3 halfway = normalize(vec3(roughness * (0.5 * p2 + 0.6667 * perp2 * dither), max(0.0, 0.1 + viewDir.z)));
    vec3 reflectedDir = reflect(-viewDir, halfway);

    // Compute light direction and Fresnel
    //   mat3 basis = CoordBase(normal);
    //  vec3 normSpaceView = normalize(-np3 * basis);

    //    vec3 L = basis * reflect(-normSpaceView, SampleGGXVNDF2(normSpaceView, roughness, blueNoise(gl_FragCoord.xy)));

    vec3 L = reflectedDir.x * tangent + reflectedDir.y * bitangent + reflectedDir.z * normal;
    float NoL = max(dot(normal, L), 0.0);
    vec3 F = f0 + (1.0 - f0) * pow(clamp(1.0 + dot(-reflectedDir, halfway), 0.0, 1.0), 5.0);
    vec3 rayContrib = F * (NoL / (NoL * (1.0 - roughness * roughness * 0.5) + roughness * roughness * 0.5));

    // Sky and reflection contributions
    vec3 sky = skyFromTexLod(L, colortex6, lod).rgb + sunLight * skyFromTexLod(L, colortex6, lod).a;
    // sky *= clamp(L.y * 0.5 + 0.5, 0.0, 1.0);

    vec3 reflectionColor = mix(scene, sky, clamp(L.y + 0.25, 0.0, 1.0)) * pow(skylight, 3.0);
    vec3 indirectSpecular = reflectionColor * rayContrib;

    // Compute final output
    vec3 effectiveAlbedo = isMetal ? albedo : vec3(1.0);
    vec3 diffuse = isMetal ? vec3(0.0) : vec3(1.0) - rayContrib;

    // return sky;
    return (indirectSpecular + specular + diffuse * scene) * effectiveAlbedo;
#else
    return scene + specular;
#endif
}