如何快速将一个float打包为4个字节?

2024-04-20

我一直在寻找一种在 WebGL 纹理上存储浮动的方法。我找到了一些解决方案 http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/在互联网上,但那些只处理 [0..1) 范围内的浮点数。我希望能够存储任意浮点数,为此,需要扩展这样的函数来存储指数(例如在第一个字节上)。不过,我不太明白它们是如何工作的,所以如何做到这一点并不明显。简而言之:

将浮点数打包为 4 个字节的有效算法是什么?


它并不快,但可行。 (请注意,GLSL 1.00 浮点文字在编译器中存在转换错误)。

struct Bitset8Bits {
    mediump vec4 bit0;
    mediump vec4 bit1;
    mediump vec4 bit2;
    mediump vec4 bit3;
    mediump vec4 bit4;
    mediump vec4 bit5;
    mediump vec4 bit6;
    mediump vec4 bit7;
};


vec4 when_gt (vec4 l, vec4 r) {
  return max(sign(l - r), 0.0);
}


Bitset8Bits unpack_4_bytes (lowp vec4 byte) {
    Bitset8Bits result;

    result.bit7 = when_gt(byte, vec4(127.5));
    vec4 bits0to6 = byte - 128.0 * result.bit7;

    result.bit6 = when_gt(bits0to6, vec4(63.5));
    vec4 bits0to5 = bits0to6 - 64.0 * result.bit6;

    result.bit5 = when_gt(bits0to5, vec4(31.5));
    vec4 bits0to4 = bits0to5 - 32.0 * result.bit5;

    result.bit4 = when_gt(bits0to4, vec4(15.5));
    vec4 bits0to3 = bits0to4 - 16.0 * result.bit4;

    result.bit3 = when_gt(bits0to3, vec4(7.5));
    vec4 bits0to2 = bits0to3 - 8.0 * result.bit3;

    result.bit2 = when_gt(bits0to2, vec4(3.5));
    vec4 bits0to1 = bits0to2 - 4.0 * result.bit2;

    result.bit1 = when_gt(bits0to1, vec4(1.5));
    vec4 bit0 = bits0to1 - 2.0 * result.bit1;

    result.bit0 = when_gt(bit0, vec4(0.5));

    return result;
}

float when_gt (float l, float r) {
  return max(sign(l - r), 0.0);
}




vec4 pack_4_bytes (Bitset8Bits state) {

  vec4 data;

  data = state.bit0
    + 2.0 * state.bit1
    + 4.0 * state.bit2
    + 8.0 * state.bit3
    + 16.0 * state.bit4
    + 32.0 * state.bit5
    + 64.0 * state.bit6
    + 128.0 * state.bit7;

  return data;
}

vec4 brians_float_pack (
    float original_value) {

    // Remove the sign
    float pos_value = abs(original_value);

    float exp_real = floor(log2(pos_value));
    float multiplier = pow(2.0, exp_real);
    float normalized = pos_value / multiplier - 1.0;

    float exp_v = exp_real + 127.0;
    // if exp_v == -Inf -> 0
    // if exp_v == +Inf -> 255
    // if exp_v < -126.0 -> denormalized (remove the "1")
    // otherwise + 127.0;

    Bitset8Bits packed_v;

    packed_v.bit7.a =
        step(sign(original_value) - 1.0, -1.5); // pos

    // Exponent 8 bits

    packed_v.bit6.a = when_gt(exp_v, 127.5);
    float bits0to6 = exp_v - 128.0 * packed_v.bit6.a;

    packed_v.bit5.a = when_gt(bits0to6, 63.5);
    float bits0to5 = bits0to6 - 64.0 * packed_v.bit5.a;

    packed_v.bit4.a = when_gt(bits0to5, 31.5);
    float bits0to4 = bits0to5 - 32.0 * packed_v.bit4.a;

    packed_v.bit3.a = when_gt(bits0to4, 15.5);
    float bits0to3 = bits0to4 - 16.0 * packed_v.bit3.a;

    packed_v.bit2.a = when_gt(bits0to3, 7.5);
    float bits0to2 = bits0to3 - 8.0 * packed_v.bit2.a;

    packed_v.bit1.a = when_gt(bits0to2, 3.5);
    float bits0to1 = bits0to2 - 4.0 * packed_v.bit1.a;

    packed_v.bit0.a = when_gt(bits0to1, 1.5);
    float bit0 = bits0to1 - 2.0 * packed_v.bit0.a;

    packed_v.bit7.b = when_gt(bit0, 0.5);

    // Significand 23 bits

    float factor = 0.5;
    // 0.4999999
    
    // Significand MSB bit 22:
    packed_v.bit6.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit6.b;
    factor = 0.5 * factor;

    packed_v.bit5.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit5.b;
    factor = 0.5 * factor;

    packed_v.bit4.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit4.b;
    factor = 0.5 * factor;

    packed_v.bit3.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit3.b;
    factor = 0.5 * factor;

    packed_v.bit2.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit2.b;
    factor = 0.5 * factor;

    packed_v.bit1.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit1.b;
    factor = 0.5 * factor;

    packed_v.bit0.b =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit0.b;
    factor = 0.5 * factor;


    packed_v.bit7.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit7.g;
    factor = 0.5 * factor;

    packed_v.bit6.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit6.g;
    factor = 0.5 * factor;

    packed_v.bit5.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit5.g;
    factor = 0.5 * factor;

    packed_v.bit4.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit4.g;
    factor = 0.5 * factor;

    packed_v.bit3.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit3.g;
    factor = 0.5 * factor;

    packed_v.bit2.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit2.g;
    factor = 0.5 * factor;

    packed_v.bit1.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit1.g;
    factor = 0.5 * factor;

    packed_v.bit0.g =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit0.g;
    factor = 0.5 * factor;


    packed_v.bit7.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit7.r;
    factor = 0.5 * factor;

    packed_v.bit6.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit6.r;
    factor = 0.5 * factor;

    packed_v.bit5.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit5.r;
    factor = 0.5 * factor;

    packed_v.bit4.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit4.r;
    factor = 0.5 * factor;

    packed_v.bit3.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit3.r;
    factor = 0.5 * factor;

    packed_v.bit2.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit2.r;
    factor = 0.5 * factor;

    packed_v.bit1.r =
        when_gt(normalized, factor - 0.00000005);
    normalized = normalized - factor * packed_v.bit1.r;
    factor = 0.5 * factor;

    // LSB bit 0
    packed_v.bit0.r =
        when_gt(normalized, factor - 0.00000005);

    vec4 result = pack_4_bytes(packed_v);

    return result;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何快速将一个float打包为4个字节? 的相关文章

随机推荐

  • 如何更改故事板上视图控制器的大小以进行编辑?

    我有一个简单的问题 我花了无数的时间试图解决这个问题 如何更改 Xcode Storyboard 中视图控制器的大小以进行编辑 我有一个大的表格 调查问卷 我想放在我的视图控制器上 但我根本无法使用情节提要给我的当前大小 此外 提供的尺寸
  • Shutil.move IOError:[Errno 2] - 当处于循环中时[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 如果我单独
  • 配置 sbt 项目以在“sbt run”中包含外部 Main 方法

    创建一个依赖于外部 jar 的 sbt 项目对我来说很常见 并且旨在使用外部 jar 中的 Main 方法运行 目前 我只是使用 run main xxx 运行它 但我更希望能够将 Main 方法包含在 sbt 提供的 run 选项列表中
  • Django Forms 视图中的自定义错误消息

    这是我的观点 if request method POST form TeacherRegister request POST Gets school object from email domain email form email va
  • TinyMCE - 外部工具栏位置

    我正在尝试与 TinyMCE 合作创建一个多文本框 点击编辑类型的图形内容编辑器 我已经使用 TinyMCE 来添加和删除它们 定位它们并调整它们的大小 单击以编辑它们等等 但有一件事困扰着我 那就是工具栏 我有一个外部工具栏 我试图将其放
  • 检查元素是否在视图中,如果是,则添加类

    我想堆叠元素 当它们进入视图时 它会添加类 active 我不想删除该类 因此一旦添加它 它就会保留在那里 大概的概念 If default在滚动视图中添加类 active 因此 当您向下滚动时 它会在类进入视图时添加该类 在查看了类似的问
  • 模块化 AngularJS 应用程序:一个或多个 AngularJS 模块?

    我尝试使用 AngularJS 构建一个模块化应用程序 我的第一个想法是使用这种文件夹结构按功能对每个模块进行分组 core controllers js directives js app js modules users control
  • C++ 错误 C2040?

    错误信息 这是什么意思 我该如何解决它 错误 C2040 int 与 const char 2 的间接级别不同 Code include
  • 找不到方法 commandLine()

    我正在尝试将预构建 shell 脚本添加到我的 gradle Android Studio 构建中 我已添加以下内容app build gradle task prePreBuild lt lt commandLine ls preBuil
  • 根据列条件连接数据框行

    为了后续的讨论 我将参考下面的示例数据框 现在 我希望实现的是将所有相似的数据包时间分组 即所有 7s 12s 等 此外 PacketTime字段应包含最小值和最大值的差异 max PacketTime min PacketTime 以及F
  • Fortran90 数组将空白值读取为 null

    我正在读取外部文本文件的数据 30 行 7 列 每行用 分隔 我缺少表示为 的值 当我将数据读入二维数组时 缺失值被 0 00 替换 但数据中也有 0 00 值 当我计算平均值时 计数 项目数 n 显示为计数 缺失值的数量 我如何动态选择缺
  • 调试断言失败

    我不断遇到这种情况 Debug assertions failed 当我在调试模式下运行程序时出错 我尝试在 Visual C 网站上查找此错误 但这些解释对我来说太先进了 而且它们与我对问题的最佳猜测没有任何相似之处 我已经检查了我的代码
  • 使用 Java 查找句子中的确切单词

    我正在编写一个代码来识别文本中的国家 地区名称 我正在使用一本包含国家名称的字典India America Sri Lanka 我目前正在使用text contains key with key从字典中 然而 即使对于像这样的字符串 这也会
  • 在 C 语言中,stdout 缓冲区的大小是多少?

    今天我了解到 stdout 在设置为终端时是行缓冲的 并且在不同情况下是缓冲的 因此 在正常情况下 如果我使用 printf 而不终止 n 只有当缓冲区已满时 它才会打印在屏幕上 如何获得这个缓冲区的大小 它有多大 实际大小由各个实现定义
  • “SolidBrush”参数类型对于格式化属性“Foreground”无效。参数名称:值

    我尝试在调用方法中更改颜色文本 RichTextBox wpf 但我遇到了一些麻烦 我的麻烦是 SolidBrush 参数类型对于格式化属性 Foreground 无效 参数名称 值 My code MethodInvoker action
  • 如何从 2 个数组创建地图?

    我有一个字符串数组和一个整数数组 如何使用第一个作为键 第二个作为值来创建地图 val keys arrayOf butter milk apples val values arrayOf 5 10 42 val map Map
  • 滚动“返回顶部”链接时显示/隐藏 div

    我无法让我的 转到顶部 id arrow updiv 在打开时消失 例如页面顶部 在页面顶部我得到了 所以我想要arrow up div to visible show slow 当不在页面顶部时 var tmp window height
  • Spring中如何从WebRequest获取请求的URI?

    我正在使用以下方法处理 REST 异常 ControllerAdvice and ResponseEntityExceptionHandler在 Spring Rest Web 服务中 到目前为止 一切都工作正常 直到我决定添加URI路径
  • php 的内容长度标头被覆盖!

    我试图弄清楚为什么 php 的 Content Length 标头被覆盖 这是演示 php 获取标头的请求 curl I http someserver com demo php HTTP 1 1 200 OK Date Tue 19 Ju
  • 如何快速将一个float打包为4个字节?

    我一直在寻找一种在 WebGL 纹理上存储浮动的方法 我找到了一些解决方案 http aras p info blog 2009 07 30 encoding floats to rgba the final 在互联网上 但那些只处理 0