【问题标题】:Pack 4 8-bit unsigned integer to a 32-bit float将 4 个 8 位无符号整数打包为 32 位浮点数
【发布时间】:2014-10-01 22:59:21
【问题描述】:

我正在开发一个基于 webgl 的渲染器,正如标题所说,我需要将 4 个 8 位无符号整数打包为 32 位浮点数, 我写了以下代码:

//pack 4 8-bit integer to a float
function packIntsToFloat(i1, i2, i3, i4) {

    //ensure 32-bit allocation
    var ints = new Uint32Array(4);

    ints[0] = i1;
    ints[1] = i2;
    ints[2] = i3;
    ints[3] = i4;

    ints[0] <<= 24;
    ints[1] <<= 16;
    ints[2] <<= 8;

    ints[3] |= ints[0] | ints[1] | ints[2];      

    //convert to float
    var f = new Float32Array(1);
    f[0] = ints[3];

    return f[0];
}

//unpack 4 8-bit integer from a float
function unPackIntsFromFloat(f) {

    var i = new Uint32Array(4);
    i[3] = f;

    var mask_7_to_0 = 255;
    var mask_15_to_8 = mask_7_to_0 << 8;
    var mask_23_to_16 = mask_15_to_8 << 8;
    var mask_31_to_24 = mask_23_to_16 << 8;

    i[0] = (i[3] & mask_31_to_24 ) >>> 24;
    i[1] = (i[3] & mask_23_to_16 ) >>> 16;
    i[2] = (i[3] & mask_15_to_8 ) >>> 8;
    i[3] = (i[3] & mask_7_to_0);        

    return new Uint8Array(i);
}

但除非跳过我需要的东西,否则它不会起作用:

//convert to float
var f = new Float32Array(1);
f[0] = ints[3];

我知道 IEEE 标准,但不应该对位进行任何更改,只是将它们解释为一个值。 提前谢谢你。

【问题讨论】:

    标签: javascript floating-point webgl


    【解决方案1】:

    所有TypedArrays 都只是类型不可知ArrayBuffer 的视图,因此您可以简单地使用它:

    包装: new Float32Array((new Uint8Array([i1,i2,i3,i4])).buffer)[0];

    开箱: new Uint8Array((new Float32Array([f])).buffer);

    有关更多信息,请参阅ArrayBufferView 的文档。

    【讨论】:

    • 非常感谢!非常非常有帮助,你能解释一下我写的代码的行为吗?
    【解决方案2】:

    你到底想做什么?

    例如,您是否尝试将浮点位置和无符号字节颜色放在同一个缓冲区中?在这种情况下,对同一个缓冲区进行 2 个视图。示例:

    var numVerts = 10;
    var bytesPerPosition = 3 * 4;  // x,y,z * 4 bytes per float
    var bytesPerColor = 4;  // r,g,b,a 1 byte each
    var bytesPerVertex = bytesPerPosition * bytesPerColor;
    var sizeOfBuffer = numVertex * bytesPerVertex;
    var offsetOfPositions = 0;
    var offsetOfColor = bytesPerPosition;
    
    // now make the buffer.
    var asUint8 = new Uint8Array(sizeOfBuffer);
    var asFloat = new FloatArray(asUint8.buffer);
    

    您现在对同一个缓冲区有 2 个视图。因此,例如设置一个你会有效地做的位置

    var strideInFloats = bytesPerVertex / 4;
    
    function setPosition(index, x, y, z) {
      var offset = strideInFloats * index;
      asFloat[offset    ] = x;
      asFloat[offset + 1] = y;
      asFloat[offset + 2] = z;
    }
    

    设置颜色会很有效

    function setColor(index, r, g, b, a) {
      var offset = strideInBytes * index + offsetToColor;
      asUint8[offset    ] = r;
      asUint8[offset + 1] = g;
      asUint8[offset + 2] = b;
      asUint8[offset + 3] = a;
    }
    

    在设置属性时,你会做类似的事情

    gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, bytesPerVertex, 
                           offsetOfPosition);
    gl.vertexAttribPointer(colorLoc, 4, gl.UNSIGNED_BYTE, true, bytesPerVertex, 
                           offsetOfColor);
    

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 2014-10-10
      • 1970-01-01
      • 2011-10-25
      • 2015-03-25
      • 1970-01-01
      相关资源
      最近更新 更多