fix: flip normal only by view direction — fixes both cubes and spheres

Previous fix flipped normal by both light AND view direction:
  if (dot(N,L) < 0) N = -N;
  if (dot(N,V) < 0) N = -N;
This double-flip broke spheres: when light is behind sphere, front faces
get N flipped by light (now facing away from camera), then flipped back
by view — but back faces get flipped once, causing inconsistency.

Correct approach: flip ONLY by view direction:
  if (dot(N, V) < 0.0) N = -N;
This ensures the normal always faces the camera. Faces pointing away
from light naturally get NdotL=0 (no lighting) — correct behavior.
Spheres keep smooth normals, cubes get inward normals fixed.
This commit is contained in:
emil28092005
2026-06-18 21:56:10 +03:00
parent 2f7430e3b1
commit 6a473bdc53
2 changed files with 2 additions and 11 deletions
@@ -138,17 +138,8 @@ void main()
float dist = length(toLight);
vec3 L = toLight / max(dist, 0.001);
// Flip normal if it faces away from light (fixes inward normals from bad winding)
if (dot(N, L) < 0.0)
{
N = -N;
}
// Also flip for view direction if needed
if (dot(N, V) < 0.0)
{
N = -N;
}
// Flip normal to face camera — fixes cubes with bad winding without breaking spheres
if (dot(N, V) < 0.0) N = -N;
float attenuation = pow(clamp(1.0 - dist / max(lightRange, 0.001), 0.0, 1.0), 2.0);
vec3 radiance = lightColor * lightIntensity * attenuation;
Binary file not shown.