三维空间中的法向量
法线的概念
法线(Normal)是一个垂直于给定表面(或曲线在该点的切线)的向量。对于一个平面,法线是垂直于该平面上任意两条相交直线的向量,对于一个曲面,在某一点P的法线,是垂直于该点切平面的向量。 简单来说,法线决定了光线如何从表面反弹,从而决定了物体在屏幕上呈现出的颜色和亮度。如果没有法线,光线就无法知道表面是朝向自己还是背向自己,渲染出的图像将是平板一块,毫无立体感。
点的法线:理论上,点是没有法线的。通常所说的“点的法线”是指该点所在曲面的法线。
如何计算法线?
平面的一般方程:
$$ Ax+By+Cz+D=0$$其中D$ =-(Ax_0+By_0+Cz_0)$,该平面经过点$(x_0,y_0,z_0)$,向量$\vec{n}=(A,B,C)$就是这个平面的法线向量。
已知曲面方程$F(x,y,z)=0:$法线可以通过梯度(Gradient)来计算:
$$ \vec{N} = \nabla F = \left(\frac{\partial F}{\partial x},\frac{\partial F}{\partial y}, \frac{\partial F}{\partial z} \right)$$
由于梯度的方向垂直于函数的等值面,并且从函数较小的等值面指向函数较大的等值面,三维空间中的法线方向指向曲面外侧,所以应该取梯度相反的反向,即
$$ \vec{n} = - \left(\frac{\partial F}{\partial x},\frac{\partial F}{\partial y}, \frac{\partial F}{\partial z}\right)$$
对于显式曲面 $z = f(x, y)$,我们可以写成隐式形式:
$$ F(x,y,z) = f(x,y) - z = 0 $$曲面的法线就是函数 $F$ 的梯度:
$$ \vec{N} = \nabla F = \left(\frac{\partial F}{\partial x},\frac{\partial F}{\partial y}, -1\right) $$
在计算中,其中一个方法是我们可以先求出函数的偏导数,然后再求具体的数值,然而实际情况往往求偏导数比较困难,特别是对于用于任意输入的函数,系统须具备自动求导功能才可以。实际中我们可以使用有限差分近似:用离散点近似偏导数:
$$ x方向的变化率=\frac{\partial F}{\partial x} = \frac{ z_1 - z}{dx} $$
$$ y方向的变化率=\frac{\partial F}{\partial y} = \frac{ z_2 - z}{dy} $$
其中:
- $z_1$是 $x+dx$ 处的函数值
- $z_2$是 $y+dy$ 处的函数值
- $dx, dy$是是步长
例如:
// 测试函数:z = sin(x) * cos(y)
float f(float x, float y) {
return sin(x) * cos(y);
}
// 在点 (1, 0.5) 处
float x = 1.0f, y = 0.5f;
float z = f(x, y);
float dx = 0.01f, dy = 0.01f;
float z1 = f(x + dx, y);
float z2 = f(x, y + dy);
法线如何“控制”光线?
在渲染中,光线照射到物体表面后,会发生反射和散射。法线($\vec{N}$)定义了表面的“向上”方向,所有的光照计算都围绕着光线方向($\vec{L}$)相对于 法线($\vec{N}$) 的角度展开。 最关键的计算是点积(Dot Product):
$$ \vec{N} \cdot \vec{L} = |\vec{N}||\vec{L}| \cos \theta $$
如果$\vec{N}$和$\vec{L}$都是单位向量(长度为1),那么点积的结果就是$\cosθ$。这个值直接决定了光线对表面的影响程度:
- 光线垂直照射$( θ=0^{\circ}): cos \theta = 1 \implies $表面最亮。
- 光线倾斜照射$( θ=60^{\circ}): cos \theta = 0.5 \implies $表面较暗。
- 光线平行表面$( θ=90^{\circ}): cos \theta = 0 \implies $表面全黑(光线擦过表面,没有照亮它)。
法线在不同光照模型中的作用
A. 漫反射(Diffuse)—— 塑造立体感
漫反射是物体表面的基础明暗变化,对应的是光线在粗糙表面的散射。公式(兰伯特光照模型):
$$ L_{\text{diffuse}} = k_d \cdot I_{\text{light}} \cdot \max(0, \vec{N} \cdot \vec{L}) $$
法线的角色:通过$\vec{N} \cdot \vec{L}$计算光线与表面的夹角。这是三维渲染中最常见的法线用法,它使得物体的正面被照亮,侧面变暗,背面全黑,从而产生立体感。
B. 镜面反射(Specular)—— 塑造光泽感
镜面反射对应的是光滑表面上的高光(如塑料、金属的反光)。公式(Phong / Blinn-Phong 模型):
$$ \vec{R} = 2(\vec{N}\cdot \vec{L})\vec{N} - \vec{L}$$需要计算反射量$\vec{R}$,
法线的角色:法线决定了反射光线的方向。如果法线方向有微小的变化,高光的位置就会发生显著偏移,这就是为什么光滑表面能看到光源的倒影。
C. 环境光遮蔽(Ambient Occlusion)
虽然不直接参与光照方程,但法线常用于判断光线是否能“到达”这里。例如,在光线追踪中,从交点沿法线方向发射一条射线,看是否能打到光源(阴影检测)。
QkCalc中的三维空间曲面
在趣宽数学软件中,通过“插入”菜单中的“空间函数图像”中绘制三维空间面。
详细请访问:三维空间曲面