Base-导数与微分在图形学中的应用
图形学里经常需要知道一个值变化得有多快:高度场在哪个方向上升,UV 在相邻像素间变化多少,曲线某一点应朝哪里。这些问题可以用导数统一描述。
原笔记只记录到极限的开头。这里沿着极限、局部线性近似和图形学应用补齐主线;原记录只精确到 2018 年 3 月,文章日期以月初占位,不表示原笔记确切写于 1 日。
1. 极限不是把变量直接设为终点
考虑 f(x)=(x²-1)/(x-1)。x=1 时原式无定义,但在 x 不等于 1 时可以化简为 x+1,所以 x 趋近 1 时,函数值趋近 2。
极限讨论的是附近行为。连续函数可以用代入求极限,不代表所有表达式都能代入;出现 0/0 时也不代表极限一定是零或不存在。
2. 导数是割线斜率的极限
1 | |
对 f(x)=x²,差商是 2x+h,极限为 2x。导数描述该点附近的变化率,也给出切线方向。
从有限差分直接跳到导数,需要函数在该点可微。绝对值函数在零点连续,却没有唯一的左右斜率;Shader 中的 step、abs 和分段选择,也会带来不光滑位置。
3. 微分是局部线性近似
小变化 dx 下,dy=f'(x)dx 描述一阶近似,实际增量 Δy 一般还包含高阶误差。dx 越小且函数越平滑,近似通常越好。
多变量函数用梯度组织偏导。例如 h(x,z) 的梯度是 (∂h/∂x,∂h/∂z),它指向高度增长最快的方向。不是每个梯度都需要归一化;归一化会丢掉变化率大小。
4. 从高度梯度构造法线
对于表面 p(x,z)=(x,h(x,z),z),向上的法线可写为:
1 | |
因为切线分别为 (1,hx,0) 与 (0,hz,1),法线应与两者正交。模型轴向与叉积顺序改变时,要同步检查法线方向。
没有解析导数时,可以用中心差分估计:
1 | |
e 应对应正确的坐标尺度。太大丢细节,太小会受浮点消减和纹理分辨率影响。把 UV 差分直接当作世界长度梯度,也会造成凹凸强度随贴图缩放变化。
5. 屏幕导数与纹理采样
像素 Shader 的 ddx、ddy 通常利用邻近片元的值估算屏幕方向差分,不是对任意表达式自动做符号求导。它们适合估计纹理足迹、边缘宽度和局部变化。
导数依赖片元组执行条件,非一致分支会让隐式导数的使用受限。Compute Shader 也不能在所有平台上默认拥有与像素阶段相同的导数能力。
6. 链式法则为什么重要
如果高度来自 h(s*x),对 x 求导会多出 s。缩放输入坐标不仅改变纹理频率,也会改变梯度大小。程序化噪声生成法线时,忽略这个因子会使高频细节的坡度不符合实际高度变化。
积分则处理累计量,例如沿射线的密度积累或曲线长度。导数与积分有紧密联系,但不是把“分得无限细”作为万能解释;需要明确求的是变化率还是累计值。
总结
导数让局部变化可计算,微分把它变成近似,梯度把它推广到多个方向。在图形学代码中,最重要的是标明变量所在空间、单位和差分尺度,避免数学形式正确而数据含义错误。