1
\$\begingroup\$

Most of the numeric quantities used in games (aside from integers for counting or indexing objects) are single-precision floating point. This is IEEE format, which allows for numbers as big as 1e38 and as small as 1e-38.

Such a large dynamic range makes sense in the context in which the IEEE floating-point standard was defined: roughly speaking, for scientists, who routinely deal with very large and very small numbers.

Intuitively, games seem unlikely to have to deal with such a wide range. Say you measure distance in meters. Draw distance maybe a few kilometers? Smallest objects a few millimeters? Granted that multiplying numbers can temporarily take them out of the original range, it would seem sufficient to have a dynamic range like 1e8 to 1e-6, whereupon more of the bits could've been used for greater precision.

But maybe I am missing something about the data and calculations routinely used in games.

What sort of dynamic range do games actually use?

\$\endgroup\$
2
  • \$\begingroup\$ I'm curious what actionable steps you're hoping to take with the answers you get to this question. Floating point may not be ideal, but it's what we have the hardware to work with. You could of course implement your own number format using integer math under the hood (or use an existing library that provides this), but that gives you flexibility to define a completely bespoke type with exactly the dynamic range you need for ONE game, or even just each single feature of one game. So knowing ranges used in "typical" games doesn't really help with that task. What's your goal we can help with? \$\endgroup\$
    – DMGregory
    Commented Dec 6, 2022 at 15:59
  • \$\begingroup\$ @DMGregory The same as my goal in reading about the orbital dynamics of galaxies or Napoleon's campaign in Russia: to understand some aspect of how the world works. \$\endgroup\$
    – rwallace
    Commented Dec 6, 2022 at 19:39

2 Answers 2

1
\$\begingroup\$

As games cover such a wide range of things, there is really no typical. However, for 3D worlds, greater scale is becoming more popular. Open worlds, for example, can cover any size you care to imagine.

Based on my experiments, if you want accuracy in the millimeters throughout, then with single precision, a world of about 70,000m is fine before you can start to notice some jitter.

Some math on this: single precision has a max mantissa value of 2^23-1, or 8,388,607. 70,000 / 8,388,607 is about 0.008m or 8mm. However, the resolution or error in 3D space is a 3D geometric formula, not the 1D calculation I just did.

If you factor in that the base error is a 3D geometric formula, the actual error is a factor of 3.4xdistance (ref geometric relative error) greater than what I calculated. I.E instead of 8mm accuracy the worst case accuracy much lower - probably in the centimetres to a meter.

Then if you do any calculations, the error is magnified by propagation. E.g. a multiply by 10 will make it 10x bigger.

The takeaway is that mm resolution is not achievable beyond 70km and most likely at a smaller range.

Practical proof: In the video: I demonstrate visible errors at the 70km range from distant relative jitter: Distant relative jitter (bookmark "Attempt to move to a point intersection". As I try to move to a point where two squares meet, the visible error would appear to be about 0.5 to a meter. The jitter at times appears to be less: in the cm range. The sliding motion demonstrates loss of resolution in at least one axis.

In contrast, at the bookmark: "At least mm accuracy when move to target" motion to target is smooth and accurate. This is because the design manages the resolution at that place by nesting a high-resolution virtual space within the World space.

\$\endgroup\$
8
  • \$\begingroup\$ That is helpful, thanks! Sounds like confirmation of my conjecture: the limiting factor is precision, not the dynamic range of the exponent, so the practically achievable range would be better if there were one or two fewer bits of exponent, and one or two more bits of precision? \$\endgroup\$
    – rwallace
    Commented Dec 6, 2022 at 13:02
  • 1
    \$\begingroup\$ @rwallace Unfortunately current CPUs and GPUs don't have hardware support for custom floating point formats. Theoretically you could emulate them by using raw bytes and implementing your own mathematical operators, but then you lose a lot of performance... and sanity. \$\endgroup\$
    – Philipp
    Commented Dec 6, 2022 at 14:03
  • \$\begingroup\$ You may also be interested in What's the largest "relative" level I can make using float? \$\endgroup\$
    – DMGregory
    Commented Dec 6, 2022 at 18:39
  • 1
    \$\begingroup\$ @rwallace Although "the limiting factor is precision" is the way I, and most people started, this is not actually true. You can travel the Solar system as one continuous space with just float, evidence: youtu.be/_04gv3CnjDU. The limiting factor is how we think about it and the resulting design we apply. \$\endgroup\$ Commented Dec 6, 2022 at 23:15
  • 1
    \$\begingroup\$ @MadMan, that is one of mine. I don't use separate local coordinates or any sectorized map of absolute coordinates - for the moving player. I use dynamic virtual spaces. The coordinate system around the stationary traveler never changes. However, the player may exist in multiple virtual spaces at any time. Travel is via relative movement (differentials) and the precision limits don't apply. \$\endgroup\$ Commented Dec 8, 2022 at 4:00
1
\$\begingroup\$

I can give the game I'm working on as an example. It certainly does not fit "routinely used" being something of an outlier, but still might be illustrative as an example that the storage of the world doesn't need to be limited to what the graphics card can handle.

I'm working on a game set in a realistically scaled galaxy (10^18 km across, or even larger, and I also want to be able to fly outside it), with a unit scale of 10 km. For this, single precision floats or even double precision floats would have inadequate precision, and single precision floats are even problematic with dynamic range in intermediate calculations (I have overflowed them several times). My solution is that positions are stored as 64 bit integers, with 128 bit integers for some intermediate calculations.

The main target for this is Android. I can't assume the graphics card can handle anything bigger than single precision floats, so there is some juggling going on. One technique I use is to pass the graphics card offsets (as floats) from a particular point in space (the zero point), and occasionally re-center the zero point to be near the viewpoint to limit the distortion that would be caused by the zero point being far from the viewpoint. (This sort of distortion can be seen in Minecraft if you go very far from the start area).

I will also have to consider changing scales to something finer than a 10 km resolution for planets or moons when the viewpoint goes close to them.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .