【问题标题】:decode rgb value to single float without bit-shift in glsl将 rgb 值解码为单个浮点数,而无需在 glsl 中进行位移
【发布时间】:2011-08-01 00:41:40
【问题描述】:

我目前正忙于 webgl 中的延迟着色,我需要将 3 个整数值(在 [0..256] = 256^3 范围内)解码为单个 32 位浮点数并稍后对其进行编码。因为这是针对 WebGL 的,所以必须在没有按位运算的情况下完成。精度对我来说并不重要(但我认为可以实现)。

这是我所拥有的,但我认为这是错误的,因为我存储编码值的纹理的精度。

float packColor(vec3 color) {   return (color.r + (color.g*256.) + (color.b*256.*256.)) / (256.*256.*256.); }

vec3 decodeColor(float f) { 
float b = floor(f * 256.0);
float g = floor(f * 65536.0) - (b*256.);
float r = (floor(f * 16777216.0) - (b*65536.)) - (g*256.);
return vec3(r, g, b)/ 256.0;//vec3(r, g, b) / 256.0;  }

谢谢..

【问题讨论】:

  • 我认为您混淆了“编码”和“解码”这两个词的含义......

标签: floating-point int rgb webgl encode


【解决方案1】:

我知道这是一个老问题,但我遇到了同样的问题,我会发布解决方案,以防将来有人需要它

float packColor(vec3 color) {
    return color.r + color.g * 256.0 + color.b * 256.0 * 256.0;
}

vec3 unpackColor(float f) {
    vec3 color;
    color.b = floor(f / 256.0 / 256.0);
    color.g = floor((f - color.b * 256.0 * 256.0) / 256.0);
    color.r = floor(f - color.b * 256.0 * 256.0 - color.g * 256.0);
    // now we have a vec3 with the 3 components in range [0..255]. Let's normalize it!
    return color / 255.0;
}

只要用 packColor 打包的浮点数不在 [0, 1] 范围内,而是在 [0, 16777215] 范围内,您就不应该有任何精度问题。但是如果你在 [0,1] 范围内对浮点数进行归一化,你就会遇到精度问题!

请注意,您也不能存储 alpha(以这种方式),因为 highp 浮点数是 24 位长,而不是通常使用的 32 位。 在顶点着色器中您可以毫无问题地使用此代码(默认精度为高),但在片段着色器中您必须确保只使用高精度!

【讨论】:

  • 感谢您对范围的评论,我遇到了这些精度问题!
【解决方案2】:

像这样?

function pack(color)  { return color.r + color.g * 256 + color.b * 256 * 256; }

function unpack(f)  {
    var b = Math.floor(f / (256 * 256));
    var g = Math.floor((f - b * 256 * 256) / 256);
    var r = Math.floor(f % 256);
    return vec3(r, g, b);
}

【讨论】:

  • 看起来它可以在算法上工作,但我认为提问者希望在 GLSL 中使用它。
【解决方案3】:

@Makers_F:感谢 unpackColor 函数的 GLSL 代码,但似乎 bluered 组件颠倒了。

对我来说,下面的代码就像一个魅力:

vec3 unpackColor(float f) 
{
    vec3 color;

    color.r = floor(f / 256.0 / 256.0);
    color.g = floor((f - color.r * 256.0 * 256.0) / 256.0);
    color.b = floor(f - color.r * 256.0 * 256.0 - color.g * 256.0);

    // now we have a vec3 with the 3 components in range [0..256]. Let's normalize it!
    return color / 256.0;
}

【讨论】:

  • 请注意,这不适用于 OP 的 packColor 代码 - 它假定您也以相反的方式打包了 R 和 B。
猜你喜欢
  • 1970-01-01
  • 2017-12-01
  • 2021-10-04
  • 2022-01-18
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
相关资源
最近更新 更多