Jump to content
  • Advertisement
Sign in to follow this  
Hyunkel

Structured buffer float compression

This topic is 2203 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

I have a computer shader that generates procedural planetary terrain and stores vertices in a structured buffer which has the following layout.

struct PlanetVertex
{
float3 Position;
float3 Normal;
float Temperature;
float Humidity;
};


That's 10 floats with 4 bytes per float -> 40 bytes per vertex.
A terrain node or patch contains 33x33 vertices, which is 43560 bytes.
At the highest quality setting, the compute shader will output up to 5000 nodes,
so the buffer needs to be 5000 * 43560 bytes, which is
217800000 bytes or ~207mb.

Due to the way I handle load balancing between rendering and terrain generation, I need to have this buffer in memory twice, so I use
~415mb only for vertex data.
This is okay I guess, since a planet is sort of the primary object, but I want to reduce this buffer size if possible.

For example the normal vector: It doesn't need 32bit precision per channel, 16 would be more than enough.
As for temperature and humidity, they could even fit in an 8bit unorm, but I doubt that's available here.

I found that there are f32tof16 and f16tof32 functions in hlsl, which I assume are what I need, but I cannot quite figure out how they're supposed to work:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff471399(v=vs.85).aspx

It says here that f32to16 returns a uint, but isn't that 32 bit as well?

Cheers,
Hyu

Share this post


Link to post
Share on other sites
Advertisement
Oh, alright, now I get it.
So basically I have to run f32tof16 on two floats which I want to store in a single uint (with 16 bit precision) but I have to do packaging myself.

uint Float2ToF1616(in float2 f)
{
uint packed;
packed = asuint(f32tof16(f.x)) | (asuint(f32tof16(f.y)) << 16);
return packed;
}


Thanks! :)

Share this post


Link to post
Share on other sites
If you assume that the normal is a normalized vector, you can pack it to a 2-element vector:

n[sub]z[/sub] = 1.0 - n[sub]x[/sub] - n[sub]y[/sub]

Share this post


Link to post
Share on other sites

Oh, alright, now I get it.
So basically I have to run f32tof16 on two floats which I want to store in a single uint (with 16 bit precision) but I have to do packaging myself.

uint Float2ToF1616(in float2 f)
{
uint packed;
packed = asuint(f32tof16(f.x)) | (asuint(f32tof16(f.y)) << 16);
return packed;
}


Thanks! :)


Yes

Share this post


Link to post
Share on other sites
The underlying reason for this is that modern hardware doesn't actually have 16-bit registers.

Share this post


Link to post
Share on other sites

If you assume that the normal is a normalized vector, you can pack it to a 2-element vector:

n[sub]z[/sub] = 1.0 - n[sub]x[/sub] - n[sub]y[/sub]


The only packing algorithms I know of are these:
http://aras-p.info/texts/CompactNormalStorage.html

and they are for view space normal vectors mostly.
I don't really see a quick way to do 2 channel packing, though it would be quite useful if I could.


The underlying reason for this is that modern hardware doesn't actually have 16-bit registers.


Yeah, I'm aware, which is why I thought that f32tof16() would need to take 2 floats as input and got confused.

Share this post


Link to post
Share on other sites
The method #1 on that page is what I had in mind. You do need bias the x and y to 0...1 beforehand, which I forgot to mention.

Share this post


Link to post
Share on other sites
...and since you bias the x and y to positive range, you can use either's sign to encode the z direction.

Share this post


Link to post
Share on other sites

If you assume that the normal is a normalized vector, you can pack it to a 2-element vector:

n[sub]z[/sub] = 1.0 - n[sub]x[/sub] - n[sub]y[/sub]


Did you mean n[sub]z[/sub] = sqrt(1.0 - n[sub]x[/sub][sup]2[/sup] - n[sub]y[/sub][sup]2[/sup]) ?

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!