Opengl es 在RGBA纹理中编码浮点数据

Opengl es 在RGBA纹理中编码浮点数据,opengl-es,webgl,Opengl Es,Webgl,我写了一些基于浮点纹理的WebGL代码。但是,在其他一些设备上测试时,我发现对OES_texture_float扩展的支持并不像我想象的那样广泛。所以我在寻找退路 我目前有一个亮度浮点纹理,其值介于-1.0和1.0之间。我想用一种纹理格式对这些数据进行编码,这种格式在WebGL中没有任何扩展,因此可能是一种简单的RGBA无符号字节纹理 我有点担心潜在的性能开销,因为需要这种退步的情况是较旧的智能手机或平板电脑,它们的GPU已经比现代台式电脑弱得多 如何在WebGL中不支持浮点纹理的设备上模拟浮点

我写了一些基于浮点纹理的WebGL代码。但是,在其他一些设备上测试时,我发现对OES_texture_float扩展的支持并不像我想象的那样广泛。所以我在寻找退路

我目前有一个亮度浮点纹理,其值介于-1.0和1.0之间。我想用一种纹理格式对这些数据进行编码,这种格式在WebGL中没有任何扩展,因此可能是一种简单的RGBA无符号字节纹理

我有点担心潜在的性能开销,因为需要这种退步的情况是较旧的智能手机或平板电脑,它们的GPU已经比现代台式电脑弱得多


如何在WebGL中不支持浮点纹理的设备上模拟浮点纹理

这应该是一个很好的起点:


它用于编码到0.0到1.0,但重新映射到所需范围应该很简单。

如果您知道范围是-1到+1,最简单的方法就是将其转换为某个整数范围,然后再转换回来。它将0到1之间的值打包为32位颜色

const vec4 bitSh = vec4(256. * 256. * 256., 256. * 256., 256., 1.);
const vec4 bitMsk = vec4(0.,vec3(1./256.0));
const vec4 bitShifts = vec4(1.) / bitSh;

vec4 pack (float value) {
    vec4 comp = fract(value * bitSh);
    comp -= comp.xxyz * bitMsk;
    return comp;
}

float unpack (vec4 color) {
    return dot(color , bitShifts);
}
然后


它的可能副本是可行的,但是由于GLSL 1.00标准的限制,导致了很多混乱,该标准预处理浮点文本,使其看起来好像不起作用。注意,我们找到了一条实现精确逐位转换的途径。这不适用于线性滤波或任何后处理滤波(如模糊)
const float rangeMin = -1.;
const float rangeMax = -1.;

vec4 convertFromRangeToColor(float value) {
   float zeroToOne = (value - rangeMin) / (rangeMax - rangeMin);
   return pack(value);
}

float convertFromColorToRange(vec4 color) {
   float zeroToOne = unpack(color);
   return rangeMin + zeroToOne * (rangeMax - rangeMin);
}