Показать сообщение отдельно
Старый 13.02.2015, 22:32   #26
WISHMASTER35
Бывалый
 
Аватар для WISHMASTER35
 
Регистрация: 21.12.2008
Адрес: UA
Сообщений: 878
Написано 105 полезных сообщений
(для 357 пользователей)
Ответ: Еще один 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. Довольно хороший результат.
Более подробно об освещении в следующих постах.

Последний раз редактировалось WISHMASTER35, 14.02.2015 в 02:29.
(Offline)
 
Ответить с цитированием