You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我编写的GLSL光照Shader会在光源原点处出现异常高亮的点?

问题原因
  • 颜色通道的合法取值范围为[0.0, 1.0],当前衰减计算逻辑在光源原点位置(abs_distance=0)时,算出的attenuation值为1/(1+0+0)*100 = 100,远超过1.0的上限,超出部分会被渲染管线直接钳位到1.0,因此原点区域会出现大面积无过渡的纯白异常高亮。
  • 当前设置的衰减参数(线性项、二次项均为1.0)与100的光强匹配度极低,衰减速度过快:距离光源1像素时衰减值降到约33,距离10像素时就已经降到0.9左右,稍远位置直接失去光照,进一步放大了近点高亮和远区全黑的割裂感。
  • 额外笔误:代码注释写的是Flip over the x axis,但实际修改的是y轴坐标,注释描述错误。
修复方案
  • 方案1:新增衰减值钳位逻辑,直接限制亮度上限
    在计算完attenuation后新增一行钳位代码,改动最小,可直接解决高亮溢出问题,适合需要保留原有衰减曲线的场景:
attenuation = clamp(attenuation, 0.0, 1.0);
  • 方案2:调整衰减参数匹配光强,获得更自然的衰减效果
    将原衰减公式的固定系数改为可调参数,适配600*600窗口尺寸的参考修改如下,可通过调整系数值自定义光照覆盖范围:
float light_strength = 1.0; // 光强改为1.0从根源避免数值溢出
float linear_factor = 0.005; // 线性衰减系数,值越小光照范围越大
float quadratic_factor = 0.0001; // 二次衰减系数,值越小光照范围越大
float attenuation = 1.0 / (1.0 + linear_factor * abs_distance + quadratic_factor * pow(abs_distance, 2.0)) * light_strength;
  • 方案3:改用半径控制的衰减逻辑,可控性更强
    如果不需要严格遵循物理衰减公式,可以直接用最大光照半径控制衰减,调整更直观且天然不会出现数值溢出问题:
float max_light_radius = 300.0; // 自定义光照最大覆盖半径
float attenuation = 1.0 - clamp(abs_distance / max_light_radius, 0.0, 1.0);
attenuation = pow(attenuation, 2.0); // 调整幂次可以修改衰减曲线的软硬程度,值越大边缘过渡越柔和

内容的提问来源于stack exchange,提问作者user16557139

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 08:15:02