86 lines
2.5 KiB
GLSL
86 lines
2.5 KiB
GLSL
#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);
|
|
}
|
|
|