51 lines
1.6 KiB
GLSL
51 lines
1.6 KiB
GLSL
#version 460 core
|
|
|
|
in vec3 FragPos;
|
|
in vec2 TexCoords;
|
|
in vec3 Normal;
|
|
|
|
out vec4 FragColor;
|
|
|
|
uniform vec3 cameraPos;
|
|
uniform vec3 lightPos;
|
|
|
|
// Material constants
|
|
const vec3 waterShallowColor = vec3(0.0, 0.6, 0.7);
|
|
const vec3 waterDeepColor = vec3(0.05, 0.15, 0.3);
|
|
const vec3 sunColor = vec3(1.0, 0.95, 0.8);
|
|
|
|
void main() {
|
|
// Normalize vectors
|
|
vec3 n = normalize(Normal);
|
|
vec3 viewDir = normalize(cameraPos - FragPos);
|
|
vec3 lightDir = normalize(lightPos - FragPos);
|
|
|
|
// 1. Ambient Lighting
|
|
vec3 ambient = 0.3 * waterShallowColor;
|
|
|
|
// 2. Diffuse Shading
|
|
float diff = max(dot(n, lightDir), 0.0);
|
|
vec3 diffuse = diff * sunColor * 0.4;
|
|
|
|
// 3. Specular Highlights (Blinn-Phong)
|
|
vec3 halfwayDir = normalize(lightDir + viewDir);
|
|
float spec = pow(max(dot(n, halfwayDir), 0.0), 64.0); // High shininess for water glaze
|
|
vec3 specular = spec * sunColor * 0.8;
|
|
|
|
// 4. Fresnel Approximation (Schlick's approximation)
|
|
// Water has a base reflectivity of roughly 0.02 at a perpendicular view angle
|
|
float F0 = 0.02;
|
|
float fresnel = F0 + (1.0 - F0) * pow(1.0 - max(dot(n, viewDir), 0.0), 5.0);
|
|
|
|
// Mix deep and shallow water colors based on the normal angle
|
|
vec3 baseWaterColor = mix(waterShallowColor, waterDeepColor, max(dot(n, vec3(0.0, 1.0, 0.0)), 0.0));
|
|
|
|
// Combine lighting results
|
|
vec3 lightingResult = ambient + diffuse + specular;
|
|
|
|
// Blend final look with Fresnel reflection dominance
|
|
vec3 finalColor = mix(baseWaterColor + specular, lightingResult + vec3(fresnel * 0.5), fresnel);
|
|
|
|
// Output final color with subtle translucency opacity
|
|
FragColor = vec4(finalColor, 0.85);
|
|
}
|