float Pack2x16Int(ivec2 val) {
    val = clamp(val, 0, 65535);
    uvec2 ui = val;
    ui.x <<= 16;
    uint pack = ui.x | ui.y;
    return uintBitsToFloat(pack);
}

ivec2 Unpack2x16Int(float pack) {
    uint packInt = floatBitsToUint(pack);
    uvec2 ui;
    ui.x = packInt >> 16;
    ui.y = packInt & 0xffff;
    return ivec2(ui);
}

float Pack4x8UInt(uvec4 ui) {
    ivec4 val = clamp(ivec4(ui), 0, 255);  // clamp -> uint:error int:works
    ui = val;
    ui.x <<= 24;
    ui.y <<= 16;
    ui.z <<= 8;
    uint pack = ui.x | ui.y | ui.z | ui.w;
    return uintBitsToFloat(pack);
}

uvec4 Unpack4x8Uint(float pack) {
    uint packInt = floatBitsToUint(pack);
    uvec4 ui;
    ui.x = packInt >> 24;
    ui.y = (packInt & 0xff0000) >> 16;
    ui.z = (packInt & 0xff00) >> 8;
    ui.w = packInt & 0xff;
    return ui;
}

uint Pack2x8uiTo16ui(uvec2 ui) {
    ivec2 val = clamp(ivec2(ui), 0, 255);  // clamp -> uint:error int:works
    ui = val;
    ui.x <<= 8;
    uint pack = ui.x | ui.y;
    return pack;
}

uvec2 Unpack16uiTo2x8ui(uint packInt) {
    uvec2 ui;
    ui.x = (packInt & 0xff00) >> 8;
    ui.y = packInt & 0xff;
    return ui;
}

/*
float Pack2x16Uint(uvec2 ui) {
    ivec2 x = clamp(ivec2(ui), 0, 65535);  // clamp -> uint:error int:works
    ui = x;
    ui.x <<= 16;
    uint pack = ui.x | ui.y;
    return uintBitsToFloat(pack);
}

uvec2 Unpack2x16Uint(float pack) {
    uint packInt = floatBitsToUint(pack);
    uvec2 ui;
    ui.x = packInt >> 16;
    ui.y = packInt & 0xffff;
    return ui;
}
*/