转换GLSL中的intBitsToFloat和Javascript中的floatBitsToInt

转换GLSL中的intBitsToFloat和Javascript中的floatBitsToInt,javascript,bit-manipulation,webgl,Javascript,Bit Manipulation,Webgl,我试图使用intBitsToFloat(我使用highp output Float vector)将GLSL 3.3着色器中的整数标识符编码为浮点输出,然后使用readPixels将该值放入pixelData=new Float32Array(4)。然后我在JS中使用floatToIntBits(pixelData[0])将其解码回Int,其中 var int8 = new Int8Array(4) var int32 = new Int32Array(int8.buffer, 0,

我试图使用
intBitsToFloat
(我使用highp output Float vector)将GLSL 3.3着色器中的整数标识符编码为浮点输出,然后使用
readPixels
将该值放入
pixelData=new Float32Array(4)
。然后我在JS中使用
floatToIntBits(pixelData[0])
将其解码回Int,其中

var int8    = new Int8Array(4)
var int32   = new Int32Array(int8.buffer, 0, 1)
var float32 = new Float32Array(int8.buffer, 0, 1)

var floatToIntBits = function (f) {
    float32[0] = f
    return int32[0]
}
现在我得到了一个非常奇怪的结果。即当我:

  • 在GLSL中编码范围
    [0,2^23-1]
    中的一个值,我总是在JS中得到
    0
  • 在GLSL中编码范围
    [2^23,…[
    中的值,我在JS中得到正确的值
  • 在GLSL中编码范围
    [-2^23+1,-1]
    中的值,我总是在JS中得到
    -2^23+1
  • 在GLSL中编码范围
    ]…,-2^23]
    中的值,我在JS中得到正确的结果

有人知道为什么会这样吗

我猜这是因为您使用的是函数,而不是直接从
readPixels
的结果中读取值。Javascript只有1个数字类型,实际上是C/C++
double
,因此从类型Darray中读取任何值时,它都会转换为
double

让我们在没有GLSL的情况下进行测试

const i32=新的Int32Array([
123,
-123,
20000000,
-20000000,
]);
log(i32[0],i32[1],i32[2],i32[3]);
const f32=新的Float32Array(i32.buffer);
var int8=新的Int8Array(4)
var int32=新的Int32Array(int8.buffer,0,1)
var float32=新的Float32Array(int8.buffer,0,1)
var floatToIntBits=函数(f){
float32[0]=f
返回int32[0]
}

log(floatToIntBits(f32[0])、floatToIntBits(i32[1])、floatToIntBits(i32[2])、floatToIntBits(i32[3])GLSL 3.3在WebGL中不存在。WebGL2仅支持GLSL ES 3.0。无论如何,我只是好奇,如果你想要int,为什么不通过帧缓冲区将int写入int格式的纹理,然后用readPixels读取int@哦,我确信WebGL2.0是基于3.3的,我的错。有趣的是,
intBitsToFloat
在我的GLSL中可用,但它可能不是当时的标准和特定于供应商的。关于直接传递Ints。。。我确信这是不可能的!我在这里指的是内部格式/格式/类型兼容性表(它没有列出RGBA32I类型):该表不完整还是缺少一些信息?该表仅适用于采用
TexImageSource
(图像、画布或视频等HTMLElement)的
texImage2D
版本。仅采用数组缓冲区的
texImage2D
版本支持OpenGL ES 3.0规范中列出的所有格式,其中列出了该规范的副本
intBitsToFloat
是GLSL 3.0 ES的一部分,因此它是完全标准的。只是指出,如果你期待GLSL 3.3,你会失望的。WebGL2是@gman,澄清了很多,非常感谢您的帮助!我被表格弄糊涂了,没有注意到它只是针对一些特定的参数,因为它只是从这些文档链接而来的:那些文档是错误的。我会去修正它们的,这是一个很好的猜测,但我非常小心,没有进行这种隐式转换。正如我在问题中所说的那样,我使用它,即
floatToIntBits(pixelData[0])
,没有任何附加变量。我在没有GLSL的情况下也进行了测试,效果很好。有趣的是,当我从GLSL发送小于
2^23
的值时,我只会在JS中用0填充缓冲区(检查类型化数组后面的缓冲区)。当然,我的问题是通过上面的评论中的Int类型解决的,但我仍然想知道这里发生了什么。我会进一步调查的!谢谢,您不需要显式变量。您从缓冲区中取出并将其传递给函数的事实意味着,从您将其从缓冲区中取出并传递给函数的那一刻起,它就已经转换为双倍。不要把它作为一个浮点数从缓冲区中拉出来,把它作为一个整数从缓冲区中拉出来!啊,毕竟这很简单也很明显。谢谢@gman!