![]() |
Еще один Minecraft на юнити
Наконец-то доделал демку своего minecraft'а)
Видео http://www.youtube.com/watch?v=TC3dv...ature=youtu.be Плеер http://dl.dropbox.com/u/55489242/Min...WebPlayer.html Исходники http://dl.dropbox.com/u/55489242/Min...1.unitypackage Сразу скажу об одной спорной особенности моей демки. Не знаю как в других реализациях этой игры, но у меня нет одного массива блоков для всей карты. А в каждом чанке храниться кусочек карты. Плюсы: Не нужно следить за двумя массивами(блоков и чанков), а работать лишь с массивом чанковов, а массив блоков автоматически создастся в чанке. При увеличении карты не нужно будет пересоздавать огромный массив блоков, а лишь массив чанков, который в 16 раз меньше. Не нужно тратить кучу памяти на этот массив блоков, если большинство его чанков будят абсолютно пусты. Минусы: Пройтись по такой карте стало немного сложнее, хотя это не сильно надо. Для оптимизации блоки строятся только те, что не имеют всех шести соседей(т.е. могут быть видны) или являются крайними в чанке. Если была бы полная карта, то блоки были крайними на карте, а не в своем чанке. Т.е. из-за этого строится много лишних блоков. На видно это видно с 1:55. Попробую брать соседние чанки и с ними проверять, но это замедлит процесс проверки видимости крайних блоков чанка. Не знаю как лучше сделать. Еще маленький баг виден на 23й секунде видео, когда курсор вылазит за пределы атласа. Можно ограничить область рисования линий? И удаление\добавление блоков работает не быстро. Но мне кажется это тормозит из-за поисков соседей у блоков. Можно как-то проверить наличие всех соседей у блока не проверяя каждого соседа у каждого блока? |
Ответ: Еще один Minecraft на юнити
2032-й год, любой технический ВУЗ, специальность программиста:
— Петров! — Я! — Хеллоу ворлд писал? — Писал. — Сортировку пузырьком делал? — Делал. — Minecraft запиливал? — Не, пока нет. — Пока не сделаешь, к зачётам не допускаешься! |
Ответ: Еще один Minecraft на юнити
Update)
Видео http://www.youtube.com/watch?v=up4MM...ature=youtu.be Веб плеер http://dl.dropbox.com/u/55489242/Min...WebPlayer.html Исходники http://dl.dropbox.com/u/55489242/Min...2.unitypackage Теперь мир генерируется шумом перлина. И генерируется он автоматически вокруг камеры. Генерируются не видимые кубы, а только видимые фейсы кубов, что намного меньше и быстрее. Но вот только проблема, когда генерируется чанк, то и строятся его боковые стороны, которые будут не видны за чанками, которые с генерируются следующими. Получается, что на эти стороны и память и время зря тратиться( Не понимаю как правильно сделать. |
Ответ: Еще один Minecraft на юнити
|
Ответ: Еще один Minecraft на юнити
дык их вообще не строить, так как я не разу в демке не попал в такую ситуацию пока не прокопал вниз. А что с водой?Это тоже куб, или плейн фигурный?
|
Ответ: Еще один Minecraft на юнити
Цитата:
Цитата:
|
Ответ: Еще один Minecraft на юнити
красавчик
|
Ответ: Еще один Minecraft на юнити
только баг нашел, если навести на куб и нажать на E и ответси курсор то выделение остается
|
Ответ: Еще один Minecraft на юнити
mepihin, вообще-то в инвентаре камера не вращается при движении курсора. Так что выделение выделенным остается тот куб, на который смотрит камера.
|
Ответ: Еще один Minecraft на юнити
Цитата:
|
Ответ: Еще один Minecraft на юнити
Спасибо за исходник :)
|
Ответ: Еще один Minecraft на юнити
Прошу сделать (можно отдельную) web-версию, +если возможно подгружать с ж\диска свои текстуры.
Чтобы так, для хобби, 3Д-рисовать, конструировать. +ещё делать снимки на память. Быструю версию, на подобие Web-3D-Paint в минекрафт так и не играл, и его уже никому не переодолеть |
Ответ: Еще один Minecraft на юнити
WISHMASTER35, если все еще занимаешься созданием Minecraft, добавь возможность генерировать случайный мир и генерировать плоскость с определенным количеством кубов. :)
|
Ответ: Еще один Minecraft на юнити
LLI.T.A.L.K.E.R., да, я хочу сделать возможность создавать свои blockSet'ы со своими текстурами и конечно загружать и сохранять уровни.
Radnk, там и так случайный мир генерируется. А генерация плоского мира конечно будет удобна для строительства. Вообще я хочу бесконечный мир заменить на один остров. А то с этой постоянной генерацией куча проблем. Цитата:
Я хотел сделать режим создания уровень и режим сетевого шутера типа C.S. Только возможность разрушать уровень в режиме шутера сомнительна т.к. перестройка будет вызывать рывки, которые будят мешать целится. Хотя заметные рывки могут быть разве при сильном изменении освещения. |
Ответ: Еще один Minecraft на юнити
UPDATE 6
http://www.youtube.com/watch?v=qOeaG2Q686Y Апдейт касается в основном редактора. Еще изменил способ хранения BlockSet, теперь список блоков хранится в xml строке, которая сериализуется. |
Ответ: Еще один Minecraft на юнити
Вложений: 1
Цитата:
Вот это будет что-то кардинально новое. Идея с шутером мне нравится) |
Ответ: Еще один Minecraft на юнити
m_512, это называется marching cubes. Хотелось бы сделать, но как не знаю. Когда-то видел статью на русском, но теперь не могу найти.
|
Ответ: Еще один Minecraft на юнити
Можно сделать имитацию, просто заготовить геометрии мягких переходов и подставлять их.
|
Ответ: Еще один Minecraft на юнити
Не мог бы сделать удаление воды как обычного блока, ибо получается не очень с водой терминатором.
И взорвать THT никак) А так норм:ok: |
Ответ: Еще один Minecraft на юнити
V9.
Не знаю, что будет в Unity 5, но пока я пришел к выводу, что unity плохо подходит для таких проектов. Нельзя читать\записывать в RenderTexture. Нельзя создавать меш со своим набором данных. Например сейчас на позицию вершины уходит три float, а достаточно было бы трех байтов. Так же и с нормалью, освещением и uv. Сглаживание блоков так и не пробовал делать, потому что не представляю как садить на такие блоки всякую траву, заборы и другое. Может получится, что трава весит в воздухе над сглаженным блоком земли. Освещение для MineCraft это проблема. При его изменении, необходимо перестроить все чанки, у которых изменилось освещение. Хорошо было бы хранить освещение не в меше, а в отдельной 3д текстуре. И в вершинном шейдере брать освещение. Но тогда размер текстуры будет под 1024x1024x256. Возможно можно создать octree или тайловую текстуру. |
Ответ: Еще один Minecraft на юнити
Круто выглядит! Демка будет?
В тег надо было запихать только эту часть "youtube.com/watch?v=LfJYNYPKi_w" |
Ответ: Еще один Minecraft на юнити
Ссылки на демки в описании видео.
https://dl.dropboxusercontent.com/u/...nd%209.2.1.rar Круто, но если бы не ограничения юнити, то было бы намного круче. Хоть на с++ начинай писать плагины. Хотя тогда веб плеер сразу отпадет. Да и черт знает как на с++ создать меш со своими данными и рендерить его. |
Ответ: Еще один Minecraft на юнити
Выглядит явно симпатичнее оригинала. Это офигенно) Может, делать не совсем майнкрафт, а с какой-нибудь фичей?
P.S. Могу попробовать написать сервер на java, играть по сети на порядок интереснее. |
Ответ: Еще один Minecraft на юнити
Igor, оригинал сам по себе довольно простой. А вот с модами MineCraft бывает очень красивый.
Я насобирал текстуры из самого MineCraft, Worms3D, Terasology и др. А вот генератор мира у меня все еще простой. Ты описываешь какую-то стратегию? Я если и сделаю из этого игру, то просто сетевой шутер. Но наверно я никогда не дойду до этого. Сейчас у меня все еще есть идеи по оптимизации рендера, но времени нет. |
Ответ: Еще один Minecraft на юнити
Производительность Mono - дело весьма странное.
Порой, чтобы функция работала в 2 раза быстрее, ее нужно разбить на несколько функций. Наверно самым тормозным местом является функция получения соседних блоков. Переводить мировые координаты в координаты grid и local, а потом еще в индексы для массива - дело медленное. Поэтому написал такую весьма запутанную функцию. Теперь время снизилось с ~20 сек. до ~7 сек. Если разделить это все на 7 функций: Теперь скорость ~4.9 сек. И это еще тратиться некоторое время на еще один вызов функции. А если напрямую вызывать эти функции: Тогда вообще ~2.9 сек. :4to: |
Ответ: Еще один Minecraft на юнити
Давно не выпускал новых версий. Уже не могу особо ничего сделать. Есть идеи, которые пока не знаю как реализовать или может быть их вообще не реализовать. Напишу их здесь.
1) Хранить террейн, деревья и др в разных структурах. + Это позволило бы одним кликом добавлять\удалять целые объекты. + Вероятно сэкономило бы много памяти, т.к. хранить byte данных для блоков террейна или деревьев не нужно. Этот байт нужен лишь, блокам, которые имеют направление или для двери, которая имеет состояние открыто\закрыто. + Т.к. обычно блоков террейна меньше 15, то на блок можно выделить 4 бита, а для блока дерева вообще 2 бита. - Преимущества есть, но недостатки тоже имеются. Нельзя будет просто и быстро получить блок в рандомной позиции. Это как минимум делает невозможным текущие освещение. 2) Объединять одинаковые фейсы. + Было бы очень здорово значительно уменьшить количество полигонов. - Из-за использования атласов, вероятно это невозможно. А Texture2DArray в юнити пока недоступен. Из-за вершинного освещения можно будет соединить далеко не все фейсы. - Соединить фейсы по одной оси - легко. Достаточно сравнивать текущий фейс с предыдущим. А как соединить фейсы по двум осям - я слабо представляю. И вопрос как это повлияет на скорость создания меша. 3) Компактный формат вершин меша. Сейчас только на позицию вершины выделяется 3 float == 12 байт. Хотя чтобы задать позицию достаточно 2х байт. С остальным так же. Если использовать геометрический шейдер, то можно хранить лишь одну координату, а из нее восстанавливать траву, фейс или целый бокс. Это можно сделать используя ComputeBuffer и Graphics.DrawProcedural. 4) Сжатие чанков. Если забить на скорость рандомного доступа к блоку, то остаются такие требования: * Быстрая итерация по чанку. * Быстрый доступ к соседним блокам. Первое легко выполняется в RLE и наверно в Octree. А вот со вторым выходит проблема. Но на самом деле необязательно иметь доступ к соседнему блоку. Достаточно знать заслоняет ли он фейс текущего блока или нет. Т.е. для непрозрачных блоков нужно знать, соседний блок прозрачный или нет. А для прозрачных блоков нужно знать, соседний блок такого же типа или нет. Ведь между двумя блоками воды не создаются фейсы. Для блока забора и подобное тоже надо знать некую информацию о соседях. В общем эту информацию можно уместить в 6 бит и вычислить до сжатия чанка. + экономия памяти. + Если использовать Octree, то возможно сделать LOD'ы. + итерация по чанку и создание меша может стать быстрее. - но на предрасчет информации о соседях - нужно время. Для изменения блока, необходимо изменить и соседние блоки. Сжатый чанк усложняет изменение блока. В результате весь профит от быстрой итерации и создания меша пропадет. 5) Освещение. Это фейковое global illumination создает много! - хранение света в вершинах меша. - это вынуждает пересоздавать меш чанка, если свет в нем изменился. А за кадр освещение может изменится во многих чанках. - если объединять одинаковые фейсы, то вершинное освещение сильно уменьшить количество объединенных фейсов. - чтобы свет для всей карты считался максимально быстро, нужно все источники света добавить в одну FIFO очередь. А затем постепенно рассеивать свет из этой очереди. Для карты 512x512 размер такой очереди получается ~100тыс. И распараллелить этот алгоритм нельзя. - необходимость быстрого рандомного доступа к блокам. - потребление памяти. Прямой свет хранится просто в 2д массиве. А рассеянный свет хранится, как и блоки, в 3д массивах(чанках). Хотелось бы более экономную структуру для света. + для карты 512x512 свет рассчитывается за 2.5 сек. И это в редакторе Unity. Довольно хороший результат. Более подробно об освещении в следующих постах. |
Ответ: Еще один Minecraft на юнити
Вложений: 1
Обычный алгоритм расчета освещения(2д версия):
В общем суть такова, что каждая LightPoint из очереди пытается осветить все соседние ячейки. С учетом Dir, все, кроме одной. Если осветить соседнюю ячейку получилось, то ее координата добавляется в очередь. |
Ответ: Еще один Minecraft на юнити
Вложений: 2
Сжатие света.
LightChunk можно хорошо сжать, если хранить только максимальные точки света(maxLightPoint) в каждом столбце. Тогда, чтобы вычислить свет в любой ячейки, надо найти в столбце ближайшую maxLightPoint. Только надо учитывать, что между текущей ячейкой и maxLightPoint может быть непрозрачный блок. Или в maxLightPoint хранить до куда она достает. Т.е. получится такая структура градиента {y1, light_1, y2, light_2}. Тогда надо просто найти градиент, в которую попадает наша ячейка. |
Ответ: Еще один Minecraft на юнити
Вложений: 2
Другие методы вычисления освещения.
1) Можно сгруппировать источники света в боксы. Тогда чтобы вычислить свет в любой ячейки, достаточно будет вычислить расстояние до ближайшего LightBox. Но это без учета непрозрачных блоков. А вот как учитывать непрозрачные блоки, не представляю. Возможно, в каждом LightBox'е хранить расстояние до которого он досвечивает. А там, где свет заворачивает, создавать вторичные источники света. Т.е. типа разрезать этот желтый ромб, на несколько простых фигур, точно описывающих форму света. Получаются такие себе объемы распространения света. + расчет этих объемов для каждого чанка - независим и может быть распараллелен. Т.е. 1 thread == 1 chunk. А может и несколько потоков на чанк. + расчет света в ячейках, тоже может быть параллелен. + для хранения этих объемов должно требоваться намного меньше памяти. На LightChunk(32x32x32) нужно 32кб. Если использовать 4 бита на ячейку света, то 16 кб. Для хранения LightBox'а нужно: (byte x,y,z, xSize, ySize. zSize, light) == 7 байт. На 32кб можно хранить 4681 таких LightBox'ов. Можно сжать, если на координату и размер использовать 5 бит, а на свет 4 бита, то нужно 34 бита == 5 байт. Может можно еще как-то сжать. 2) Есть идея разбить пространство на такие боксы, чтобы внутри бокса, между любыми двумя ячейками, не было преград. Имея список LightPoint'ов внутри бокса, вычислить освещение для любой ячейки бокса будет очень просто. Но есть вопрос, как передать освещение из одного бокса в другой. Можно в light list соседних боксов добавлять вторичные источники света. Или искать свет и в соседних боксах. Но пока я даже не представляю как вычислить такие боксы. 3 Хорошо бы перенести освещение из вершин в постобработку. Тогда надо решить два вопроса: * как хранить освещение на видюхе. Обычно освещение хранится в octree. Я предпочел бы Grid of Chunks. Grid - 3д массив чанков. Chunk - или просто 3д массив ячеек света, или octree, или список только ячеек, которые граничат с геометрией, или другой сжатый формат. * как наложить освещение в пост обработке. Или может быть сразу во время рендеринга освещать. (deferred \ forward) С этим должно быть проще. Только вероятно надо будет в каком-то буфере хранить тип и позицию блока. Не знаю возможно ли такое создать на DX11 и юнити сделать. 4 А может было бы проще сделать физически корректное Global Illumination, в котором свет отражается, а не заполняет пустые ячейки. Voxel Cone Tracing вычисляется свет для каждой группы пикселей 4x4, и каждый кадр. На моем железе это выдает несколько фпс. Думаю можно оптимизировать для MineCraft. Для этого нужно: * вычислять свет для блоков, а не пикселей (На чанк таких блоков обычно ~2тыс). * вычислять только после изменения геометрии и сохранять. А не каждый кадр. К сожалению VCT дает утечки света, но если бы удалось его реализовать без тормозов, то все равно было бы круто. Или сферические гармоники использовать, но я пока точно не понимаю как они работают. Если не получится улучшить освещение, то лучше его вообще удалю. Вроде все идеи описал. Не знаю осилит ли кто-то прочитать эти посты)) Может у кого-то есть еще идеи по освещению? |
Ответ: Еще один Minecraft на юнити
Вложений: 1
Цитата:
Внутри красного бокса все прозрачные ячейки имеют прямой доступ ко всем другим прозрачным ячейкам. А синие точки это ячейки, которые не имеют прямого доступа друг к другу. Но не представляю как разбить пространство на такие боксы. |
Ответ: Еще один Minecraft на юнити
Вложений: 2
Цитата:
Даже в таком случае есть доступ. |
Ответ: Еще один Minecraft на юнити
Вложений: 1
Продолжу монолог.
Light Radiance - текущий алгоритм Снял видел объясняющее как работает Light Spread алгоритм в MineCraft. Честно сказать, я до этого не совсем правильно представлял как он работает)) Все LightPoint'ы добавляются в очередь и равномерно рассеиваются. Когда одна LightPoint встречается с другой, то рассеивание прекращается. По этой причине для максимальной производительности необходимо добавить в очередь все LightPoint'ы сцены (А это сотни тысяч). И многопоточность нельзя использовать т.к. используется только одна очередь. Light Gathering Можно вычислять свет лишь для блоков, граничащих с твердыми блоками или содержащими в себе траву или что-то подобное. На рисунке эти блоки выделены красным. Вот видео показывающие работу такого алгоритма. Плюсы такого метода: - Можно вообще не выделять память на хранение освещение. Разве какие-то ускоряющие структуры создать. - Легко распараллеливается. Но есть и серьезные недостатки: Метод Light Spread в посещенные ячейки записывает освещение, поэтому алгоритм второй раз в одну и тужу ячейку не зайдет. И вообще не зайдет в ячейку, в которой уже есть свет, который больше текущего. Можно создавать массив в который записывать посещенные вершины. Думаю, можно 1 bit на вершину. Но этот массив придется каждый раз чистить. Пока не представляю сколько времени займет такой алгоритм, но памяти он экономил бы много. Задача в общем-то сводится к графу, каждая вершина которого содержит\не содержит свет и имеет уровень прозрачности (воздух, вода, непрозрачный). Вот и надо обойти все соседние вершины и собрать с них свет. Может у кого-то есть идеи как это можно ускорить или не хранить посещенные вершины? Правильный Global Illumination Ray Tracing Мне парой кажется, что нормальный Global Illumination будет не медленнее, чем тот Light Gathering. Можно Indirect Lighting вычислять не для всей сцены, а для куска карты, вокруг игрока. На карте 256x256x256 есть ~230тыс блоков, для которых надо вычислить свет. Для сбора света из hemi-cube размером 64 нужно 12288 луча, это не так и много. Код:
int faceArea = 64 * 64;И того. 12.288 лучей * 230.000 ячеек = 2.826.240.000. Почти 3 миллиарда лучей - очень огромное число. И это только для одного bounce. Если бы можно было вычисление света разделить на несколько кадров. Сначала 1й bounce, потом 2й bounce. Еще можно сделать, чтобы за кадр пускался только каждый десятый луч, типа сначала четные, потом нечетные. Было бы терпимо, если бы свет полностью перевычислялся за 0.5 - 1 секунду. Но вряд ли даже за минуту можно пустить такое кол-во лучей. :"( LVP Можно при изменении геометрии пересчитывать сферические гармоники. Тогда освещение нужно будет собирать с ячеек, которые попали внутрь объема сферической гармоники. Если я вообще правильно понимаю смысл сферических гармоник. Но я понятия не имею сколько времени нужно на перерасчет сферических гармоник. Список видимых ячеек Просто для каждой ячейки хранить список видимых ячеек. Для многих ячеек такой список будет одинаковым или почти одинаковым, поэтому можно будет хорошо сжать. Собрать освещение из готового списка ячеек - самое простое. Но этот список надо еще вычислить и сжать. Как вычислить, сколько времени это займет - тоже вопрос. |
Ответ: Еще один Minecraft на юнити
|
Ответ: Еще один Minecraft на юнити
Выглядит офигенно!
|
Ответ: Еще один Minecraft на юнити
Знатная работа проделана!
Монстр напомнил скелетика из Keep Out |
Ответ: Еще один Minecraft на юнити
|
Ответ: Еще один Minecraft на юнити
Сделал несколько панорамных скриншота. Пост эффекты пришлось отключить т.к. они обычно зависят от направления взгляда и получалось черти что.
https://www.facebook.com/terra.voxel...83283398395233 |
| Часовой пояс GMT +4, время: 01:28. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Перевод: zCarot