34 lines
1.3 KiB
GLSL
34 lines
1.3 KiB
GLSL
#version 460 core
|
||
|
||
layout(location = 0) out vec4 color;
|
||
in vec4 vColor;
|
||
in vec3 vNormal;
|
||
in vec3 vPosition;
|
||
|
||
void main() {
|
||
vec3 lightDirection = normalize(vec3(0.8, -0.5, 0.6));
|
||
// ambient component
|
||
float ambientStrength = 0.1;
|
||
vec3 ambient = ambientStrength * vColor.rgb;
|
||
// terrain bump mapping with multi‐octave noise based on world position
|
||
float bumpStrength = 0.4;
|
||
float n1 = fract(sin(dot(vPosition.xz, vec2(12.9898, 78.233))) * 43758.5453);
|
||
float n2 = fract(sin(dot(vPosition.xz * 0.5, vec2(93.9898, 67.345))) * 24634.6345);
|
||
float noiseVal = mix(n1, n2, 0.5);
|
||
vec3 bumpNormal = normalize(vNormal + bumpStrength * (noiseVal - 0.5) * vec3(1.0));
|
||
// diffuse component (Lambert) with bump
|
||
float lambert = max(0.0, dot(normalize(bumpNormal), -lightDirection));
|
||
vec3 diffuse = vColor.rgb * lambert;
|
||
// combine ambient and diffuse
|
||
vec3 result = ambient + diffuse;
|
||
// specular component (Phong)
|
||
float shininess = 32.0;
|
||
vec3 viewDir = vec3(0.0, 0.0, 1.0);
|
||
vec3 reflectDir = reflect(-lightDirection, bumpNormal);
|
||
float spec = pow(max(dot(reflectDir, viewDir), 0.0), shininess);
|
||
float specStrength = 0.5;
|
||
vec3 specular = specStrength * spec * vec3(1.0);
|
||
result += specular;
|
||
color = vec4(result, vColor.a);
|
||
}
|