EPSILON
EPSILON
一个极小的正数常量(通常为 1e-6),用于在着色器计算中规避浮点数精度问题,确保数值稳定性和健壮性。
核心优势
通过提供一个统一的、命名清晰的“容错阈值”,它能从根本上提升代码的健壮性和可读性,避免了因除零、不精确比较等问题导致的渲染瑕疵,并使精度标准的调整变得简单集中。
常见用途
安全除法:在光照计算中,将可能为零的分母加上或取最大值 EPSILON,以防止除以零。
模糊比较:判断一个值是否“足够接近”零,例如 `length(v) < EPSILON`,而不是使用危险的 `v == 0.0`。
防止自相交:在光线追踪中,将反射光线的起点沿法线方向偏移一个 EPSILON 的距离,以避免“阴影粉刺”(shadow acne)。
保护函数定义域:确保传入 `log()` 或 `sqrt()` 等函数的参数为正数,例如 `log(x + EPSILON)`。
如何调整
EPSILON 是一个编译时常量,无法在运行时调整。选择其值是一种权衡:值太大(如 0.01)会牺牲视觉精度,导致高光变暗或阴影悬浮;值太小(如 1e-10)则可能在低精度硬件上失效,无法起到保护作用。默认值 1e-6 是在安全性和准确性之间公认的良好平衡点。
代码示例
1// 确保分母最小也是一个微小的正数,防止除零
2const denominator = TSL.max( dot( N, L ), TSL.EPSILON );
3const result = 1.0 / denominator;