如何将vec4 rgba值转换为浮点值?

Xav*_*ier 8 opengl-es webgl

我在纹理中打包了一些浮点数据作为unsigned_byte,这是我在webgl中的唯一选择.现在我想在顶点着色器中解压缩它.当我采样一个像素时,我得到一个vec4,它实际上是我的一个浮点数.如何从vec4转换为浮点数?

twe*_*ter 13

以下代码专门针对使用OpenGL ES 2.0的iPhone 4 GPU.我没有使用WebGL的经验,因此我无法声称知道代码在该上下文中的工作方式.此外,这里的主要问题是highp float不是32位而是24位.

我的解决方案是片段着色器 - 我没有在顶点着色器中尝试它,但它不应该是任何不同.为了使用你需要从sampler2d统一得到RGBA纹素,并确保每个R,G,B和A通道的值在0.0到255.0之间.这很容易实现如下:

highp vec4 rgba = texture2D(textureSamplerUniform, texcoordVarying)*255.0;
Run Code Online (Sandbox Code Playgroud)

您应该知道,机器的字节顺序将决定字节的正确顺序.上面的代码假定浮点数以big-endian顺序存储.如果您发现结果有误,那么只需通过写入来交换数据的顺序

rgba.rgba=rgba.abgr;
Run Code Online (Sandbox Code Playgroud)

紧接在您设置它的行之后.或者交换rgba上的索引.我认为上述内容更具有直观性,并且不容易出现粗心错误.我不确定它是否适用于所有给定的输入.我测试了大量的数字,发现decode32和encode32不是完全相反的.我也遗漏了用来测试它的代码.

#pragma STDGL invariant(all) 

highp vec4 encode32(highp float f) {
    highp float e =5.0;

    highp float F = abs(f); 
    highp float Sign = step(0.0,-f);
    highp float Exponent = floor(log2(F)); 
    highp float Mantissa = (exp2(- Exponent) * F);
    Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa));
    highp vec4 rgba;
    rgba[0] = 128.0 * Sign  + floor(Exponent*exp2(-1.0));
    rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0);  
    rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0)));
    rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0)));
    return rgba;
}

highp float decode32(highp vec4 rgba) {
    highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
    highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0; 
    highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
    highp float Result =  Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 )); 
    return Result;
}

void main()  
{  
    highp float result;

    highp vec4 rgba=encode32(-10.01);
    result = decode32(rgba);
}
Run Code Online (Sandbox Code Playgroud)

以下是我发现有用的IEEE精度的一些链接.Link1.Link2.Link3.