TGViewer
Phase Of Horizon | HollowEngine Phase Of Horizon | HollowEngine @hollowengine · 373 subscribers
Post #162 344
Оптимизация Minecraft или "Почему лагает даже на RTX 5090"? | День 73

Недавно я начал углубляться в тему рендеринга Vulkan (да и OpenGL), а также изучил подходы к рендерингу в популярных движках вроде Unity или Unreal Engine 5. В связи с этим хочу рассказать про подход Minecraft (да и Hytale в том числе). Пост большой и отношения к HollowEngine практически не имеет, но возможно кому-то будет интересно почитать :)

Думаю все заметили, что при 32 чанках уже начинаются просадки FPS, причём даже на топовом железе, которое легко тянет киберпанк в 165 fps, но Minecraft без теней, отражений, реалистичной воды едва-едва вывозит 80 кадров, но почему?
Прежде всего, при прогрузке мира все чанки упаковываются в уникальные VAO - это что-то вроде большого массива с вершинами, координатами текстур, цветом, освещением и т.п. После чего для каждого чанка вызваются команды вроде "Установить текущий VAO" и "Нарисовать текущий VAO". Вроде бы всё просто и логично? - Но в этом и заключается проблема, когда таких чанков 100-200 штук, это не так уж и страшно, но на деле их тысячи. И проблема даже не в том, что железо слабое. Проблема в том, что эти команды идут примерно по следующему пути: Java (JNI) -> OpenGL -> CPU -> GPU, то есть для каждого чанка приходится постоянно спамить от процессора к видеокарте по одной команде: "Нарисуй этот чанк". И даже если у тебя видеокарта легко справится с сотнями миллионов вершин, ей эти данные будут поступать такими маленькими группами, грубо говоря забивая шину.

И что же с этим делать и почему в других играх такой проблемы нет? - Прежде всего, в других играх всё куда проще, если в Minecraft нужно зарендерить город, видеокарта получает условные 500 команд "Нарисуй этот чанк", а в большинстве других игр это просто 1 команда "Нарисуй мне город целиком". Логично было бы сделать также в Minecraft, но тут возникает нюанс: в Minecraft вы легко можете сломать любой блок в мире, а в других играх - нет, максимум только некоторые допустимые объекты, вроде тех же деревьев. А после ломания блока придётся целиком обновить всю карту и отправить новую на GPU.

Но решения тут всё же есть, по сути их 2: LOD'ы и Indirect-рендеринг. Плюс их можно комбинировать между собой.
Про LOD'ы расскажу лишь кратко: они просто упрощают и объединяют те чанки, что находятся далеко от игрока, тем самым вместо того, чтобы рисовать 9 чанков, может быть нарисован всего один, но упрощённый. Игрок всё равно не заметит разницы, ведь он сильно далеко, но у такого подхода есть 2 больших минуса. Он требует очень много оперативки, ведь нужно хранить геометрию не только для обычных чанков, к тому же и сам мир приходится прогружать на тысячи блоков вперёд. А ещё перестраивать эти LOD'ы очень дорого, поскольку обычно есть где-то 6-8 уровней детализации и объединения нескольких чанков и получается - игрок сломал блок, и теперь придётся все эти LOD'ы строить заново. Тут конечно много хитрых ходов, огромные БД, генерация чанков на GPU и т.п. Но я сам в это дело пока не лез, так что строить теорий не буду.
Второй метод, Indirect-рендеринг, на деле куда интереснее: Вместо того, чтобы делать отдельный VAO под каждый чанк, создаётся один большой массив для всех прогруженных чанков и в этом массиве размечается пространство (грубо говоря, каждые 1024 байта - новый чанк), при добавлении новых чанков они записываются в этот массив и сохраняется индекс этого чанка в массиве, а при удалении этот индекс просто удаляется (при этом сам чанк может и дальше висеть в памяти, со временем его просто заменят другие чанки), а вместо 500 команд "Нарисуй мне этот чанк", создаётся всего одна: "Нарисуй мне объекты из {массив} с индексами [0, 1, 3, 6, 7, ...]".
Появляется логичный вопрос - моджанг нанимают на работу говнокодеров почему в Minecraft сразу так не сделали? А всё просто, такие возможности появились только в OpenGL 4.0, а Minecraft держит совместимость c 3.2 (он вышел в 2009), поэтому никакой оптимизации под современное железо там и не делают.
Разве что с одним уточнением - Sodium использует схожий подход, но с небольшими упрощениями (опять же, для совместимости).
  • ❤ 4
  • 😱 2
More from @hollowengine
  1. Sep 24, 2026Новый интерфейс движка 🛞 | День 10 Да, я опять его переделал, и что вы мне сделаете? В пе…
  2. Sep 23, 2026Эмиттеры партиклов 🎮 | День 9 В общем, сегодня доработал ядро системы эффектов до уровня…
  3. Sep 22, 2026Ну вот, и даже ничего не сгорело, не зря год назад запарился и написал систему инстансинга…
  4. Sep 22, 2026Зря вы мне доверили систему эффектов и партиклов 😱 (День 8)
  5. Sep 21, 2026Ещё больше визуальных доработок ✨ (День 7) Продолжаю вчерашние доработки и исправления, на…
  6. Sep 20, 2026Доработка панелей мода 🛞 Сегодня я существенно доработал панели и окна движка, если корот…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →