Javascript WebGL中从float32数组到uint16数组的转换

Javascript WebGL中从float32数组到uint16数组的转换,javascript,webgl,ieee-754,typed-arrays,Javascript,Webgl,Ieee 754,Typed Arrays,我有可以通过WebGL正确显示的数组纹理。但是,当我尝试将它们转换为UINT16阵列时,问题出现了 这是我的转换部分 var _floatToHalfFloat = function(input, offset) { var largestHalf = Math.pow(2, 30-15) * (1 + 1023/1024); var m = new ArrayBuffer(4); var n = new Float32Array(m); var o = new

我有可以通过WebGL正确显示的数组纹理。但是,当我尝试将它们转换为UINT16阵列时,问题出现了

这是我的转换部分

var _floatToHalfFloat = function(input, offset) {
    var largestHalf = Math.pow(2, 30-15) * (1 + 1023/1024);
    var m = new ArrayBuffer(4);
    var n = new Float32Array(m);
    var o = new Uint32Array(m);
    var f = 0.0;
    for (var i = input.length - 1 - offset; i >= 0;i--) {
        n[0] = input[i];
        f = o[0];
        // fast conversion of half
        // ref : ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf

        if (isNaN(input[i])) {
            input[i] = 0x7fff;
        } else if(n === Infinity || n > largestHalf) {
            input[i] = 0x7c00;
        } else if(n === -Infinity || n < -largestHalf) {
            input[i] = 0xfc00;
        } else if(n === 0) {
            input[i] = 0;
        } else {
            input[i] = ((f>>16)&0x8000)|((((f&0x7f800000)-0x38000000)>>13)&0x7c00)|((f>>13)&0x03ff);
        }
    }
    return new Uint16Array(input);
};
var\u floatToHalfFloat=函数(输入,偏移){
var largestHalf=数学功率(2,30-15)*(1+1023/1024);
var m=新阵列缓冲器(4);
var n=新阵列(m);
var o=新的UINT32阵列(m);
var f=0.0;
对于(var i=input.length-1-offset;i>=0;i--){
n[0]=输入[i];
f=o[0];
//半自动快速转换
//参考:ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf
if(isNaN(输入[i])){
输入[i]=0x7fff;
}else if(n==无穷大| | n>最大一半){
输入[i]=0x7c00;
}else if(n==-无穷大| | n<-最大一半){
输入[i]=0xfc00;
}else如果(n==0){
输入[i]=0;
}否则{
输入[i]=((f>>16)和0x8000)|(((f&0x7f800000)-0x38000000)>>13)和0x7c00)|((f>>13)和0x03ff);
}
}
返回新的UINT16阵列(输入);
};

当原始图像达到黑色时,我们可以在转换后的图像中看到饱和颜色(全红、全绿和/或全蓝)。我认为函数在0附近工作得不太好

我已经快速实现了

这表明最后两个信息不一致。0.000025被转换为无穷大(而不是0?),0本身被转换为2。这似乎不正确。维基百科说:“当你想编码一个零,你的尾数和指数应该是零。”。在您提供的代码中,尾数为零,但指数为16,这导致2(2^(16-15))

在调整了一点你的函数之后,所有的情况都被当作正常情况处理。这是由于if语句中的错误造成的。因此,我们没有:

} else if(n === 0) {
    input[i] = 0;
}
你可能想做这样的事情:

} else if(n[0] === 0) {
    input[i] = 0;
}
对于
n
变量的所有用法也是如此。但您仍然存在下溢问题。因此,您可能会发现可以接受这样做:

} else if(Math.abs(n[0]) < 0.0001) {
    input[i] = 0;
}
}else if(Math.abs(n[0])<0.0001){
输入[i]=0;
}
} else if(n[0] === 0) {
    input[i] = 0;
}
} else if(Math.abs(n[0]) < 0.0001) {
    input[i] = 0;
}