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 需要自己归一化。