Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

大世界坐标

备注

大世界坐标主要用于 3D 项目;2D 项目很少会用到。此外,启用大世界坐标后,2D 渲染目前无法从精度的增加中获益,但 3D 渲染可以。

为什么要使用大世界坐标?

在 Godot 中,物理仿真和渲染都依赖于浮点数。然而,计算机中浮点数的精度和范围是有限的,可能在太空、星球尺度的仿真游戏等拥有庞大世界的游戏中产生问题。

浮点数的精度在 0.0 附近是最高的。随着取值离 0.0 越来越远,精度就会变得越来越低。每次浮点数的指数变大时,精度就会降低,也就是浮点数取值越过 2 的幂(2、4、8、16……)的时候。此时浮点数的最小步长就会增大,精度因此变低。

在实践中,这意味着玩家远离世界原点(2D 游戏的 Vector2(0, 0) 和 3D 游戏的 Vector3(0, 0, 0)),精度就会下降。

精度的丢失可能会导致远离世界原点的对象看上去在“抖动”,因为模型的位置会吸附到最接近的浮点数能够表示的值。这种情况下,如果玩家远离世界原点,还可能导致物理方面的问题。

范围决定的是所能够存储的最小和最大值。如果玩家尝试移出这个范围就会直接失败。但是实际情况下,在能够受到范围影响之前几乎都会遇到浮点数精度问题。

范围和精度(两个指数间隔的最小步长)取决于浮点数的类型。单精度浮点数的理论范围支持存储极高的值,单精度很低。实践中,无法表示所有整数值的浮点数类型并不是很有用。极值附近的精度会变得非常低,低到连两个整数值也无法区分。

以下是浮点数能够表示整数值的范围:

  • 单精度浮点数范围(表示所有整数):-16,777,216 和 16,777,216 之间

  • 双精度浮点数范围(表示所有整数):-9 千万亿和 9 千万亿之间

范围

单精度步长

双精度步长

注释

[1; 2]

~0.0000001

~1e-15

0.0 附近精度会变大(本表省略)。

[2; 4]

~0.0000002

~1e-15

[4; 8]

~0.0000005

~1e-15

[8; 16]

~0.000001

~1e-14

[16; 32]

~0.000002

~1e-14

[32; 64]

~0.000004

~1e-14

[64; 128]

~0.000008

~1e-13

[128; 256]

~0.000015

~1e-13

[256; 512]

~0.00003

~1e-13

[512; 1024]

~0.00006

~1e-12

[1024; 2048]

~0.0001

~1e-12

[2048; 4096]

~0.0002

~1e-12

第一人称 3D 游戏的最大推荐单精度范围,不会有渲染和物理方面的问题。

[4096; 8192]

~0.0005

~1e-12

第三人称 3D 游戏的最大推荐单精度范围,不会有渲染和物理方面的问题。

[8192; 16384]

~0.001

~1e-12

[16384; 32768]

~0.0019

~1e-11

俯视角 3D 游戏的最大推荐单精度范围,不会有渲染和物理方面的问题。

[32768; 65536]

~0.0039

~1e-11

所有 3D 游戏的最大推荐单精度范围。双精度(大世界坐标)通常会超过这个点。

[65536; 131072]

~0.0078

~1e-11

[131072; 262144]

~0.0156

~1e-10

> 262144

> ~0.0313

~1e-10(0.0000000001)

超过这个值之后,双精度仍然比单精度要精确地多。

使用单精度浮点数时,可以超过建议的范围,但此时就会更多可见的渲染问题,物理问题也会变得更常见(例如玩家在某些方向上无法直线移动)。

参见

详见 Demystifying Floating Point Precision 一文。

大世界坐标的工作原理

大世界坐标(也叫双精度物理)能够增加引擎中所有浮点数计算的精度级别。

By default, float is 64-bit in GDScript, but Vector2, Vector3 and Vector4 are 32-bit. This means that the precision of vector types is much more limited. To resolve this, we can increase the number of bits used to represent a floating-point number in a Vector type. This results in an exponential increase in precision, which means the final value is not just twice as precise, but potentially thousands of times more precise at high values. The maximum value that can be represented is also greatly increased by going from a single-precision float to a double-precision float.

To avoid model snapping issues when far away from the world origin, Godot's 3D rendering engine will increase its precision for rendering operations when large world coordinates are enabled. The shaders do not use double-precision floats for performance reasons, but an alternative solution is used to emulate double precision for rendering using single-precision floats.

备注

Enabling large world coordinates comes with a performance and memory usage penalty, especially on 32-bit CPUs. Only enable large world coordinates if you actually need them.

This feature is tailored towards mid-range/high-end desktop platforms. Large world coordinates may not perform well on low-end mobile devices, unless you take steps to reduce CPU usage with other means (such as decreasing the number of physics ticks per second).

On low-end platforms, an origin shifting approach can be used instead to allow for large worlds without using double-precision physics and rendering. Origin shifting works with single-precision floats, but it introduces more complexity to game logic, especially in multiplayer games. Therefore, origin shifting is not detailed on this page.

大世界坐标的目标群体是谁?

Large world coordinates are typically required for 3D space or planetary-scale simulation games. This extends to games that require supporting very fast movement speeds, but also very slow and precise movements at times.

On the other hand, it's important to only use large world coordinates when actually required (for performance reasons). Large world coordinates are usually not required for:

  • 2D games, as precision issues are usually less noticeable.

  • Games with small-scale or medium-scale worlds.

  • Games with large worlds, but split into different levels with loading sequences in between. You can center each level portion around the world origin to avoid precision issues without a performance penalty.

  • Open world games with a playable on-foot area not exceeding 8192×8192 meters (centered around the world origin). As shown in the above table, the level of precision remains acceptable within that range, even for a first-person game.

If in doubt, you probably don't need to use large world coordinates in your project. For reference, most modern AAA open world titles don't use a large world coordinates system and still rely on single-precision floats for both rendering and physics.

启用大世界坐标

This process requires recompiling the editor and all export template binaries you intend to use. If you only intend to export your project in release mode, you can skip the compilation of debug export templates. In any case, you'll need to compile an editor build so you can test your large precision world without having to export the project every time.

See the Compiling section for compiling instructions for each target platform. You will need to add the precision=double SCons option when compiling the editor and export templates.

The resulting binaries will be named with a .double suffix to distinguish them from single-precision binaries (which lack any precision suffix). You can then specify the binaries as custom export templates in your project's export presets in the Export dialog.

单双精度构建之间的的兼容性

When saving a binary resource using the ResourceSaver singleton, a special flag is stored in the file if the resource was saved using a build that uses double-precision numbers. As a result, all binary resources will change on disk when you switch to a double-precision build and save over them.

Both single-precision and double-precision builds support using the ResourceLoader singleton on resources that use this special flag. This means single-precision builds can load resources saved using double-precision builds and vice versa. Text-based resources don't store a double-precision flag, as they don't require such a flag for correct reading.

已知的不兼容

  • In a networked multiplayer game, the server and all clients should be using the same build type to ensure precision remains consistent across clients. Using different build types may work, but various issues can occur.

  • The GDExtension API changes in an incompatible way in double-precision builds. This means extensions must be rebuilt to work with double-precision builds. On the extension developer's end, the REAL_T_IS_DOUBLE define is enabled when building a GDExtension with precision=double. real_t can be used as an alias for float in single-precision builds, and double in double-precision builds.

限制

Since 3D rendering shaders don't actually use double-precision floats, there are some limitations when it comes to 3D rendering precision:

  • Shaders using the skip_vertex_transform or world_vertex_coords don't benefit from increased precision.

  • Triplanar mapping doesn't benefit from increased precision. Materials using triplanar mapping will exhibit visible jittering when far away from the world origin.

2D rendering currently doesn't benefit from increased precision when large world coordinates are enabled. This can cause visible model snapping to occur when far away from the world origin (starting from a few million pixels at typical zoom levels). 2D physics calculations will still benefit from increased precision though.