- No specular on surfaces facing away from the light source - Transform the light direction to view space to ensure that all lighting calculations happen in a consistent coordinate space. - Other lighting tweaks
43 lines
1.3 KiB
GLSL
43 lines
1.3 KiB
GLSL
#version 330 core
|
|
|
|
in vec3 v_normal;
|
|
in vec2 v_tex;
|
|
in vec3 v_position;
|
|
|
|
out vec4 frag_color;
|
|
|
|
uniform vec3 u_light; // direction TO the light (normalized)
|
|
uniform sampler2D tex;
|
|
uniform vec3 color; // base colour factor (acts as solid colour when no texture)
|
|
|
|
void main() {
|
|
// Combine base texture (or constant white) with colour factor supplied by CPU.
|
|
vec3 base_col = texture(tex, v_tex).rgb * color;
|
|
|
|
vec3 N = normalize(v_normal);
|
|
vec3 L = normalize(u_light);
|
|
|
|
// Classic Blinn-Phong lighting
|
|
// Ambient: always present
|
|
vec3 ambient = base_col * 0.15;
|
|
|
|
// Diffuse: N dot L, clamped
|
|
float NdotL = max(dot(N, L), 0.0);
|
|
vec3 diffuse = base_col * NdotL * 0.7;
|
|
|
|
// Specular: only on surfaces facing the light (NdotL > 0)
|
|
float specular = 0.0;
|
|
if (NdotL > 0.0) {
|
|
vec3 V = normalize(-v_position); // view direction (camera at origin in view space)
|
|
vec3 H = normalize(L + V); // half-vector
|
|
float NdotH = max(dot(N, H), 0.0);
|
|
specular = pow(NdotH, 32.0) * 0.5; // tighter highlight, moderated intensity
|
|
}
|
|
|
|
vec3 result = ambient + diffuse + vec3(specular);
|
|
|
|
// Convert from linear to sRGB for display (approximate gamma correction)
|
|
result = pow(result, vec3(1.0 / 2.2));
|
|
|
|
frag_color = vec4(result, 1.0);
|
|
}
|