#version 330 // Input from vertex shader in vec3 fragPosition; in vec3 fragNormal; in vec2 fragTexCoord; // Uniforms uniform sampler2D texture0; uniform vec3 viewPos; uniform vec3 lightDir; uniform vec3 lightColor; uniform float lightIntensity; uniform float ambientIntensity; uniform vec3 terrainColor; // Output out vec4 finalColor; // Simplex noise for AO calculation float hash(float n) { return fract(sin(n) * 43758.5453123); } float noise(vec3 p) { vec3 i = floor(p); vec3 f = fract(p); f = f * f * (3.0 - 2.0 * f); float n = i.x + i.y * 157.0 + i.z * 113.0; return mix( mix(mix(hash(n), hash(n + 1.0), f.x), mix(hash(n + 157.0), hash(n + 158.0), f.x), f.y), mix(mix(hash(n + 113.0), hash(n + 114.0), f.x), mix(hash(n + 270.0), hash(n + 271.0), f.x), f.y), f.z ); } // Calculate ambient occlusion with more contrast float calculateAO(vec3 position, vec3 normal) { // Sample 8 directions around the surface float ao = 0.0; float radius = 2.5; int samples = 8; for (int i = 0; i < samples; i++) { float angle = 6.28318530718 * float(i) / float(samples); vec3 offset = vec3(cos(angle) * radius, noise(position * 0.5 + float(i)), sin(angle) * radius); // Sample height variation (approximated via noise) float heightVariation = noise((position + offset) * 0.3); // Calculate occlusion based on height and normal float dotProduct = max(0.0, dot(normal, normalize(offset))); ao += mix(0.0, dotProduct * heightVariation, 0.7); } // Increased contrast: 0.8 multiplier instead of 0.6 ao = 1.0 - (ao / float(samples)) * 0.8; // Min 0.1 (darker shadows) instead of 0.2 return max(0.1, ao); } void main() { // Normalize interpolated normal vec3 norm = normalize(fragNormal); // Use normal Y component to create geometry-revealing green shading // Higher Y normal (upward-facing) = brighter green (peaks/flat areas) // Lower Y normal (sloped) = darker green (slopes/valleys) float brightness = (norm.y + 1.0) * 0.5; // Map -1..1 to 0..1 // Increase contrast: darker minimum, brighter maximum // Old range: 0.4 to 1.0 (0.6 total range) // New range: 0.2 to 1.2 (1.0 total range) - much more contrast float contrastMultiplier = 0.2 + brightness * 1.0; // Create base terrain color modulated by geometry vec3 baseColor = terrainColor; vec3 finalColorRGB = baseColor * contrastMultiplier; finalColor = vec4(finalColorRGB, 1.0); }