/*
====================================================================
  SXGG: Realis — Shader ultra-realistica per Minecraft
  Autore : Samax.GG
  File   : lib/common.glsl
  Scopo  : Costanti, layout G-Buffer, ricostruzione posizioni,
           encoding blockId, dithering.
====================================================================
*/

#ifndef COMMON_GLSL
#define COMMON_GLSL

const float PI      = 3.14159265358979;
const float TAU     = 6.28318530717959;
const float EPSILON = 1e-5;

/*
------------------------------------------------------------------
  LAYOUT G-BUFFER (MRT)
------------------------------------------------------------------
  colortex0 : scena HDR (albedo nei gbuffers, luce dal deferred in poi)
  colortex1 : normale world *0.5+0.5     | POM self-shadow
  colortex2 : lightmap.xy | blockId enc. | AO (vertex*texture)
  colortex3 : specular map LabPBR raw
  colortex4 : bloom (composite1/2)
------------------------------------------------------------------
*/

float luminance(vec3 color) {
    return dot(color, vec3(0.2126, 0.7152, 0.0722));
}

float saturate(float x)  { return clamp(x, 0.0, 1.0); }
vec2  saturate(vec2  x)  { return clamp(x, 0.0, 1.0); }
vec3  saturate(vec3  x)  { return clamp(x, 0.0, 1.0); }

// ----- Encoding blockId (10000..11023 -> [0,1]) -----
float encodeBlockId(float id) { return (id - 10000.0 + 0.5) / 1024.0; }
float decodeBlockId(float x)  { return floor(x * 1024.0) + 10000.0; }
bool  isBlockId(float encoded, float id) {
    return abs(decodeBlockId(encoded) - id) < 0.5;
}

// ----- Normale LabPBR (texture _n): RG = XY, Z ricostruita -----
vec3 decodeLabNormal(vec4 normalTex) {
    vec3 n;
    n.xy = normalTex.xy * 2.0 - 1.0;
    n.z  = sqrt(saturate(1.0 - dot(n.xy, n.xy)));
    return normalize(n);
}

// ----- Ricostruzione posizione view-space dal depth buffer -----
vec3 screenToView(vec2 uv, float depth, mat4 projInverse) {
    vec4 pos = projInverse * vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
    return pos.xyz / pos.w;
}

// ----- View -> screen (per SSR / god rays) -----
vec3 viewToScreen(vec3 viewPos, mat4 proj) {
    vec4 clip = proj * vec4(viewPos, 1.0);
    return (clip.xyz / clip.w) * 0.5 + 0.5;
}

// ----- Profondità lineare -----
float linearizeDepth(float depth, float near, float far) {
    return (2.0 * near) / (far + near - depth * (far - near));
}

// ----- Interleaved gradient noise: dithering per i raymarch -----
float ign(vec2 coord) {
    return fract(52.9829189 * fract(dot(coord, vec2(0.06711056, 0.00583715))));
}

#endif // COMMON_GLSL
