I'm using OpenGL ES 3.0 to create a fluid dynamics effect on the GPU. Using a 16 bit floating point FBO I can make the effect work correctly.
My problem is I am targeting the GPU that does not support floating point textures. The effect crumbles under the lack of precision.
This effect is only two dimensional so I am only reading from and writing to the first 2 channels of an FBO. So, I am wondering if anyone has successfully used two channels of an unsigned int texture to add extra precision, and how this might be possible.
My current solution is as follows (GLSL fragment shader snippet) , and it doesn't work well at all:
#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);
}
I think the main problem may be that with any scheme like this it is impossible to write zero.
I'm hoping someone has solved this already, or can see the solution to such a problem :)
I assume the values you want to store are between 0.0 and 1.0, but you want to have more precision utilizing two effective bytes of data right?
float read(vec2 rawData)
{
return rawData.x + rawData.y / 256.0;
}
vec2 write(float value)
{
return vec2(value, floor(value * 256.0));
}
Setting the limits of the input/output floats to anything different than [0,1] would simply require mapping the output value into the range [0,1] and calling write, or mapping the input value from [0,1] to [min,max] which is simple:
// 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));
}
Simply call these functions twice for two-channel input/output.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments