HLSL:调度线程 ID returns 的模数与普通 uint 的值不同?

HLSL: the modulus of a dispatch thread ID returns a different value than a normal uint?

对于id.x = 70这个returns3:

RWStructuredBuffer<int> _TestBuffer;
. . . 
_TestBuffer[id.x] = floor(id.x / 5) % 5;

然而这 returns 4 如预期的那样:

_TestBuffer[id.x] = floor(70 / 5) % 5;

如果id.x69.999999(可能是坐标计算的结果),

floor(id.x / 5) 将是 13 而不是 14,因此:

floor(id.x / 5) % 5 将是 3 而不是预期的 4。

计算前第id.x轮解题:

_TestBuffer[id.x] = (round(id.x) / 5) % 5;

按照建议,我尝试像这样使用 round()

floor(round(id.x) / 5) % 5;

returns id.x = 70 的值为 3。然而,玩了一会儿后,我发现将 _TestBuffer 的数据类型从 int 更改为 float 会返回正确的值 4,这是弄清楚是什么的重要线索出错了:

RWStructuredBuffer<float> _TestBuffer;
. . . 
_TestBuffer[id.x] = floor(id.x / 5) % 5;
//This returns 4 for _TestBuffer[70]

所以这是导致错误的原因:

  1. floor(id.x / 5)函数returns一个float
  2. 因为是float取模运算14 % 5returns一个浮点数,大概是3.99999
  3. 该数字在分配给 _TestBuffer[id.x]
  4. 时隐式转换为类型 int
  5. 根据 HLSL 中 conversion 的规则,3.99999 向零舍入,导致 int 值为 3

该错误的解决方案是简单地在赋值前对表达式进行舍入,如下所示:

RWStructuredBuffer<int> _TestBuffer;
. . . 
_TestBuffer[id.x] = round(floor(id.x / 5) % 5);