0

我正在使用 OpenGL ES 3.0 在 GPU 上创建流体动力学效果。使用 16 位浮点 FBO 我可以使效果正常工作。

我的问题是我的目标是不支持浮点纹理的 GPU。由于缺乏精确性,效果会崩溃。

这种效果只是二维的,所以我只读取和写入 FBO 的前 2 个通道。所以,我想知道是否有人成功地使用了 unsigned int 纹理的两个通道来增加额外的精度,以及这如何可能。

我目前的解决方案如下(GLSL 片段着色器片段),它根本不能正常工作:

#define read(vec) ((((vec).xy * 255.0) - 127.0) / 127.0) + (vec).zw / 255.0

vec4 write(vec2 vec)
{
    vec2 temp = ((vec * 127.0) + 127.0);
    vec2 a = floor(temp) / 255.0;
    vec2 b = mod(temp, 255.0);
    return vec4(a,b);
}

我认为主要问题可能是这样的任何方案都不可能写为零。

我希望有人已经解决了这个问题,或者可以看到此类问题的解决方案:)

4

1 回答 1

0

我假设您要存储的值介于 0.0 和 1.0 之间,但是您希望利用两个有效字节的数据获得更高的精度,对吧?

float read(vec2 rawData) 
{
    return rawData.x + rawData.y / 256.0;
}

vec2 write(float value)
{
    return vec2(value, floor(value * 256.0));
}

将输入/输出浮点数的限制设置为不同于 [0,1] 的任何值,只需将输出值映射到范围 [0,1] 并调用 write,或将输入值从 [0,1] 映射到 [ min,max] 这很简单:

// maps val from [fromMin,fromMax] to [toMin,toMax]
float lerp(float val, float fromMin, float fromMax, float toMin, float toMax)
{
    return toMin + (toMax - toMin) * (val - fromMin) / (fromMax - fromMin);
}

const vec2 minMax = vec2(-5.0, 10.0);

float readMapped(vec2 rawData)
{
    return lerp(read(rawData), 0.0, 1.0, minMax.x, minMax.y);
}

vec2 writeMapped(float value)
{
    return write(lerp(value, minMax.x, minMax.y, 0.0, 1.0));
}

对于双通道输入/输出,只需调用这些函数两次。

于 2013-10-30T10:45:29.783 回答