DXT1压缩的设计是为了在硬件中快速解压缩,在硬件中使用它的纹理采样器。维基百科的文章说,在某些情况下,你可以计算出插值颜色的系数如下:
c2 = (2/3)*c0+(1/3)*c1或者重新安排:
c2 = (1/3)*(2*c0+c1)不管你如何重新排列上面的等式,最终你总是不得不将某物乘以1/3 (或除以3,同样的交易甚至更昂贵)。在我看来,一种纹理格式被设计成可以在硬件中快速解压缩,它需要乘法或除法,这让我觉得很奇怪。我正在实现我的GPU的FPGA上只有有限的乘法资源,我想把它们保存到真正需要它们的地方。
那我是不是漏掉了什么?有没有一种有效的方法来避免1/3的颜色通道的乘法?或者我应该吃乘法的成本吗?
发布于 2019-06-06 10:07:01
这可能是一个不好的方式来想象它,但你能通过使用加减法连续的一半(班次)来实现它吗?
由于您有16位,这使您能够获得相当准确的连续增减。
第三个可以表示为
a(n+1) = a(n) +/- A>>1,其中,列表0、0、1、0、1等显示是添加还是减去移位的结果。
我相信这叫做分数数学。
然而,在FPGA中,很难知道这是否实际上比提供的本地DSP块(例如DSP48E1)更有效。
发布于 2019-06-06 09:53:44
我能想到的最好的答案是,我可以使用这个身份:
x/3 = sum(n=1 to infinity) (x/2^(2n))然后取前n项。我用了4个术语:
(x/4)+(x/16)+(x/64)+(x/256)这等于
x*0.33203125这可能就足够了。
这依赖于一个固定的幂乘法2是免费的硬件,然后3个加法,我可以运行2并行。
不过,如果有更好的答案,我们将不胜感激。
**编辑**:结合使用这个和@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](幸运的是,上述序列中没有一个能猜出一个太大的答案,所以即使它们并不完美,也不需要夹紧)。
https://stackoverflow.com/questions/56474930
复制相似问题