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.x
是69.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]
所以这是导致错误的原因:
floor(id.x / 5)
函数returns一个float
- 因为是
float
取模运算14 % 5
returns一个浮点数,大概是3.99999
- 该数字在分配给
_TestBuffer[id.x]
时隐式转换为类型 int
- 根据 HLSL 中 conversion 的规则,
3.99999
向零舍入,导致 int
值为 3
该错误的解决方案是简单地在赋值前对表达式进行舍入,如下所示:
RWStructuredBuffer<int> _TestBuffer;
. . .
_TestBuffer[id.x] = round(floor(id.x / 5) % 5);
对于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.x
是69.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]
所以这是导致错误的原因:
floor(id.x / 5)
函数returns一个float
- 因为是
float
取模运算14 % 5
returns一个浮点数,大概是3.99999
- 该数字在分配给
_TestBuffer[id.x]
时隐式转换为类型 - 根据 HLSL 中 conversion 的规则,
3.99999
向零舍入,导致int
值为3
int
该错误的解决方案是简单地在赋值前对表达式进行舍入,如下所示:
RWStructuredBuffer<int> _TestBuffer;
. . .
_TestBuffer[id.x] = round(floor(id.x / 5) % 5);