GLSL 内置函数

normalize()

返回与 x 方向相同、长度为 1.0 的向量。保留方向,丢掉大小。

函数签名

vec2 normalize(vec2 x)
vec3 normalize(vec3 x)
vec4 normalize(vec4 x)

参数

x
要归一化的向量,不能是零向量。

返回值

x / length(x),一个与 x 类型相同的单位向量。

在线示例

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

工作原理

向量有方向和长度。normalize 保留方向,并把长度设为正好 1:

normalize(vec2(3.0, 4.0)) // vec2(0.6, 0.8),长度 1.0

示例用每个像素到中心的向量来上色。左半边用原始向量,靠近中心的地方向量很短,颜色就褪成灰色。右半边把同样的向量归一化,每个像素的颜色都是满强度的,只剩方向起作用,于是得到边界清晰的色块。

常见用法

  • 光照方向:光源方向和视线方向必须是单位向量,dot 才能给出正确的 0 到 1 亮度。
  • 表面法线:计算或插值得到法线后,先 normalize 再使用。
  • 光线方向:在光线步进中用 normalize(vec3(p, -1.0)) 生成相机射线。

常见错误

  • 对零向量归一化。normalize(vec2(0.0)) 会除以 0,返回 NaN,通常表现为正中心的一个黑点。先加一个很小的偏移,或先检查长度。
  • 对颜色归一化。normalize(color) 改变亮度的方式很少好看,它是给方向用的。
  • 两个单位向量相加后忘了再归一化。normalize(lightDir + viewDir) 才是半程向量,单纯相加的结果太长。

相关函数

用到 normalize() 的教程