39 lines
1.2 KiB
GLSL
39 lines
1.2 KiB
GLSL
#version 450 core
|
|
layout(location=0) out vec4 oColor;
|
|
|
|
layout(std140, binding=0) uniform PerFrame { mat4 uView; mat4 uProj; vec4 uLightDir; };
|
|
layout(std140, binding=2) uniform Material { vec4 uAlbedo; };
|
|
|
|
layout(location=0) in VS_OUT {
|
|
vec3 wPos;
|
|
vec2 uv;
|
|
} v;
|
|
|
|
// geometric normal from screen-space derivatives of the *world* position
|
|
vec3 normal_from_worldpos(vec3 w){
|
|
vec3 dx = dFdx(w), dy = dFdy(w);
|
|
vec3 n = cross(dx,dy);
|
|
float l2 = dot(n,n);
|
|
return (l2 < 1e-12) ? vec3(0,0,1) : normalize(n);
|
|
}
|
|
|
|
void main(){
|
|
vec3 N = normal_from_worldpos(v.wPos);
|
|
vec3 L = normalize(-uLightDir.xyz);
|
|
float ndl = max(dot(N,L), 0.0);
|
|
|
|
// cheap color: height-based gradient + slight darkening by slope
|
|
float h = v.wPos.z; // world height
|
|
float h01 = clamp(h * 0.1 + 0.5, 0.0, 1.0); // remap height to 0..1
|
|
vec3 low = vec3(0.35, 0.38, 0.40); // rock/soil
|
|
vec3 high = vec3(0.65, 0.75, 0.60); // grass
|
|
vec3 base = mix(low, high, h01);
|
|
|
|
float slope = 1.0 - abs(N.z); // 0 = flat up, 1 = vertical
|
|
base *= mix(1.0, 0.8, slope); // darker on steep slopes
|
|
|
|
vec3 ambient = vec3(0.08);
|
|
vec3 color = ambient + base * (uAlbedo.rgb * ndl);
|
|
|
|
oColor = vec4(color, 1.0);
|
|
} |