在 HLSL 中将 float 转换为 unorm
Convert float to unorm in HLSL
我正在尝试在像素着色器中实现我自己的深度模板功能。
我有一个归一化的深度值,我想将其转换为整数以便使用 SM5 InterlockedMin() 操作,如下所示:
uint d_uint = (uint)(dnorm * 4294967295);
uint d_uint_original = 0;
InterlockedMin(depthmask[c], d_uint, d_uint_original);
if (d_uint < d_uint_original) { //if true, we will have written a new depth into the mask, so write the element to the field
field[c].x = d;
field[c].yzw = i.n;
}
其中dnorm
是深度值。
但是,uint d_uint = (uint)(dnorm * 4294967295);
只会评估为 0。
我知道这一点是因为我可以在 RenderDoc 中查看缓冲区并看到着色器只写入 0。我还可以减少常量,比如 229496729,它会正确写入。如果我将它设置为 2294967295 但它不会。
我知道我被浮点量化问题绊倒了,但不知道怎么办。
在整数数组中编码规范化值的正确方法是什么?
我知道 DX 的 UNORM/SNORM,也许我需要休息一下,但从该文档中不清楚应该如何使用它们,特别是将一个转换为 UINT 以便与互锁函数一起使用.
在你的情况下,因为我假设 dnorm > 0,你也可以简单地使用
uint depthAsUint = asuint(dnorm);
因为对于正浮点数,二进制表示满足比较运算符。
例如:
asuint(0.1f) < asuint(0.5f) = true
我正在尝试在像素着色器中实现我自己的深度模板功能。
我有一个归一化的深度值,我想将其转换为整数以便使用 SM5 InterlockedMin() 操作,如下所示:
uint d_uint = (uint)(dnorm * 4294967295);
uint d_uint_original = 0;
InterlockedMin(depthmask[c], d_uint, d_uint_original);
if (d_uint < d_uint_original) { //if true, we will have written a new depth into the mask, so write the element to the field
field[c].x = d;
field[c].yzw = i.n;
}
其中dnorm
是深度值。
但是,uint d_uint = (uint)(dnorm * 4294967295);
只会评估为 0。
我知道这一点是因为我可以在 RenderDoc 中查看缓冲区并看到着色器只写入 0。我还可以减少常量,比如 229496729,它会正确写入。如果我将它设置为 2294967295 但它不会。
我知道我被浮点量化问题绊倒了,但不知道怎么办。
在整数数组中编码规范化值的正确方法是什么?
我知道 DX 的 UNORM/SNORM,也许我需要休息一下,但从该文档中不清楚应该如何使用它们,特别是将一个转换为 UINT 以便与互锁函数一起使用.
在你的情况下,因为我假设 dnorm > 0,你也可以简单地使用
uint depthAsUint = asuint(dnorm);
因为对于正浮点数,二进制表示满足比较运算符。 例如:
asuint(0.1f) < asuint(0.5f) = true