2013-10-30 72 views
0

我使用OpenGL ES 3.0在GPU上創建流體動力學效果。 使用16位浮點FBO我可以使該效果正常工作。16位浮點紋理

我的問題是我針對的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); 
} 

我認爲主要的問題可能是與任何像這樣的方案是不可能的寫零。

我希望有人已經解決了這一點,還是可以看到解決這樣的問題:)

回答

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],並調用寫入,或從映射的輸入值[0,1]至[最小,最大]這很簡單:

// 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)); 
} 

只需調用這些函數兩次輸入/輸出雙通道。