DirectX11中有限差分法计算曲面法线的代码逻辑疑问
你这段代码是针对规则高度场网格计算法线的实现,高度场可以表示为 y = f(x,z),其中x和z是水平面的两个正交轴,相邻网格点在x、z方向的间距都是mSpatialStep。
整个逻辑的核心仍然是「两个正交切向量叉乘得到法线」,有限差分只是用来在没有显式曲面公式时,近似计算切向量里的偏导数,具体推导过程如下:
1. 用中心差分近似偏导数
对高度场函数y = f(x,z),某个点的偏导数我们用相邻点的高度做中心差分近似(中心差分的精度比单侧差分更高):
- x方向的偏导数 ∂y/∂x ≈ (右侧点高度 - 左侧点高度) / (2 * 网格间距) =
(r - l) / (2 * mSpatialStep) - z方向的偏导数 ∂y/∂z ≈ (下侧点高度 - 上侧点高度) / (2 * 网格间距) =
(b - t) / (2 * mSpatialStep)
2. 构造两个正交切向量
- x方向的切向量是沿着x轴移动时的方向向量:x每走1单位,y变化为∂y/∂x,z不变,所以切向量
Tₓ = (1, ∂y/∂x, 0) - z方向的切向量是沿着z轴移动时的方向向量:z每走1单位,y变化为∂y/∂z,x不变,所以切向量
T_z = (0, ∂y/∂z, 1)
3. 切向量叉乘得到法线
法线向量等于两个切向量的叉乘,为了得到朝向y轴正方向的法线,我们可以调整叉乘顺序,并且利用「法线是方向向量,缩放不改变方向,最终会做归一化」的特性,提前消掉公共系数简化计算:
原始叉乘(调整朝向后)的向量经过-2*mSpatialStep缩放后,就得到了你代码里的分量:
- x分量:
-(r-l) = l - r = -r + l,和代码里的x分量完全一致 - y分量:
2.0f * mSpatialStep,和代码里的y分量完全一致 - z分量:
b - t,和代码里的z分量完全一致
4. 简化计算的合理性
因为代码最后会对法线做XMVector3Normalize归一化处理,向量整体乘以任意非零常数都不会改变最终的归一化结果,所以直接用简化后的分量计算完全不会影响法线的正确性,还能减少不必要的除法运算,提升性能。
内容的提问来源于stack exchange,提问作者zhoyic
相关产品推荐
相关产品推荐

