zoukankan      html  css  js  c++  java
  • 如何将一个float的小数部分保存成RGBA4个8位的byte

    shadow map的时候经常看到这两个函数

    vec4 packFloatToVec4i(const float value) {
      const vec4 bitSh = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);
      const vec4 bitMsk = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
      vec4 res = fract(value * bitSh);
      res -= res.xxyz * bitMsk;
      return res;
    }
    
    float unpackFloatFromVec4i(const vec4 value) {
      const vec4 bitSh = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
      return(dot(value, bitSh));
    }

    用于将0-1之间的深度值保存到RGBA8纹理里面。

    参考http://marcodiiga.github.io/encoding-normalized-floats-to-rgba8-vectors解释下原理:

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    首先上述方法只能编码/解码小数部分,也就是0-1之间的值。

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    IEEE754 floats

    也就是说:0.3可以分解成:{2^(-2) + 2^(-5) + 2^(-6)} + {2^(-9) + 2^(-10) + 2^(-13) + 2^(-14)} + {2^(-17) + 2^(-18) + 2^(-21) + 2^(-22)} + {2^(-25)}

    也就是说:如果我们能分别拿到上面的四部分,就能重新拼出这个0.3,那么如何得到每一部分的值呢?

    {2^(-25)}:这个比较简单,fract(0.3 << 24) >> 24; [fract函数为取小数部分]

    {2^(-17) + 2^(-18) + 2^(-21) + 2^(-22)}:(fract(0.3 << 16) - (fract(0.3 << 24) >> 8)) >> 16

    我们来分析一下:

    • a:=fract(0.3 << 16),先右移16位再取小数部分,这样得到的结果是({2^(-17) + 2^(-18) + 2^(-21) + 2^(-22)} {2^(-25)})<< 16
    • b:= fract(0.3 << 24) >> 8, 结果是{2^(-25)}<<16
    • 哈哈,(a - b)>>16 就得到了蓝色部分{2^(-17) + 2^(-18) + 2^(-21) + 2^(-22)} 

    依次类推:

    {2^(-9) + 2^(-10) + 2^(-13) + 2^(-14)} :(fract(0.3 << 8) - (fract(0.3 << 16) >> 8)) >> 8

    {2^(-2) + 2^(-5) + 2^(-6)}: (fract(0.3) - (fract(0.3 << 8) >> 8)) >> 0

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    To Sum Up : 上面的两个函数。

  • 相关阅读:
    怎么才能快捷的使用Beyond Compare
    Navicat遇到1130错误该如何处理
    做软件开发对这几款软件应该不陌生
    有什么方法可以快速找出文本的异同
    怎么给数据库管理工具设置数据同步
    程序员常常会用到的几款文本编辑器
    Java经典案例之-判断兔子的数量(斐波那契数列)
    菲波那切数列案例演示(递归方法)
    Java反射机制
    位运算,算术、逻辑运算详解-java篇
  • 原文地址:https://www.cnblogs.com/redips-l/p/11882887.html
Copyright © 2011-2022 走看看