Jump to content
  • Advertisement
Sign in to follow this  

GLSL: Pack into half floats

This topic is 2541 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,
I was wondering if anyone had any ideas on how to pack and unpack 2 floating point values into a single float16, in glsl? Loss of precision is acceptable. I am trying to add extra attributes into my gbuffer, so I am trying to pack normal values to save space. My gbuffer is 4 framebuffers, with 16-bit float storage per channel.
Thanks
-othello

Share this post


Link to post
Share on other sites
Advertisement
You really think float16 is precise enough for your normals?

You could just store your normal buffer in spherical coordinates, which cuts it down to 2 channels instead of 3. This is a common approach and shouldn't effect your precision.

Share this post


Link to post
Share on other sites

You really think float16 is precise enough for your normals?

You could just store your normal buffer in spherical coordinates, which cuts it down to 2 channels instead of 3. This is a common approach and shouldn't effect your precision.


Sorry, I wasn't completely clear. I would be storing each component into a byte. So if I'm storing emission, for example, in the buffer:


| 16 bits | 16 bits | 16 bits | 16 bits |
| buff_r | buff_g | buff_b | buff_a |
| n.x | n.y | n.z | pad | e.r | e.g | e.b | pad |


A conversion to fixed point bytes is probably necessary for the attributes.

Share this post


Link to post
Share on other sites

[quote name='Chris_F' timestamp='1307246947' post='4819629']
You really think float16 is precise enough for your normals?

You could just store your normal buffer in spherical coordinates, which cuts it down to 2 channels instead of 3. This is a common approach and shouldn't effect your precision.


Sorry, I wasn't completely clear. I would be storing each component into a byte. So if I'm storing emission, for example, in the buffer:


| 16 bits | 16 bits | 16 bits | 16 bits |
| buff_r | buff_g | buff_b | buff_a |
| n.x | n.y | n.z | pad | e.r | e.g | e.b | pad |


A conversion to fixed point bytes is probably necessary for the attributes.
[/quote]
Frist off, you can't divide a floating point number simple into two parts, for this you should use an integer format (not greatly supported by older hardware).

For my deferred rendering engine I always use 16bit floats for all rendering targets. Here are some tips to compress low and high detail data:
1. normals
As already mentionend, try to use normal compression (3 component => 2 component) to save some space. Take a look at aras normal compression page over here.

2. depth
16bit for depth is too low, use 2 16bit floats (precison ~24 bit):

encode
float depth = ...
float d_high = floor(depth*1024);
float d_low = fract(depth*1024);

decode
float depth = (d_high+d_low)/1024;


3. flags
For flags use simply the sign.

4. int + float[0..1)
Sometimes an index plus an alpha value [0..0.99999] are useful and these values can simply be compressed into a single float by:

encode
float result = (float)index + alpha

decode
int index = (int)floor(input)
float alpha = fract(alpha)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!