AltDevArts

Share this post

Fixed-point as compression

www.altdevarts.com

Discover more from AltDevArts

Sharing what we have learned over the years, in the art of development.
Continue reading
Sign in

Fixed-point as compression

Any given fixed-point format can be considered a method of compressing another, higher resolution fixed-point format.

Mike Acton
Sep 11, 2023
3
Share this post

Fixed-point as compression

www.altdevarts.com
Share

This is part 4 of the onboarding floating point series. This series is intended to be used for onboarding of programmers new to the team to review a basic understanding of fixed-point and floating-point number formats, or for programmers who would like to remove some of the mystery from formats they may use everyday.

We introduced 1:16:15 fixed-point in fixed-point as fractions. Consider the following table of values. Assume they represent distances in meters, as in previous examples.

table_4_1.txt

Lossless compression

Assuming these values are representative of some group (e.g. vertices of models, instance positions, etc), what can we see from the data?

There are a set of bits that are always zero. Values are within +/-32 meter range and 1/4096 meter resolution.

-:00000000000-----:------------000

Mark those bits with ‘x’ for “don’t care”

-:xxxxxxxxxxx-----:------------xxx

Mark bits that are used with letters for reference.

S:xxxxxxxxxxxAAAAA:BBCCDDEEFFGGxxx

Remove the bits we don’t care about.

S:xxxxxxxxxxxAAAA A:BBCCDDEEFFGGxxx -> s:AAAA:BBCCDDEEFFGG
uint32_t compress( uint32_t d )
{
  return ((d&0x80000000)>>11)|((d&0xffff8)>>3);
}

Without losing any information, we can store these same values in 1:5:12 fixed-point format. However, that requires 18 bits of storage, so we might want to consider how we can reduce it to fit into 16 bits.

Lossy compression

1:5:12 fixed-point storage of distance has a resolution of 1/4096 meter, which is approximately 1/4 of a millimeter. In many common cases like game object model vertices or world positions, that resolution is imperceptible. We can often use 1/1024 meter resolution (or less!) without any difference perceivable by anyone other than the original artist. For any game that works with average human scale interactions, a millimeter is pretty small. Alternatively, if you’re making a game about brain surgery, nanometer resolution might be appropriate but anything more than a +/- 1 meter range is probably unnecessary.

If we don’t care about anything more than 1/1024 meter resolution, we can mark two additional bits ‘x’ as don’t care in the source 1:16:15 fixed-point data. By reasoning about what resolution we need, we can store the same values in a 1:5:10 format, which fits neatly into 16 bits.

S:xxxxxxxxxxxAAAAA:BBCCDDEEFFxxxxx -> s:AAAA:BBCCDDEEFF
uint32_t compress( uint32_t d )
{
  return ((d&0x80000000)>>16)|((d&0xfffd0)>>5);
}
table_4_2.txt

Note that you can’t say whether or not compression is lossless or lossy without knowing concretely what data is being compressed.

Take-away

Consider fixed-point a form of compression. Select the appropriate size and format by considering the range and resolution necessary given the specific input data and how it’s used.

Next: Part 5

Floating-point as compression - A floating-point format can be considered a (generally lossy) approach to compressing a high-resolution fixed-point format.

AltDevArts is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.

Get 10% off a group subscription

3
Share this post

Fixed-point as compression

www.altdevarts.com
Share
Comments
Top
New
Community

No posts

Ready for more?

© 2023 Matt Yaney
Privacy ∙ Terms ∙ Collection notice
Start WritingGet the app
Substack is the home for great writing