Показаны сообщения с ярлыком programming. Показать все сообщения
Показаны сообщения с ярлыком programming. Показать все сообщения

понедельник, 5 октября 2015 г.

Размышления на тему генератора мира

Пока я ковырялся с определением видимости чанков, передо мной встала проблема, как сделать что-то похожее на то, как это будет выглядеть в будущем. Конечно, тупо сделать один шум Перлина на весь мир - совсем не то, что должно получаться, с учетом всяких особенностей разных по климату и возрасту областей, но я уже имел честь повстречаться с некоторыми неприятностями.
Первая состоит в том, что шум, на самом деле, не самая быстрая вещь, которую можно придумать. А если еще и использовать много разного шума для разных особенностей ландшафта (например, пещер, как это делается в других играх), это может оказаться чрезвычайно медленно. Но, возможно, это не самая большая проблема - никто не будет генерировать огромное количество чанков с максимальным уровнем деталей, я полагаю. Однако, об этом еще придется подумать.
Вторая же проблема несколько более забавна - обычный шум хорошо работает на плоскости. И на первый взгляд тут есть серьезная проблема с тем, чтобы потом обернуть эту плоскость вокруг шара или чего-то еще, то есть, замкнуть в выбранных границах. В итоге не получается никакого плавного перехода, и это очень плохо выглядит. Но, к счастью, есть несколько методов решения этой проблемы - во-первых это четырехмерный шум, во-вторых, библиотека, которую я использую, позволяет менять модель шума и одна из моделей как раз называется "Сфера".
Конечно, применение шума для создания интересного ландшафта дело увлекательное и я чуть было не ударился в эту тему, забросив все остальное. Сразу же в голове начали крутиться мысли о том, как можно было бы с помощью него создать континенты и острова, молодые поросли гор с крутыми обрывами, каньоны и овраги, и реки, и всё такое прочее. Но это тема еще на месяц работы, как мне кажется. И, конечно, кроме формы ландшафта, должно быть и его содержание, то есть, разные минералы и прочие породы тоже как-то должны соответствовать форме этого ландшафта. Правда, тут есть и еще одна будущая проблема - как можно увидеть, что получилось, в большом масштабе? Форму в целом, в теории, можно натянуть на сферу и так и рендерить, возможно, даже раскрасить текстуру в какие-то цвета, и, конечно, чтобы не генерировать овердофига блоков, нужно делать это в низком разрешении, но будет очень сложно узнать, что же получилось под поверхностью. Вообще, интересно, как это можно было бы сделать, не запуская после каждого мелкого изменения заново всю симуляцию и не пытаясь что-то копать.

воскресенье, 4 октября 2015 г.

Статус воксельного движка


Похоже, пока я размечтался о крутых особенностях физически обоснованной игровой механики в воксельных мирах, я недооценивал проблемы производительности при отображении мира игроку. Начнем по-порядку.
Я уже говорил раньше, что для более быстрого рендера блоков на экране, их пришлось собрать в группы, которые обычно называют чанками и рисовать уже чанки. Дальнейшие опыты показали, что довольно тупым и неэффективным путем Майнкрафта у меня идти не получается. Дело в том, что конечность высоты мира в Майнкрафте позволяет там считать чанком целый столбец мира высотой в 256 блоков, что, конечно, позволяет рисовать намного меньше поверхностей этих самых блоков изначально. Поэтому, тупо загрузить N * N * N чанков вокруг игрока оказалось жутко неэффективной затеей. Еще более неэффективным ее делала большая разница в представлении блоков. В Майнкрафте у блока просто есть одно число, которое полностью описывает "материал" и "положение" блока, скажем, его ориентацию, если она важна. Или это же число используется для запаковки множества похожих типов блоков, например, разноцветных блоков шерсти или глины. Понятное дело, это изначально показалось мне слишком жестким и мне захотелось расширить число свойств блоков, сразу позволив хранить целые списки разных значений. Конечно, это сразу же значит, что, во-первых, блоки занимают больше памяти, во-вторых, передаются по сети дольше. Так что вместо каких-то двух байт на тип блока, у меня получается все довольно толстым. С учетом того, что Майнкрафт и дальше немного оптимизирует эту часть протокола в последних версиях, они, наверное. о чем-то догадываются. Я об этом догадался не сразу, так что время доставки чанка с сервера на клиент оказалось великоватым, и даже если рендеринг успевает хорошо рисовать кучу поверхностей, обеспечить приемлемый радиус отрисовки уже становится трудным, потому что, мать их, чанки с сервера приходят долго. А то что они занимают сокет передачей, лишает некоторой плавности синхронизацию движения игрока в клиенте и сервере. В общем, время передачи чанков на клиент оказывается очень критичным (или нужно изобретать протокол вроде FTP, который бы использовал отдельное соединение для данных чанков). Значит, сообщения должны быть короче, а чанк придется разбить на части при передаче.
Но это еще не вся проблема. В сервере придется понятие "чанк" реализовать тоже, чтобы оптимизировать поиск и отправку всех блоков из запрошенного чанка. Раньше, когда он не мог оперировать таким понятием, ему приходилось вычислять, какие блоки из каких мест нужно вычитывать и последовательно их выдергивать. Я подозреваю, что это слишком медленно.
Но наилучшее решение, которое я нашел для этой проблемы, это оптимизировать число чанков, которые нужно загружать с сервера. Правда, эта часть до сих пор работает очень нестабильно. Работает это так: сначала вокруг игрока загружается минимальная область, скажем, 4х4 чанка. Далее, в текущей реализации, вокруг этой области клиент проверяет, видно ли каждый соседний, еще не загруженный чанк, разыскивая пересечения лучей от углов чанка до игрока и проверяя, сталкивается ли он с непрозрачным блоком внутри такого чанка. Однако, это, видимо, недостаточно точная проверка, потому как игроку не обязательно видеть углы, чтобы видеть кусок какой-то поверхности. И здесь интересно подумать, как сделать это лучше. Но уже так можно не загружать большое количество лишних данных с сервера. Возможно, если эту методику скрестить с понижением уровня детализации для дальних чанков, может быть возможным значительно увеличить дистанцию, на которой можно что-то разглядеть.
Печально в этом всём то, что постоянно приходится переписывать большие куски кода повсюду, так что даже нормальное, приемлемое по производительности, рисование одного типа блоков, похоже, будет возможным еще не скоро. А хотелось бы все-таки заняться чем-то более веселым, например, тем же движением игрока и обнаружением его столкновений с блоками.