В SpaceEngine наконец-то появились объемные планетарные кольца с трехмерными камнями и эффектом пыли. Мы с Duke работаем над ними около полугода, с небольшими перерывами по личным причинам. Пришла пора выпустить первую версию системы. В будущем ещё предстоит много работы над кольцами, но я думаю, что текущий результат достаточно хорош для релиза (инструкции по присоединению к публичной бете приведены в конце этого поста). Выбранный нами метод – raymarching – потребовал неожиданно много времени на реализацию, потому что мы столкнулись со множеством проблем. Raymarching похож на трассировку луча, в нём отсутствуют классические полигональные модели камней: они не генерируются и не удаляются при движении камеры. Вместо этого, специальный шейдер на видеокарте выпускает виртуальный луч, проходящий через каждый пиксель изображения, и решает, есть ли камень на пути луча, вычисляя специальные уравнения. Чем-то это похоже на объёмные туманности, которые уже есть в SE: камни – это как бы «сгустки» туманности. Полигонов нет, только математика. Кроме камней, также рисуется объёмный туман, камни могут двигаться, имеют текстуры и освещение и затеняются центральной планетой и её спутниками. С помощью raymarching можно рендерить что угодно, вы можете найти много отличных примеров на shadertoy.com. Основными недостатками этого метода являются часто низкая производительность (сильно зависящая от разрешения изображения), отсутствие аппаратного сглаживания (но можно применить шейдерное сглаживание) и плохая точность на больших расстояниях (что не является проблемой для большинства демок на Shadertoy, но большая беда в SE). Ниже я опишу все технические детали. Что на данный момент поддерживает система 3D колец в SE?

Реалистичные масштабы

Кольца могут варьироваться от узкого потока камней вокруг астероидов (например, кольца вокруг Харикло; и да, SE теперь генерирует процедурные кольца для некоторых холодных астероидов) до огромных кольцевых систем в несколько а.е. диаметром (как кольца у планеты J1407 b; и да, я планирую использовать эту систему для протопланетных дисков). Камни могут быть размером от 1 см до нескольких километров. Толщина кольцевой системы может быть от нескольких размеров камней до сотен километров. Однако есть некоторые ограничения: в огромных кольцевых системах точности может быть недостаточно для 1-сантиметровых камней.

Дифференциальное вращение

Частицы в кольцах вращаются вокруг своей родительской планеты по круговым орбитам. Согласно третьему закону Кеплера, их линейная скорость движения выше вблизи планеты и ниже вдалеке. В играх-космических симуляторах это обычно игнорируется: кольца либо неподвижны (частицы не вращаются вокруг планеты), либо вращаются как твердое тело (все частицы движутся с одинаковой угловой скоростью). В SE мы попытались решить эту проблему, разделив кольцо на несколько тысяч «субколец», каждое из которых вращается со своей скоростью в соответствии с законами Кеплера. Эта функция снижает производительность и порождает видимые щели между субкольцами, поэтому мы пока ограничили количество таких субколец. Но всё же это намного ближе к реальности, чем визуализации колец, которые имеются во многих других движках. Это важно не только потому, что SE претендует на звание научно-точного симулятора, но важно и для игрового процесса. Если вы возьмёте корабль и выйдете на круговую орбиту внутри системы колец, камни должны стать почти неподвижными относительно корабля. Любая другая орбита корабля приведёт к высокой относительной скорости частиц, и будет фатальной (когда будет реализована система повреждений).

В каждом субкольце сами камни могут медленно вращаться вокруг своих осей и медленно дрейфовать друг относительно друга, но это пока не реализовано. Это, безусловно, снизит производительность, потому что при трассировке лучей все вычисления приходится повторять для каждого луча (пикселя изображения).

Важный момент: если вы влетите в кольца в режиме планетария (используя свободную камеру) при запущенной симуляции течения времени, вы увидите, как камни очень быстро проносятся мимо вас. Это связано с тем, что свободная камера в SE фиксируется относительно центра планеты (в режиме слежения) или поверхности планеты (в режиме вращения): она остается неподвижной, а кольца вращаются с орбитальной скоростью. Так что камни будут пролетать мимо вас со скоростью много километров в секунду. Вы должны вручную лететь со скоростью камней, или же просто приостановить время. Еще один способ увидеть камни (почти) неподвижными, или рассмотреть относительное движение субколец – создать корабль и выйти на круговую орбиту внутри колец (довольно интересная задача!) Или отправиться к спутнику внутри колец, такому, ​​как Дафнис или S/2009 S 1, и полетать возле него. На видео ниже камера прикреплена к S/2009 S 1, чтобы продемонстрировать дифференциальное вращение субколец (это всё в реальном времени):

Освещение и текстуры

Каждый камень имеет PBR текстуру, карту нормалей и шероховатости. Это те же текстуры, что используются для ландшафта. В будущем набор текстур может быть настроен индивидуально для каждой планеты. PBR (physically-based rendering, физически-корректный рендеринг) колец поддерживает до 4 источников света и до 8 теней от спутников на каждый источник света. Освещение сильно влияет на производительность, поэтому кольца имеют более строгие ограничения на минимальную яркость источника света, чем планеты. Обычно основным источником света является солнце (или несколько солнц) и сама родительская планета. Некоторые большие спутники также могут давать освещение. Освещение от родительской планеты учитывает её фазу, видимую из положения камня; это сильно влияет на вид колец около равноденствия (см. скриншот ниже). Планета также отбрасывает тень на кольца; эта тень теперь вычисляется более точно даже для старой 2D модели колец, поскольку учитывает видимый размер солнца. Спутники планеты и другие планеты в системе тоже могут отбрасывать тени на кольцо. Конечно, сами спутники тоже могут иметь кольца, и все описанное применимо и к их кольцевым системам. Тени объёмные, но в некоторых случаях могут быть заметны проблемы с точностью. Освещение и тени не вычисляются с использованием чисел двойной точности, потому что это крайне негативно повлияет на производительность. Работа над этим отложена на будущее.

Пыль и переход в 2D кольцо

Частицы, которые находятся далеко, плавно исчезают и превращаются в «пыль», как далекие снежинки в метель, которые невозможно различить по отдельности. Этот эффект пыли имеет освещение, которое соответствует интегральному (усредненному) освещению камней. В кольцах также есть настоящая пыль, которую можно увидеть, например, на кольце E Сатурна, и у этой пыли другая модель освещения. На ещё большем расстоянии объемные кольца переходят в модернизированную 2D модель колец. Почему? Потому что 2D кольца почти не влияют на производительность, что, очевидно, хорошо для далёких планет и для предпросмотра в Wiki и браузере системы. Также 3D кольца могут неправильно перекрываться с родительской планетой, потому что у неё могут быть прозрачные слои, поэтому рендеринг колец должен быть разделен на несколько этапов. На самом деле камни чрезвычайно малы по сравнению с размером колец и с расстоянием до планеты, поэтому такой подход является разумным. Конечно, кто-нибудь обязательно всё поломает в редакторе планет, но вы предупреждены о такой возможности! 🙂 Пока что есть ограничения на толщину системы колец, поэтому по-настоящему толстые пылевые кольца, такие как кольцо E Сатурна или кольца Юпитера, не моделируются корректно (они выглядят слишком плоскими).

Скрипты и редактор

В скрипты планет были введены дополнительные параметры для описания новых колец (они же добавлены в редактор планет). Как и раньше, профиль цвета/плотности задаётся одномерной текстурой, но ее формат может быть изменен в будущем (работа над ним продолжается). Поскольку кольца теперь имеют рендер, близкий к физически-корректному, простая непрозрачность в альфа-канале текстуры должна быть заменена на оптическую толщину. Работа над новой текстурой колец для Сатурна все еще продолжается. Можно реализовать поддержку нескольких систем колец на планету, что поможет сэкономить память или увеличить разрешение текстуры, потому что, например, туманное кольцо E Сатурна сейчас занимает значительную часть текстуры.

Настройки качества/производительности

Использование raymarching для колец даёт очень большую нагрузку на видеокарту (и совсем не нагружает центральный процессор), поэтому мы ввели различные настройки, чтобы можно было разменять качество на производительность.

В реальности кольца представляют собой гигантское плоское скопление небольших твёрдых тел, вращающихся вокруг планеты в её экваториальной плоскости. Под «плоскими» я имею в виду действительно плоское – кольца Сатурна имеют диаметр 280 000 км и толщину всего от 10 до 30 метров! Поскольку SpaceEngine – реалистичный космический симулятор, нам пришлось воспроизвести это графически. Это сразу же привело ко множеству проблем, самая серьезная из которых – точность. Например, кольца Сатурна при их гигантских размерах имеют типичный размер частицы около 10 см, то есть около 3·10-10 от размера колец. Это ниже предела точности 32-битных чисел с плавающей запятой FP32 (IEEE 754 float), с которыми работают видеокарты. На практике это приводит к заметному дрожанию и разрыву изображения камня. Это связано с тем, что в raymarching вы не размещаете модель камня в определенных координатах, вы «размещаете» каждый пиксель его изображения с ограниченной точностью. Поэтому, если у вас дисплей разрешением 1080p и вы хотите видеть камни без артефактов, вы должны рассчитать каждый пиксель камня с такой точностью, которая как минимум в 10 000 раз выше, чем могут себе позволить числа FP32. Есть только два способа решения этой проблемы. Первый – сделать камни в 1000 – 10000 раз больше. Но это не вариант для SE как научно достоверного симулятора. В кольцах Сатурна нет камней размером 100 метров (ну, есть немного, но они редки; большинство камней меньше 10 метров). Другое решение – переделать некоторые части кода шейдера на 64-битные числа с плавающей запятой FP64 (IEEE 754 double). И это работает, теперь точности хватает для камней размером до 10 см. Но FP64 очень, катастрофически медленные на видеокартах Nvidia и AMD. Скажите спасибо сегментации рынка: полная производительность FP64 доступна только на «профессиональных» картах вроде Quadro. Поэтому для потребительских игровых видеокарт мы реализовали эмуляцию FP64, используя два числа FP32. Производительность по-прежнему не радует, но всё же намного лучше, чем при использовании аппаратных FP64.

Чтобы решить проблему с производительностью, нам пришлось уменьшить разрешение изображения – слайдер «Rings resolution» («Разрешение колец») в меню настроек графики. Это распространенный подход во многих играх. SpaceEngine поддерживает рендеринг колец с определенным процентом от разрешения экрана (от 10 до 100%) и различные методы его масштабирования. На 4k дисплее даже 50% выглядит нормально, но при меньшем разрешении дисплея качество должно быть выше. Но проблема с производительностью всё ещё не решена: даже на Nvidia RTX 2080 на 4k дисплее при 50% масштабировании движок выдаёт только 30 кадров в секунду. Наша цель – иметь 60 кадров в секунду на любом оборудовании, оптимистично так 🙂 Так что мы использовали ещё один приём: темпоральный рендеринг (флажок «Fast temporal rendering» («Быстрый темпоральный рендер») в настройках графики). Каждый кадр движок обновляет только один пиксель в блоке 2×2, чередуя, какой пиксель обновляется в следующем кадре. На статической сцене это работает превосходно, обеспечивая четырёхкратное ускорение рендеринга, что позволяет повысить качество или разрешение при сохранении 60 кадров в секунду. Но никому не нужна статичная картинка при 60 кадрах в секунду 🙂 В движении этот темпоральный рендеринг приводит к появлению шлейфов, или артефактов, похожих на размытие движения. Некоторые игры уменьшают этот эффект с помощью различных техник, например, репроекции, но в SE они пока не реализованы. На мой вкус, несильные шлейфы не мешают, если вы двигаетесь достаточно медленно относительно камней и имеете стабильные 60 кадров в секунду (что является целью темпорального рендеринга). Движение на высоких скоростях в любом случае испортит эффект погружения, потому что камни будут мельтешить. С темпоральным рендерингом на высоких скоростях камни выглядят как бы «прозрачными». К сожалению, темпоральный рендеринг нельзя использовать в виртуальной реальности, потому что он полностью ломает эффект погружения. Поэтому в VR мы вынуждены использовать только масштабирование разрешения, с более серьезным снижением разрешения, чем при использовании темпорального рендеринга.

Реализовано три режима масштабирования: шахматный, бикубический и бикубический с резкостью и FXAA. Это соответствует низкому, среднему и высокому качеству (выпадающее меню «Volumetric rings» («Объёмные кольца») в настройках графики), которые выбираются автоматически с помощью глобальной настройки качества/производительности в SE (но вы всегда можете переключить глобальную настройку на “своё”, чтобы тонко настроить кольца).

Checkerboard, или «шахматная доска» – это метод рендеринга, при котором движок рисует только два пикселя в блоке 2×2. В SE мы пока реализовали простую его версию; чередование в темпоральном режиме осуществляется только между этими двумя пикселями. Это означает, что даже при 100% разрешении вы не увидите резкой картинки, всегда будет присутствовать интерполяция. Но это также делает шлейфы в темпоральном режиме менее заметным, чем в следующих двух (поскольку цикл обновления составляет два кадра, а не четыре). Также не поддерживается сглаживание, потому что изображение несколько размытое даже при 100% разрешении.

Бикубический режим аналогичен тому, который используется для галактик и туманностей (да, они также рендерятся в пониженном разрешении – вы можете найти настройки для них в разделе «Volumetric objects resolution» («Разрешение объёмных объектов»)). Картинка в бикубическом режиме резкая при 100% разрешении, но выглядит несколько размытой при меньшем разрешении. Режим «бикубический с резкостью» решает эту проблему, применяя фильтр повышения резкости, но при этом усиливается алиасинг (пиксельная лесенка) на краях камней. Чтобы побороть алиасинг в этом режиме, применяется фильтр FXAA. Этот FXAA отличен от глобального FXAA, используемого в движке для всего кадра, он влияет только на частицы колец.

Надо разъяснить последнюю настройку, выпадающее меню «Rings target resolution» («Целевое разрешение колец»). Она была добавлена для плавного перехода к дисплеям с высоким разрешением, и чем-то похожа на опцию «Landscape target resolution» («Целевое разрешение ландшафта»), которая уже есть в SE (она называлась «Максимальное разрешение ландшафта», но я переименовал её для ясности). Предположим, что у пользователя есть Nvidia RTX 2080, и она выдаёт 150+ кадров в секунду при разрешении экрана 1080p с настройками колец «высоко» (разрешение 85% и включён темпоральный рендеринг). Но при переходе на 4k дисплей у пользователя будет всего 45 кадров в секунду. Чтобы получить 60 кадров в секунду, необходимо уменьшить разрешение рендеринга до 50%. Функция «целевое разрешение» ограничивает разрешение не процентом разрешения экрана, а абсолютным значением. Значение «1080p» означает, что кольца будут рендериться в разрешении 1080p, даже если разрешение экрана выше. Фактически, SE выбирает меньшее из двух чисел – этот параметр и физическое разрешение экрана, поэтому на небольших дисплеях этот параметр ничего не меняет. Настройка «Разрешение колец» применяется поверх этой, поэтому в приведенном выше примере у нас будет 85% от 1080p, то есть 918 строк. Этого достаточно для 60 кадров в секунду на RTX 2080.

Известные проблемы и ограничения

Пока что у новой системы колец есть несколько проблем и ограничений. В конце концов, они всё ещё находятся в стадии беты. Некоторые из этих проблем/ограничений были перечислены выше. Кроме этого:

  • Спутники, вращающиеся внутри колец, правильно сортируются с кольцами, только если смотреть в сторону от родительской планеты; если смотреть на планету, спутник будет рендериться перед кольцами.
  • Космические корабли вообще не сортируются с кольцами и всегда рендерятся перед ними.
  • Освещённая и теневая стороны колец имеют одинаковую яркость.
  • Может быть заметна линия перехода в 2D кольца.
  • Камни выглядят довольно круглыми, более сложную форму пока нельзя создать из-за ограничений по производительности.
  • По той же причине камни не кучкуются в веретенообразные сгущения – «пропеллеры».
  • Эти проблемы будут исправлены в будущем либо во время публичного бета-тестирования, либо после полного релиза этого обновления.

    Тепловое свечение деталей космических кораблей

    В этом обновлении добавлена ​​гораздо меньшая, но все же полезная функция – это поддержка теплового излучения для моделей космических кораблей. Некоторые высокотемпературные элементы кораблей, такие как радиаторы и сопла двигателей, теперь могут быть визуализированы с точным цветом и яркостью – особенно это заметно в автоматическом и ручном режимах экспозиции. До этого была просто статическая эмиссионная текстура. Это нововведение является частью разрабатываемой системы симуляции теплового/энергетического баланса корабля.

    Чтобы узнать, как присоединиться к бета-версии SpaceEngine, нажмите здесь. Ваши отзывы и сообщения об ошибках очень ценны для нас!

    Полный список изменений в этом обновлении:

  • Добавлены объемные планетарные кольца
  • Обновлён каталог экзопланет (3 июня 2021 г.)
  • Поддержка карт температуры для теплового свечения моделей космических кораблей
  • FXAA сглаживает альфа-канал на скриншотах и в предпросмотрах
  • Альфа-канал снова используется в предпросмотрах браузера Солнечной системы
  • Отдельно настраиваемая единица измерения температуры поверхности звёзд в интерфейсе
  • При открытии режима карты, когда выбрана звезда, применяется масштаб её планетной системы
  • Добавлена ​​поддержка формата DEG MIN SEC для широты и долготы в команде Goto
  • Исправлено отображение спин-орбитального резонанса для гиперболических орбит
  • Исправлен ​баг, из-за которого обломочные кольца вокруг газовых гигантов встречались очень редко
  • Исправлен баг с отсутствующими поясами астероидов
  • Исправлен баг с расплавленными кометами
  • Исправлена ​​неработающая интерполяция переменной, если длительность интерполяции равна нулю или отрицательна
  • Обсудить этот пост можно на форуме.