#1 Members - Reputation: 271
Posted 20 April 2012 - 01:25 PM
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine
#2 Members - Reputation: 791
Posted 20 April 2012 - 02:53 PM
What about packing 8 floats into an GL_RG32UI? (two unsigned ints with each 4 byte, which means 8 bit per float.)
This could save you some instructions, since you could pack with the little helper below 4 floats simultaneously (instead of just 2 if you would use 16-bit floats).
Would that help you?
// vec4 to rgba8Unorm
uint pack(vec4 value)
{
// Ensure values are in [0..1] and make NaNs become zeros.
value = min(max(value,0.0f), 1.0f);
// Each component gets 8 bit.
value = value * 255 + 0.5f;
value = floor(value);
// Pack into one 32 bit uint.
return (((uint)value.x) |
(((uint)value.y)<< 8) |
(((uint)value.z)<<16) |
(((uint)value.w)<<24) );
}
// rgba8Unorm to vec4
vec4 unpack(uint value)
{
return vec4((float) (value & 0x000000ff) / 255,
(float) ((value>> 8) & 0x000000ff) / 255,
(float) ((value>>16) & 0x000000ff) / 255,
(float) ((value>>24) & 0x000000ff) / 255);
}(Haven't checked the code... Just ported from HLSL to GLSL.)Cheers!
Acagamics e.V. – IGDA Student Game Development Club (University of Magdeburg, Germany)
#3 Members - Reputation: 271
Posted 20 April 2012 - 04:17 PM
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine
#4 Members - Reputation: 595
Posted 20 April 2012 - 11:11 PM
Since when?Not an option unfortunately since you can't use multiple render targets bound to an FBO which are of different texture format.
There was (Not sure whether it still is (*). I think the limitation was lifted, but not sure) a requirement of all targets having the same total bits per texel - but no requirements on how the bits are used (ie. R32F is the same size as RGBA8).
*) After searching around a bit: not sure when, but seems the last restriction was lifted at some point - so, any and all of the required formats ( http://www.opengl.org/wiki/Image_Formats#Texture_and_Renderbuffer ) are OK. have not yet used mismatching (ex: RGBA8 + RGBA32F) ones myself.
#5 Members - Reputation: 292
Posted 23 April 2012 - 01:48 AM
#6 Moderators - Reputation: 13598
Posted 23 April 2012 - 04:15 AM
I've never done this, but it should be possible. All the required details should be on the wikipedia page on floating point (and on logarithms). I imagine a packing function would look something like:Is there a way to pack 2 float values into 1 16-bit float texture color component? Since that way a single GBuffer texture could hold 8 float values of limited accuracy. Somebody said one to use "float output = floor( floatValue1 * 255.0 ) + floatValue2;". Somehow I don't think that would do the trick as 16-bit float is not stored in a way for this to have much of an effect. I presume the sign bit, exponent bits and a couple of value bits would have to be used to store one value and the rest for the second.
half PackHalf( float A/*one bit*/, float B/*5 bits*/, float C/*10 bits*/ )//all inputs in 0-1 range
{
float s = A*2-1;// -1/+1
float e = lerp( -13, 14, B );
float f = lerp( 1024, 2047, C );
return s*f*pow(2,e);
}//N.B. most likely contains mistakes
#7 Members - Reputation: 271
Posted 23 April 2012 - 03:41 PM
Because in the original specs FBOs didn't allow for such combinations and the five an FBO Incomplete error. There's some extension I think that is supposed to remove this restriction but I had no luck so far getting a mix to work reliably across different hardware so I'm hesitant to rely on such format combination although it would be of an advantage.In DX10+ it's perfectly legal and usual to bind several render targets of completely different formats and bit depths and numbers of channels (such as RGBA8 + RGBA32F + RG16F + whatever) to output merger simultaneously and get perfect results. The only restriction is the same resolution (width * height * array slices). I don't see why this wouldn't work with OpenGL 3+ as SM4.0+ HW apparently supports this.
I see where you come from with this one. So an 8+8 bit (or 7+7 bit) encoding doesn't seem possible, only a 5+10 encoding.I've never done this, but it should be possible. All the required details should be on the wikipedia page on floating point (and on logarithms). I imagine a packing function would look something like:Is there a way to pack 2 float values into 1 16-bit float texture color component? Since that way a single GBuffer texture could hold 8 float values of limited accuracy. Somebody said one to use "float output = floor( floatValue1 * 255.0 ) + floatValue2;". Somehow I don't think that would do the trick as 16-bit float is not stored in a way for this to have much of an effect. I presume the sign bit, exponent bits and a couple of value bits would have to be used to store one value and the rest for the second.
half PackHalf( float A/*one bit*/, float B/*5 bits*/, float C/*10 bits*/ )//all inputs in 0-1 range { float s = A*2-1;// -1/+1 float e = lerp( -13, 14, B ); float f = lerp( 1024, 2047, C ); return s*f*pow(2,e); }//N.B. most likely contains mistakes
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine
#8 Members - Reputation: 595
Posted 25 April 2012 - 06:24 PM
The original specs did allow mixing, for example: RGBA8 + RG16F + R32F (ie. all 32bit formats). The restriction was lifted in one of the OpenGl releases (ie. no extension of any sort is needed. it is core.) - however, i was not able to track down exactly which OGL version it was :/. Probably starting with 3.0?Because in the original specs FBOs didn't allow for such combinations and the five an FBO Incomplete error. There's some extension I think that is supposed to remove this restriction but I had no luck so far getting a mix to work reliably across different hardware so I'm hesitant to rely on such format combination although it would be of an advantage.
#9 Members - Reputation: 271
Posted 26 April 2012 - 12:56 PM
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine






