#version 330 core
precision highp float;

// Pyramid look for osmium: harsh two-tone (almost black or almost white) directional
// lighting, animated film grain whose amount is driven by the beat, and a per-fragment
// alpha so the monument reads as a translucent layer over the beat-synced background.

in vec2 ex_Uv;
in vec3 ex_Normal;
out vec4 fragColor;

uniform sampler2D uTex;   // sandstone diffuse (used only as subtle detail)
uniform vec3 uLightDir;   // direction the light travels
uniform float uAlpha;     // base layer alpha (wobbled with the beat on the CPU side)
uniform float uNoise;     // grain amplitude (reacts to the beat on the CPU side)
uniform float uTime;      // track time in seconds (animates the grain)


float hash(vec2 p)
{
	p = fract(p * vec2(123.34, 456.21));
	p += dot(p, p + 45.32);
	return fract(p.x * p.y);
}


void main()
{
	vec3 n = normalize(ex_Normal);
	vec3 l = normalize(-uLightDir);
	float lambert = max(dot(n, l), 0.0);

	// Harsh: collapse the shading to almost black or almost white with a hard edge.
	float lit = smoothstep(0.46, 0.54, lambert);
	float shade = mix(0.02, 0.98, lit);

	// A hint of sandstone detail, without breaking the two-tone.
	float tex = texture(uTex, ex_Uv).r;
	shade *= mix(1.0, tex, 0.35);

	// Animated grain; the beat pushes the amplitude (uNoise) up.
	float g = hash(gl_FragCoord.xy + vec2(uTime * 137.0, uTime * 91.0)) * 2.0 - 1.0;
	shade += g * uNoise;

	shade = clamp(shade, 0.0, 1.0);
	fragColor = vec4(vec3(shade), uAlpha);
}
