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

为何光源与相机裁剪空间变换一致时仍存在自阴影走样问题

差异点定位

  1. 矩阵运算顺序错误带来的浮点误差
    你的Camera Pass顶点着色器中,对光源空间裁剪坐标的处理顺序是「先乘偏置矩阵biasMat,再在片元着色器做透视除法」,这和Light Pass的硬件处理逻辑完全相反:
    Light Pass中硬件对gl_Position的处理顺序是先做透视除法得到NDC坐标,再做视口变换、深度范围映射写入深度缓冲。你提前乘biasMat会改变透视除法前的坐标值,引入额外的浮点舍入误差。

  2. 深度计算路径不一致的误差
    Light Pass写入深度缓冲的深度值是硬件光栅化阶段直接生成的,经过了固定管线的深度范围映射、精度截断(取决于你用的深度缓冲格式,比如D24S8只有24位精度),而你在Camera Pass片元着色器中计算的depthInLightSpace是着色器端32位浮点运算的结果,两者天然存在精度差。

  3. 插值精度差异
    你在Camera Pass顶点着色器中计算vPositionFromLight后,经过跨三角形插值传递到片元着色器,这个插值过程的精度和Light Pass中硬件直接对深度值做的光栅化插值精度不一致,尤其是透视投影下非线性深度的插值误差会被放大。

  4. 无深度偏移的直接比较
    你直接用depthFromShadowMap >= depthInLightSpace做判断,哪怕只有1e-6量级的浮点误差,也会导致本应该相等的深度被判为更小,触发误遮挡。


修复方案

  1. 调整偏置矩阵的运算顺序:在片元着色器做完透视除法得到NDC坐标后,再乘偏置矩阵做坐标映射,或者直接提前把biasMat * proj * uLightViewMatrix预计算成一个光影投影矩阵,减少着色器端的运算次数。
  2. 增加深度偏移:比较时给depthInLightSpace增加一个极小的固定偏移,比如0.0005,或者根据场景深度范围动态调整偏移值,也可以在Light Pass绘制时开启多边形偏移(Vulkan对应vkCmdSetDepthBias)直接给写入的深度值加偏移。
  3. 尽量用更高精度的深度缓冲格式:比如用D32_SFLOAT格式的深度纹理,减少精度截断带来的误差。
  4. 可选优化:如果是方向光可以用正交投影减少非线性深度的插值误差,或者使用百分比渐近过滤(PCF)、方差阴影映射(VSM)等算法弱化精度问题带来的走样。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:09:02