在OpenGL(或者更广义的图形学)里,“法线”(Normal 或者 Normal Vector)是一个非常基础但极重要的概念。我分几个方面给你详细说明:定义、用途、计算、在渲染管线里的变换以及实践注意事项。

定义
(1) “法线”通常指的是在某一点上垂直于表面(或曲面、平面)的向量。也就是说,它指明这个表面在那个点“朝哪个方向”垂直指向。
(2) 通常我们使用单位法线(unit normal),也就是长度为1的向量,这样在后续光照计算中更方便(避免因长度不同引入误差)。

用途
法线在图形学里大部分作用都和光照/阴影/反射/可见性等“方向感”相关,具体地:

1.光照计算(Lighting)
漫反射 (diffuse):Lambert 定律中,光线入射方向和法线的夹角决定这点表面接受光线强度的多少。点积(dot product)通常是 max(dot(N, L), 0)。
镜面反射 (specular):反射方向与观察方向之间的关系通常也要法线参与计算。比如 Phong or Blinn‐Phong 模型等。

2.决定面朝方向 / 背面剔除(Back‐face culling)
如果一个法线朝向观察者(或者法线与视线方向的点积为负/正,视具体约定而定),你可以判定这个面是否要被绘制。

3.阴影/环境光/置换贴图/法线贴图(normal mapping)等高级效果
法线贴图里,是通过纹理修改每个像素点的法线,以模拟细节。

4.几何学/曲面细节
在曲面处(非平面多边形),每个顶点通常都有一个法线(vertex normal),这可以使光照看起来更平滑(Smooth shading)。如果只对面使用一个法线,那么边界会显得很“硬”。

法线怎么计算

几种常见方式:

对于平面 /三角形面片 (polygon / triangle face):
用两个边向量(假设三角形顶点为 A, B, C),计算 (B−A) × (C−A),得到一个向量,这个向量垂直这个三角形面。通常再做单位化处理。

顶点法线 (vertex normal):
顶点通常是许多面共享的点,为了让光照看起来平滑,人们一般把这些面片的法线先算出来,然后对共享顶点上的这些面片法线求平均,再单位化。这样顶点处的法线就大致指向“曲面”的方向,而不是某一个面片。

曲面 /参数化表示的曲线 /隐式曲面:
对于参数化曲面 r(s,t),法线可以用 ∂r/∂s × ∂r/∂t。
对于隐式定义的曲面 F(x, y, z) = 0,则法线是梯度 ∇F(x, y, z)。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐