How to work with half and snorm I have just come across this article about half, snorm and unorm, but I don't get some of the points (or why they work).


According to the article, a half is basically a 16 bit float and an snorm is a signed float integer$^1$ dividied by 65535. Therefore, they are basically the same, just that the snorm is represented in $[-1, 1]$ whereas the half is in $[-65520; 65520)$ (where did those 32 values go?) but doesn't need another multiplication to get to the "real" value.  Now the article says:



  Other people prefer 16-bit xNORM variants because they tend to give really good precision and it is evenly distributed.


Why do they give a "good precision" and are "evenly distributed" (as opposed to the half)?


For snorm a division is suggested, by either $64$ or the maximum AABB value. I get the latter, that can be used for more or less any model then, but why use the magic number $64$ if I don't want to calculate it? Is it common to have models that don't exceed this specific value?
If I get good precision with half (or xnorm respectively) to save bandwidth, but in my application actually need really large position values, can I leverage the better precision of xnorm with a multiplication for "full" float and save myself from using  double variables?




$^1$ Edit for future readers. I wrongly assumed it was a float.
According to the article, a half is basically a 16 bit float and an snorm is a signed float dividied by 65535. Therefore, they are basically the same


No, they're not, and you do the article a great disservice by suggesting that it says such a thing.

Yes, Half-floats are 16-bit floats. But they are floating point numbers, as defined in IEEE-754. Which means that they can express a relatively large range of values.

Normalized integers can only directly express values in the range [0, 1] (for unsigned) and [-1, 1] (for signed). Floating-point numbers can extend beyond this range. 16-bit floats can express numbers approximately on the range [-6.55*104, 6.55*104], and it can handle decimal values in-between them.


  Why do they give a "good precision" and are "evenly distributed" (as opposed to the half)?


Because that's how IEEE-754 works. After all, normalized 16-bit values and 16-bit float values have the same size. 16-bits of storage gives you 65536 different values, no matter how you interpret them. Therefore, to get the range of values outside of [-1, 1], 16-bit floats sacrifice some bits to define additional values.

16-bit floats give you about 3 decimal digits of precision. Normalized 16-bit values give you at most 5 (though the closer to zero you get, the fewer significant digits you get, unlike floating-point values).


  why use the magic number 64 if I don't want to calculate it?


No reason; it's just a made-up number.


  Is it common to have models that don't exceed this specific value?


Not particularly.


  If I get good precision with half (or xnorm respectively) to save bandwidth, but in my application actually need really large position values, can I leverage the better precision of xnorm with a multiplication for "full" float and save myself from using double variables?


No.

Generally speaking, model space positions do not need "really large position values". They're in model space, so they're generally expressed relative to a center position that's quite close to them. They don't really have to be in scale with the rest of the world either.

However, if your model space positions really do need "really large position values", then you have to use whatever gives you the precision you need. That's pretty much never double.