GLSL Learning

GLSL built-in function

faceforward()

Returns N or -N, whichever points against the incoming direction I. Makes normals face the viewer for two-sided lighting.

Syntax

vec3 faceforward(vec3 N, vec3 I, vec3 Nref)
vec2 faceforward(vec2 N, vec2 I, vec2 Nref)

Parameters

N
The normal to possibly flip.
I
The incoming (view) direction.
Nref
The reference normal used for the test, usually the same as N.

Return value

N if dot(Nref, I) < 0.0, otherwise -N.

Live example

Edit the code and the preview updates as you type.

How it works

Lighting usually assumes the normal points toward the viewer. When you see the back of a surface, such as the inside of a bowl, a leaf or a flag, the normal points away and dot(normal, light) gives the wrong answer.

faceforward(N, I, Nref) fixes that. It checks dot(Nref, I):

  • negative, meaning the normal already faces the viewer: returns N
  • otherwise: returns -N

In the example the normals point away from the camera. The left half uses them as they are and stays almost dark; the right half passes them through faceforward and lights correctly.

Typical uses

  • Two-sided surfaces: leaves, cloth, paper and planes seen from both sides.
  • Robust lighting when you are not sure which way a computed normal points.

Common mistakes

  • Passing the direction from the surface to the camera. I is the incoming direction, from the camera toward the surface.
  • Expecting it to normalize. It only flips the sign; normalize N yourself.

Related functions