普通压缩背后的数学

时间:2018-10-29 09:02:38

标签: math vector compression

下面的代码(由C#重写)用于压缩Wild Magic 5.17中的单位法向矢量,有人可以在其后面解释一些数学运算或共享一些相关的引用吗? 我可以弄清楚八位位的设置,但是尾数的打包和拆包似乎很复杂...

codes gist

一些代码在这里

// ...

public static ushort CompressNormal(Vector3 normal)
{
    var x = normal.x;
    var y = normal.y;
    var z = normal.z;
    Debug.Assert(MathUtil.IsSame(x * x + y * y + z * z, 1));

    // Determine octant.
    ushort index = 0;

    if (x < 0.0)
    {
        index |= 0x8000;
        x = -x;
    }
    if (y < 0.0)
    {
        index |= 0x4000;
        y = -y;
    }
    if (z < 0.0)
    {
        index |= 0x2000;
        z = -z;
    }

    // Determine mantissa.
    ushort usX = (ushort)Mathf.Floor(gsFactor * x);
    ushort usY = (ushort)Mathf.Floor(gsFactor * y);
    ushort mantissa = (ushort)(usX + ((usY * (255 - usY)) >> 1));
    index |= mantissa;

    return index;
}

// ...

2 个答案:

答案 0 :(得分:0)

作者想使用13位。
简单的方法:x分量的 6位+ y的6位-仅占12位,因此他发明了为x和y分配〜90(lsb)单位和y分配〜90(msb)单位的方法(90 * 90〜2 ^ 13)。

我不知道他为什么对y分量使用二次公式-这种方式在较小值和较大值之间给出近似值的分布略有不同-但是为什么专门针对y?

答案 1 :(得分:0)

我问过Eberly先生(Wild Magic的作者),他给上面的ref(简而言之,desc)代码尝试将(x,y)映射到三角形数组的索引(索引从0到N * (N +1)/ 2-1)

enter image description here

更多详细信息在此处的相关doc中, 顺便说一句,另一个使用不同压缩方法的解决方案here