【图形学入门】Phong 光照模型中反射方向公式是怎么来的

发布时间:2026/7/2 3:02:02
【图形学入门】Phong 光照模型中反射方向公式是怎么来的 它用来计算镜面反射方向。一开始看到这个公式感觉有点突兀为什么是 2(⋅)−这个 2 是哪里来的点积 ⋅ 在里面起什么作用后来把它从向量分解的角度拆开之后瞬间就清楚了。这篇博客记录一下我的理解。1. Phong 中的几个方向在 Phong 光照模型中计算高光时会涉及几个方向(N)表面法线方向(L)从当前点指向光源的方向(R)光线关于法线反射后的方向(V)从当前点指向观察者也就是摄像机的方向高光是否明显主要看⋅也就是说反射方向 (R) 和观察方向 (V) 越接近看到的高光越强。所以问题就变成了已知法线方向 (N) 和光照方向 (L)怎么求反射方向 (R)2. 先不要背公式先看反射到底发生了什么镜面反射的本质是入射方向和反射方向关于法线对称。也就是说法线 (N) 像一面“镜子的中轴线”。可以粗略理解成L / / / / ---P--------- | | N |其中 (P) 是当前表面上的点。我们要求的是 (L) 关于 (N) 对称后的方向也就是 (R)。3. 关键思想把 (L) 拆成两部分一个向量 (L) 可以拆成两部分∥⊥其中(L_{\parallel})沿着法线 (N) 的分量(L_{\perp})垂直于法线 (N) 的分量换句话说就是把 (L) 拆成L 朝着法线方向的部分 横向偏出去的部分4. 沿着法线的部分怎么求如果 (N) 是单位向量也就是||1那么 (L) 在 (N) 上的投影就是∥(⋅)这里的 (N \cdot L) 是点积它表示(L) 在 (N) 方向上的长度。然后再乘上方向 (N)就得到了完整的投影向量。所以∥(⋅)剩下的垂直分量就是⊥−∥也就是⊥−(⋅)5. 反射时哪部分变哪部分不变这是整个公式最核心的地方。当 (L) 关于法线 (N) 反射时沿着法线方向的分量不变垂直于法线方向的分量反向也就是说∥−⊥因为原来∥⊥反射后把横向偏出去的部分翻到另一边∥−⊥6. 开始代入推导因为⊥−∥所以∥−⊥代入∥−(−∥)展开∥−∥合并2∥−又因为∥(⋅)所以2(⋅)−最终得到2(⋅)−7. 为什么公式里面有一个 2这个 2 不是凭空来的。它来自这里∥−(−∥)展开后2∥−也就是说反射方向可以理解为先找到 (L) 在法线方向上的投影然后从这个投影位置“翻过去”。原来的 (L) 在法线的一侧反射后的 (R) 在另一侧所以需要跨过法线方向的投影点。这个“跨过去”的过程就导致了 (2L_{\parallel})。8. 用一个二维例子验证一下假设法线方向是竖直向上(0,1)假设光照方向 (L) 是右上方 45 度(22,22)先计算点积⋅0×221×2222然后计算2(⋅)2×22×(0,1)最后2(⋅)−代入(0,2)−(22,22)得到(−22,22)结果是左上方 45 度。这正好符合直觉原来的 (L) 指向右上方关于竖直法线反射后应该指向左上方。9. 一个容易踩坑的地方方向定义不同公式可能长得不一样有些图形学 API 或教材里反射公式可能写成−2(⋅)这和本文的公式看起来不一样。原因不是数学矛盾而是方向定义不同。本文使用的是(L)从表面点指向光源所以反射方向是2(⋅)−而很多 API 中使用的是(I)入射方向也就是光线真正打向表面的方向此时 (I) 和 (L) 通常相反−所以公式会变成−2(⋅)本质上是同一个东西只是向量方向的约定不同。10. 总结Phong 光照模型里的反射方向公式2(⋅)−不是硬背出来的而是从向量分解自然推出来的。核心逻辑是∥⊥其中∥(⋅)反射时沿法线方向的分量不变垂直法线方向的分量反向所以∥−⊥最后推出