光线追踪多光源漫反射着色实现中90度角位置出现异常阴影问题求助
问题根因
你遇到的90度入射角位置暗线问题,核心来自两个错误设计:
- 用反三角函数计算光线与法向量的夹角,在夹角接近90度时,反三角函数的浮点精度误差会导致亮度值发生跳变:极小的方向计算误差就会让角度一会略小于PI/2、一会略大于PI/2,对应亮度一会返回极小的正值、一会被Clamp直接置0,多光源叠加后这种跳变就会形成清晰的硬边暗线
- 对漫反射亮度的映射逻辑不符合物理规律,你采用了角度到亮度的线性映射,而标准Lambert漫反射的亮度衰减是和夹角的余弦值成正比,本身就不需要额外计算角度
修复方案
直接用法向量和光线方向的单位向量点积替代角度计算,点积结果本身就是夹角的余弦值,完全规避反三角函数的精度问题,同时符合漫反射的物理特性:
float brightness = 0; for (Light* light : unintersectedLights) { Vector3 intersectionToLightDirVec = Vector3Normalize(Vector3Subtract(light->position, intersection)); // 用单位向量点积直接计算漫反射系数,避免角度计算误差 float diffuseFactor = Vector3DotProduct(intersectionNormalVec, intersectionToLightDirVec); brightness += Clamp(diffuseFactor, 0, 1) * light->brightness; } color = ColorMultiply(color, brightness);
额外排查项
如果修改后仍存在边缘异常,可以优先校验两个点:
- 交点法向量
intersectionNormalVec是否做了归一化处理 - 阴影射线计算时是否加了极小的正向偏移,避免浮点误差导致的自遮挡误判
内容的提问来源于stack exchange,提问作者veqa
相关产品推荐
相关产品推荐

