1

DXT1 压缩设计用于在用于纹理采样器的硬件中快速解压缩。维基百科文章说,在某些情况下,您可以计算出插值颜色的系数:

c2 = (2/3)*c0+(1/3)*c1

或重新安排:

c2 = (1/3)*(2*c0+c1)

但是,如果您重新排列上述等式,那么您最终总是不得不将某个值乘以 1/3(或除以 3,同样的交易更昂贵)。对我来说很奇怪,设计为在硬件中快速解压缩的纹理格式需要乘法或除法。我在其上实现 GPU 的 FPGA 只有有限的乘法资源,我想将它们保存在真正需要的地方。

所以我错过了什么吗?有没有一种有效的方法可以避免将颜色通道乘以 1/3?还是我应该只吃乘法的成本?

4

2 回答 2

1

我能想出的最佳答案是我可以使用身份:

x/3 = sum(n=1 to infinity) (x/2^(2n))

然后取前 n 项。使用 4 个术语,我得到:

(x/4)+(x/16)+(x/64)+(x/256)

这等于

x*0.33203125

这可能已经足够好了。

这依赖于硬件中免费的 2 的固定幂的乘法,然后我可以并行运行 2 的 3 个加法。

不过,任何更好的答案都会受到赞赏。

** 编辑**:结合使用这个和@dyslexicgruffalo 的答案,我制作了一个简单的c++ 程序,它迭代了各种序列并尝试了它们并记录了各种平均/最大错误。

我这样做是为了 0 <= x <= 189 (因为 189 是 2*c0.g + c1.g 当 g (即 6 位)最大时的值。

最短的良好序列(最大误差为 2,平均误差为 0.62)和 4 个操作是:

1 + x/4 + x/16 + x/64.

最大误差为 1,平均误差为 0.32,但操作次数为 6 的最佳序列是:

x/2 - x/4 + x/8 - x/16 + x/32 - x/64.

对于 5 位值(红色和蓝色),最大值为 31*3,上述序列仍然很好,但不是最好的。这些是:

x/4 + x/8 - x/16 + x/32 [max error of 1, average 0.38]

1 + x/4 + x/16 [max error of 2, average of 0.68]

(而且,幸运的是,上述序列都没有猜到一个太大的答案,因此即使它们并不完美,也不需要夹紧)

于 2019-06-06T09:53:44.433 回答
1

这可能是一种不好的想象方式,但是您可以通过使用连续一半(班次)的加法/减法来实现它吗?

由于您有 16 位,这使您能够通过连续的加法和减法获得相当准确的结果。

第三个可以表示为

a(n+1) = a(n) +/- A>>1,其中列表 [0, 0, 1, 0, 1, etc] 显示是加还是减移位结果。

我相信这被称为分数数学。

然而,在 FPGA 中,很难知道这是否真的比提供的本地 DSP 模块(例如 DSP48E1)更节能。

于 2019-06-06T10:07:01.347 回答