fwidth
fwidth
计算一个值在屏幕空间中相邻像素间的总变化率,即 abs(dFdx) + abs(dFdy)。它主要用于测量程序化生成的边缘在屏幕上的“宽度”,从而实现平滑的抗锯齿效果。
核心优势
实现真正的分辨率无关性。使用 fwidth 创建的抗锯齿效果,无论在何种分辨率或摄像机距离下,都能保持一致的视觉宽度(如1像素的柔和边缘),是高质量程序化图形的基石。
常见用途
为程序化生成的线条、网格和形状提供完美的抗锯齿边缘。
在卡通渲染中,通过分析法线与视角的点积梯度,绘制宽度恒定的轮廓线。
通过计算UV坐标的变化率,实现自定义纹理滤波器,以消除远距离或斜视角的摩尔纹。
如何调整
你不能直接调整 fwidth,而是通过改变其输入来观察其响应。将 fwidth(uv()) 可视化会显示出透视失真。其核心特性是:即使你将输入值缩放(如 uv.x * 10),fwidth 的输出也会相应变大,但在 smoothstep 中,这会与输入值的更快变化完美抵消,最终在屏幕上产生视觉宽度恒定的平滑边缘,这就是分辨率无关性的体现。
代码示例
1// p 是定义形状的值, 如 uv.x
2const width = fwidth( p );
3// 使用计算出的宽度创建平滑过渡,代替生硬的 step() 函数
4const antiAliasedEdge = smoothstep( 0.5 - width, 0.5 + width, p );