Большие мировые координаты
Примечание
Большие мировые координаты полезны в основном в 3D-проектах; в 2D-проектах они требуются редко. Кроме того, в отличие от 3D-рендеринга, 2D-рендеринг в настоящее время не обеспечивает повышенной точности при использовании больших мировых координат.
Зачем использовать большие мировые координаты?
В Godot и моделирование физики, и рендеринг основаны на числах с плавающей точкой. Однако в вычислительной технике числа с плавающей точкой имеют ограниченную точность и диапазон. Это может стать проблемой для игр с огромными мирами, например, космических или планетарных симуляторов.
Точность максимальна, когда значение близко к 0.0. Точность постепенно снижается по мере удаления от 0.0. Это происходит каждый раз, когда увеличивается показатель числа с плавающей точкой, то есть когда число с плавающей точкой превосходит степень двойки (2, 4, 8, 16, …). Каждый раз, когда это происходит, минимальный шаг числа увеличивается, что приводит к потере точности.
На практике это означает, что по мере удаления игрока от начала координат мира (Vector2(0, 0) в 2D-играх или Vector3(0, 0, 0) в 3D-играх) точность будет снижаться.
Из-за этой потери точности объекты могут "вибрировать" при удалении от начала координат, поскольку положение модели будет привязано к ближайшему значению, которое можно представить числом с плавающей точкой. Это также может привести к физическим сбоям, возникающим только тогда, когда игрок находится далеко от начала координат.
Диапазон определяет минимальное и максимальное значения, которые может хранить число. Если игрок попытается выйти за пределы этого диапазона, он просто не сможет этого сделать. Однако на практике точность чисел с плавающей точкой почти всегда становится проблемой раньше, чем диапазон.
Диапазон и точность (минимальный шаг между двумя экспоненциальными интервалами) определяются типом числа с плавающей точкой. Теоретический диапазон допускает хранение чрезвычайно больших значений в числах с плавающей точкой одинарной точности, но с очень низкой точностью. На практике тип с плавающей точкой, неспособный представить все целые значения, не очень полезен. При экстремальных значениях точность становится настолько низкой, что число не может даже отличить два отдельных целых значения друг от друга.
Это диапазон, в котором отдельные целочисленные значения могут быть представлены в виде числа с плавающей запятой:
Диапазон чисел с плавающей точкой одинарной точности (представляет все целые числа): От -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 |
Максимальный рекомендуемый диапазон одинарной точности для трехмерной игры от третьего лица без артефактов рендеринга или физических сбоев. |
[8192; 16384] |
~0.001 |
~1e-12 |
|
[16384; 32768] |
~0.0019 |
~1e-11 |
Максимальный рекомендуемый диапазон одинарной точности для трехмерной игры с видом сверху без артефактов рендеринга или физических сбоев. |
[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) |
Двойная точность остается намного точнее одинарной после этого значения. |
При использовании чисел с плавающей точкой одинарной точности можно выйти за пределы рекомендуемых диапазонов, но при этом будут наблюдаться более заметные артефакты, а физические сбои будут более частыми (например, игрок не будет ходить прямо в определенных направлениях).
См. также
Дополнительную информацию см. в статье Развенчивание мифов о точности чисел с плавающей точкой.
Как работают большие мировые координаты
Большие мировые координаты (также известные как физика двойной точности) повышают уровень точности всех вычислений с плавающей точкой в движке.
По умолчанию float в GDScript имеет разрядность 64 бита, но Vector2, Vector3 и Vector4 — 32 бита. Это означает, что точность векторных типов значительно ограничена. Чтобы решить эту проблему, можно увеличить количество бит, используемых для представления числа с плавающей запятой в векторном типе. Это приводит к экспоненциальному росту точности, то есть конечное значение не просто вдвое точнее, а потенциально в тысячи раз точнее при больших значениях. Максимальное представляемое значение также значительно увеличивается при переходе от чисел с плавающей запятой одинарной точности к числам с плавающей запятой двойной точности.
Чтобы избежать проблем с привязкой модели при большом удалении от начала координат, движок 3D-рендеринга Godot увеличивает точность рендеринга при использовании больших мировых координат. Шейдеры не используют числа с плавающей точкой двойной точности из соображений производительности, но для эмуляции двойной точности при рендеринге с использованием чисел с плавающей точкой одинарной точности используется альтернативное решение.
Примечание
Включение больших мировых координат приводит к снижению производительности и расходу памяти, особенно на 32-битных процессорах. Включайте большие мировые координаты только в случае реальной необходимости.
Эта функция предназначена для настольных платформ среднего и высокого уровня. Большие мировые координаты могут работать некорректно на недорогих мобильных устройствах, если вы не предпримете меры по снижению загрузки процессора другими способами (например, уменьшив количество физических тиков в секунду).
На слабых платформах вместо этого можно использовать подход сдвиг начала координат, позволяющий создавать большие миры без использования физики и рендеринга двойной точности. Сдвиг начала координат работает с числами с плавающей точкой одинарной точности, но усложняет игровую логику, особенно в многопользовательских играх. Поэтому смещение начала координат на этой странице не рассматривается подробно.
Для кого предназначены большие мировые координаты?
Большие мировые координаты обычно требуются для игр-симуляторов трёхмерного пространства или планетарного масштаба. Это относится и к играм, где требуется поддержка очень высокой скорости движения, но иногда и очень медленных и точных движений.
С другой стороны, важно использовать большие мировые координаты только тогда, когда это действительно необходимо (из соображений производительности). Большие мировые координаты обычно не требуются для:
2D-игры, так как проблемы с точностью обычно менее заметны.
Игры с мирами малого или среднего масштаба.
Игры с большими мирами, разделёнными на уровни с загрузочными последовательностями между ними. Вы можете центрировать каждую часть уровня относительно начала координат, чтобы избежать проблем с точностью и не снизить производительность.
Игры с открытым миром, где игровая зона для пеших прогулок не превышает 8192×8192 метров (с центром в точке начала координат). Как показано в таблице выше, уровень точности остаётся приемлемым в пределах этого диапазона, даже для игр от первого лица.
Если вы сомневаетесь, вам, вероятно, не нужно использовать большие мировые координаты в вашем проекте. Для справки, большинство современных игр с открытым миром уровня AAA не используют большие мировые координаты и по-прежнему используют числа с плавающей точкой одинарной точности как для рендеринга, так и для физики.
Включение больших мировых координат
Этот процесс требует перекомпиляции редактора и всех двоичных файлов шаблонов экспорта, которые вы планируете использовать. Если вы планируете экспортировать проект только в режиме релиза, вы можете пропустить компиляцию шаблонов экспорта для отладки. В любом случае вам потребуется скомпилировать сборку редактора, чтобы вы могли протестировать свой мир высокой точности без необходимости каждый раз экспортировать проект.
Инструкции по компиляции для каждой целевой платформы см. в разделе Compiling. Вам потребуется добавить параметр precision=double SCons при компиляции редактора и шаблонов экспорта.
Полученные двоичные файлы будут иметь имена с суффиксом .double, чтобы отличать их от двоичных файлов с одинарной точностью (у которых нет суффикса точности). Затем вы можете указать эти двоичные файлы в качестве пользовательских шаблонов экспорта в настройках экспорта вашего проекта в диалоговом окне Export.
Совместимость между сборками с одинарной и двойной точностью
При сохранении двоичного ресурса с помощью синглтона ResourceSaver в файле сохраняется специальный флаг, если ресурс был сохранён с помощью сборки, использующей числа двойной точности. В результате все двоичные ресурсы на диске изменятся при переключении на сборку с двойной точностью и сохранении поверх них.
Сборки как с одинарной, так и с двойной точностью поддерживают использование синглтона ResourceLoader для ресурсов, использующих этот специальный флаг. Это означает, что сборки с одинарной точностью могут загружать ресурсы, сохранённые с помощью сборок с двойной точностью, и наоборот. Текстовые ресурсы не хранят флаг двойной точности, поскольку он не требуется для корректного чтения.
Известные несовместимости
В сетевой многопользовательской игре сервер и все клиенты должны использовать один и тот же тип сборки, чтобы обеспечить одинаковую точность на всех клиентах. Использование разных типов сборки может работать, но могут возникнуть различные проблемы.
API GDExtension изменяется несовместимым образом в сборках с двойной точностью. Это означает, что расширения необходимо пересобрать для работы со сборками с двойной точностью. Со стороны разработчика расширения определение
REAL_T_IS_DOUBLEвключается при сборке GDExtension сprecision=double.real_tможно использовать как псевдоним дляfloatв сборках с одинарной точностью иdoubleв сборках с двойной точностью.
Ограничения
Поскольку шейдеры 3D-рендеринга фактически не используют числа с плавающей точкой двойной точности, существуют некоторые ограничения, касающиеся точности 3D-рендеринга:
Triplanar mapping не выигрывает от повышения точности. Материалы, использующие трипланарное наложение, будут демонстрировать заметное дрожание при удалении от начала координат.
GPUParticles3D nodes with Local Coords disabled will not benefit from increased precision. This can cause visible particle snapping to occur when far away from the world origin. Nodes with Local Coords enabled, as well as CPUParticles3D nodes, will still benefit from increased precision.
Shaders using the
skip_vertex_transformorworld_vertex_coordsrender modes don't benefit from increased precision.В сборках с двойной точностью координаты мирового пространства в функции шейдера
fragment()не могут быть реконструированы из пространства вида, например:vec3 world = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
Вместо этого вычислите координаты мирового пространства в функции
vertex()и передайте их с помощью varying, например:varying vec3 world; void vertex() { world = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; }
В настоящее время 2D-рендеринг не поддерживает повышение точности при использовании больших мировых координат. Это может привести к видимой привязке модели на большом расстоянии от начала координат (начиная с нескольких миллионов пикселей при типичном масштабировании). Однако расчёты 2D-физики по-прежнему будут получать преимущества от повышения точности.