我在纹理中打包了一些浮点数据作为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.
归档时间: |
|
查看次数: |
11246 次 |
最近记录: |