GLSL 内置函数

faceforward()

返回 N 或 -N 中与入射方向 I 相反的那个。让法线朝向观察者,用于双面光照。

函数签名

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

参数

N
可能需要翻转的法线。
I
入射(视线)方向。
Nref
用于判断的参考法线,通常和 N 相同。

返回值

若 dot(Nref, I) < 0.0 返回 N,否则返回 -N。

在线示例

修改右侧代码,左侧预览会实时更新。

工作原理

光照计算通常假设法线朝向观察者。当你看到的是表面的背面,比如碗的内侧、树叶或旗帜,法线就背离观察者,dot(normal, light) 会给出错误的结果。

faceforward(N, I, Nref) 用来修正这个问题。它检查 dot(Nref, I):

  • 为负,说明法线已经朝向观察者:返回 N
  • 否则:返回 -N

示例中的法线都背离相机。左半边直接使用,几乎全黑;右半边先经过 faceforward,光照就正确了。

常见用法

  • 双面表面:树叶、布料、纸张、从两面都能看到的平面。
  • 更稳健的光照:不确定计算出的法线朝哪边时使用。

常见错误

  • 传入的是从表面指向相机的方向。I 是入射方向,从相机指向表面。
  • 以为它会归一化。它只翻转符号,N 需要自己归一化。

相关函数