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

HLSL计算着色器中约0.002量级数值加减运算的异常表现

异常核心成因

所有测试表现的分界阈值,完全匹配8位归一化纹理(DXGI_FORMAT_R8G8B8A8_UNORM)的存储量化精度边界,和计算逻辑本身无关:

  • 8位UNORM纹理的每个颜色通道,存储时会把输入的浮点值乘以255,四舍五入到0-255的整数,再映射回0.0-1.0的浮点范围,相邻两个可存储灰度值的间隔为1/255≈0.00392,间隔中点的半格误差为(1/255)/2≈0.00196。
  • 当你对纹理值执行加减操作时,如果步长小于这个半格误差,操作后的值四舍五入后会和原存储值完全一致,写回后读不到任何变化,和你测到的递减操作阈值(0.00195失效、0.00196生效)完全吻合。
  • 累加场景下的失效阈值略微上浮到0.002区间,是因为每次从纹理读取的都是已经被量化截断的值,累积的量化偏移会进一步缩小实际有效步长,最终导致步长略高于纯数学半格阈值时,依然会卡在两个存储灰度值的中点,无法继续跨级提升亮度。
排查思路
  • 用图形调试工具(RenderDoc、PIX)查看你绑定的Result纹理的实际DXGI格式,90%的概率是默认的R8G8B8A8_UNORM上屏格式。
  • 做对照验证:临时把Result格式换成R32G32B32A32_FLOAT(32位全精度浮点),再跑低步长累加逻辑,如果渐变能正常运行,就直接实锤是存储量化的问题,不需要再排查着色器计算逻辑。
  • 对照量化规则验算:当步长小于≈0.002时,每次累加的有效变化量被量化截断,最终必然出现亮度停滞、完全不变化的现象,和你观察到的所有测试结果逻辑自洽。
可行解决方向
  • 不要直接在最终上屏的低精度纹理上做读-改-写的累加操作:额外分配一块R16F/R32F格式的高精度临时纹理,所有的渐变计算都在这块高精度资源上完成,每帧最后再把高精度结果量化写入上屏纹理,彻底规避中间步骤的量化截断问题。
  • 如果不需要额外分配资源,就不要每次从纹理读取已经量化的值作为累加基数:在常量缓冲区里维护精确的累积亮度值,每次计算后直接写入8位上屏纹理,避免量化误差累积卡壳。
  • 如果渐变精度要求不高,直接把步长调整到大于≈0.002的量化半格阈值即可,但这种方式受限于纹理格式的硬精度,没法实现更慢的平滑渐变效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 05:06:08