вторник, 2 февраля 2016 г.

И снова немного о планетах из кубиков

Как же все-таки из шарика сделать кубик?
Конечно, когда я говорил, что надо пробовать делать "Майнкрафт со сферическим миром", я несколько размыто описал, как же все-таки в итоге можно сделать так, чтобы на поверхности все выглядело как плоскость из кубиков, а высоко вверху - как сфера. Хотя, признаюсь, сначала я отнесся к этому как-то по-наивному просто, решив, что можно и тупо перепрыгивать с левой стороны плоскости в правую и обратно, а на сферу просто такую "текстурку" натянуть, сделанную из плоскости.
Конечно, еще на этапе, когда я попытался сгенерировать такой мир, я понял, что генератор должен тоже понимать, что у него должен быть повторяющийся плавный узор из того, что он сделал, а не просто обрывать его в том месте, где нам больше не нужно ничего. Поэтому, да, есть такая вещь как Sphere в flow-noice, которая позволяет получать значения по координатам вроде долготы и широты в градусах.
И шо, вы таки думаете, что можно вот так вот взять и перенести полученные значения на плоскость? Вообще-то нет.
В общем, главным критерием "правильности" была возможность, в итоге, ползая по полученной плоскости обойти вокруг света за 8 шагов, если ты находишься прямо рядом с полюсом планеты. То есть никакой "растянутости" возле полюса быть не должно, а ведь она обычно есть, и эту проблему долго пытались решать картографы. Причем, если так подойти, то у вас на сферической проекции к полюсам такой широкий на плоскости мир сожмется до невероятно малых размеров.
Раздумия на эту тему, конечно, прошли не без гугла, ведь странно было бы, если бы этим никто еще не занимался. Да, я нашел кучу разных вариантов разной степени паршивости. Например, такой: https://en.wikipedia.org/wiki/Peirce_quincuncial_projection.
Но это не совсем хорошо для нашего случая. Самый крутой для меня вариант, который равномерно размазывает искажения, это проекция поверхности сферы на вписанный в нее куб, но не так, а немного иначе. По крайней мере, мне сейчас так кажется.
Ну и, конечно, нашлось, что это уже не новая идея: https://acko.net/blog/making-worlds-1-of-spheres-and-cubes/
И, получается, единственное, что здесь нужно, это преобразование координат из lat/long в x/y и конкретную поверхность "куба". Что, конечно, чревато некоторыми погрешностями на уровне плавающей точки, но я пока работаю над этим вариантом.
У этого последнего блога есть еще немного просто вдохновляющих и открывающих глаза идей вроде правильного использования SVO, которые выглядят красиво, но я еще не совсем понял, как потом этим пользоваться. И это тоже стоит попробовать.

Ну и... я тут думал запостить еще скриншот для подтверждения, что я таки умею что-то пионерское из кода написать, но подумал, что нафиг надо, и все равно хочется часть переписать, чтобы все "сразу было как надо".

среда, 6 января 2016 г.

Снова про эти воксельные движки

Все-таки, в заду жжет и хочется изобретать велосипед. Однако, вместо очередной попытки сделать что-то в лоб я принялся за изучение имеющихся API, протоколов и внутренних структур Minecraft как одного из наиболее успешных (хотя, все уверены, что он "неоптимизирован", "криво написан", "тормозит потому что жава"). Узнал много интересного, развеял многие свои заблуждения насчет "да блин, это ж так просто". Смотришь так формат хранения/пересылки чего-то и видишь там много интересных особенностей. И начинаешь думать, можно ли сделать как-то иначе, и как-то в голову сразу ничего не приходит (особенно после опыта собственной "жырноты").

Например, о чем я сразу подумал плохо - это об объемах данных, которые нужно перегнать с сервера на клиент, например, чтобы показать мир в радиусе 80 блоков (то есть 10 чанков - по 5 в каждую сторону).
Примем ради простоты, что у нас каждый чанк состоит из 4096 блоков (16х16х16), и каждый блок у нас ничего кроме статичного ID не описывает. И пусть наш ID будет 32-битным (4 байта), потому что мы щедрые и хотим много блоков (или хранить какие-то дополнительные данные о них).
Если загрузить все полностью (и с этим, в принципе, я справился даже с жирнотой, в которой было больше 4-х байт на блок, просто все не так быстро было), то это 10*10*10 чанков, то есть тыща чанков... и если использовать даже по 4 байта на блок, у вас получается 16 мегабайт данных (4096*4*1000). Вроде-бы не космос какой-то для современных сетей. Но так и 10 чанков это не так много - это средние настройки для Майнкрафта. Максимум там 16 чанков (правда, это не радиус, а диаметр). Примерно 64 мегабайта (4096*4096*4), что чуть больше. 100-мегабитная сеть будет грузить это до 10 секунд. Конечо же, в идеале, нужно догнать и перегнать MC, отрисовывая не 8 чанков перед игроком, что всего-то составляет 128 блоков (128 метров). Размер блоков без снижения детализации позволяет рисовать гораздо дальше, создавая офигительный ландшафт, и надо увеличить это хотя-бы раза в два, но это будет не в 2 раза больше по объему, а в 8 (это ведь 3Д, Карл!), то есть, офигенная половина гигабайта (если быть точным, то 32*32*32*4*4096 байт).

Конечно, вы не хотите передавать от сервера клиенту полгигабайта данных (ну может меньше, за счет сжатия), поэтому нужно делать что-то еще, изобретая невероятные способы уменьшить эти объемы. Например, Minecraft целиком "пустые" куски чанков не передает вообще, совершает ряд манипуляций с blockID, чтобы вместо 2-х байт использовать иногда и один. Нам же придется кроме этого добавить и еще что-то вроде уменьшения числа данных о далеких чанках (такой себе LOD) и умные алгоритмы определения, надо ли их вообще загружать, что я уже делал, хоть и криво). И даже если не хочется очень далеко видеть, это очень нужно чтобы уметь быстро двигаться в мире.

Поэтому, кстати, Minecraft начинает как-то медленнее работать, если в него впихивают моды и ставят кучу блоков из них (хотя есть и другая причина, но о ней в следующий раз). Ну и еще стоит помнить, что кроме передачи этих данных по сети, их нужно на сервере хранить на диске и в памяти, и в памяти клиента тоже.

TL;DR: В общем, для тех, кому много букв: движки с унылой воксельной графикой все еще слишком сложны для компьютеров, просто потому что другими их сделать не получится, и из-за этого менее унылые не появятся еще долго.

среда, 11 ноября 2015 г.

Всё не тлен

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

суббота, 31 октября 2015 г.

Все тлен


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

И как люди с этим обычно борются?

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

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

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

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

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


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

суббота, 3 октября 2015 г.

Про электронные сигареты


Не хотел торопиться об этом говорить, но, похоже, после двух недель такого существования я набрал немного опыта. Не все знают, но я курю уже 11 лет и в последнее время меня это стало понемногу напрягать, потому что курить я стал по две, а иногда и больше, пачки в день, и с прошлой попытки бросить стало только хуже. Так что, совершенно случайно заметив, как выглядит и работает современная электронная сигарета, я приобрел себе одну неплохую из тех, что можно посоветовать начинающим - Kanger EVOD Mega. Также, по незнанию, я взял пару разных жидкостей для нее, обе с 6 миллиграммами никотина на 1 миллилитр. Этого, правда, оказывается мало для того, кто курил много, но уже в первые дни обычные сигареты стали интересовать меня намного меньше и я почти не возвращался к ним, выкуривая где-то десяток в день. Спустя несколько дней, в течение которых я немного погуглил, изучил тему и оказалось, что мне стоило выбрать что-то намного более крепкое, и после перехода на 18 мг курить мне не хочется совсем, а один запах дыма вызывает неприятную реакцию. Но о реакции позже. :)
Сразу я обратил внимание, что у вновь начинающих наблюдается какая-то болезнь ньюфага, когда они восторжено начинают рассказывать и пропихивать идею перехода на парилки с курилок. Оно и понятно, потому что впечатлений куча. Первое начинается тогда, когда небольшое количество угарного газа, образующегося при горении, уходит из крови и позволяет транспортировать больше кислорода. От этого, в первую очередь, начинает наблюдаться покалывание конечностей, как бывает, если на них долго лежали и вдруг встали и дали крови нормально циркулировать. Это вызывает необычайное желание бегать, прыгать и рассказывать, как же это круто, парить эти новые штуки. Кроме того, попытки курить вызывают недоумение, потому что вкус и запах дыма уже не так интересны. Но все еще может оставаться тяга к сигарете, потому что в дыме не только никотин вызывает привыкание (гугление позволило узнать, что там еще с десяток веществ, которые имеют тот же эффект). Кроме того, никотин всасывается медленнее и не сразу попадает туда, куда нужно, чтобы тяга пропала моментально, как это бывает при курении.
Потом, правда, эйфория проходит. Где-то через неделю у меня полностью пропал вкус жидкости при парении и это вызвало новый позыв гугла об этой проблеме. Оказалось, это обычное дело и оно проходит само собой. На мое счастье, вкус пропал не полностью, так что еду и напитки я мог нормально воспринимать. Бывает хуже. Прошло это дня через три.
В остальном, тело испытывает симптомы обычного отказа от курения, включая бессонницу и сонливость одновременно, проблемы с пищеварением и все то прочее, что обычно бывает, включая обострение хронического бронхита на пару дней, повышенное выделение мокроты и насморк. Последнее у меня к настоящему моменту прошло. Теперь все кажется вполне обычным делом, однако напрягает возможная реакция окружающих на такую штуковину и связанная с этим проблема парить на ходу.
Однако, особо хочется отметить то, какую реакцию теперь вызывает запах дыма обычных сигарет. Причем, эта реакция намного слабее, если это дым сигары или трубки, например. Этот запах стал жутко раздражать. Я стал замечать этот запах повсюду и даже просто идти по улице стало неприятно, так как число курящих, оказывается, очень велико и они повсюду, они разного пола и возраста. И их запах распространяется на десятки метров вокруг. Так я осознал, насколько антисоциальным было мое прошлое поведение. По сравнению с этим парение, конечно, куда менее раздражает окружающих, так как запаха почти нет и он не такой противный, а иногда даже приятный.
В общем, если кто-то не может бросить курить обычными способами, рекомендую попробовать вот так. Во-первых, даже если после этого не удастся бросить и парить, это, вроде-бы, не так вредно, во-вторых, вполне вероятно, что путем понижения содержания никотина, можно будет и плавно от него отказаться, чтобы бросить совсем. Ну и для меня, в моей стране, это относительно более дешевый способ получения дозы никотина (правда это зависит от марки используемых расходников и частоты прошлого курения).