Tilemap rendering
|
|
soos | Дата: Понедельник, 20.06.2011, 21:19 | Сообщение # 1 |
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
| Есть идея сделать трёхмерный клиент для одной MMORPG. После анализа протокола выяснилось, что карта куска поверхности передаётся с сервера в виде массива тайлов 100х100. Попробовал отрисовывать этот кусок как 10000 копий отдельных объектов, скорость никуда не годится, а это только лишь небольшая часть карты. Попробовал делать instance'ы вместо копий, результат такой же. Видимо, нужно создавать один объект и для него, каким то образом, динамически генерировать текстуру из текстур тайлов. Подскажите, пожалуйста, как подобное лучше и эффективней реализовать.
|
|
| |
serg-kkz | Дата: Понедельник, 20.06.2011, 21:34 | Сообщение # 2 |
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
| Зачем серверу передавать ресурсы игры? когда они должны уже быть в клиенте. Разве для обновления.
ООП -
|
|
| |
soos | Дата: Понедельник, 20.06.2011, 21:40 | Сообщение # 3 |
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
| Quote (serg-kkz) Зачем серверу передавать ресурсы игры? потому что ландшафт динамически меняется
|
|
| |
serg-kkz | Дата: Понедельник, 20.06.2011, 21:55 | Сообщение # 4 |
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
| Как это понять. Есть локация которая состоит 3D обьектов частей ландшафта которые загружаютя опять таки по мере надобности из ресурсов клиента но никак из сервера. Так же и с отресовкой только часть ландшафта которые находятся в близи игрока(камеры) в общем нужно писать менеджер обьектов который будет загружать части ландшафта и лоды для них. А загрузка обьектов в реальном времени с серевера. это не реально либо пропускная способность интернет канала должа быть выше чем у видио карточки и оперативки.
ООП -
Сообщение отредактировал serg-kkz - Понедельник, 20.06.2011, 21:57 |
|
| |
ninth | Дата: Понедельник, 20.06.2011, 21:59 | Сообщение # 5 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| для начала посмотри сюда: RigidBodyCombiner http://panda3d.org.ru/forum/9-115-2692-16-1295432944 второе - неужели у тебя видна сразу вся площадь 100 * 100 тайлов? Я думаю - нет, тогда просто стоит достраивать нужные тайлы на лету, а те, которые ушли из виду - убирать.
|
|
| |
soos | Дата: Вторник, 21.06.2011, 07:39 | Сообщение # 6 |
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
| Quote (ninth) для начала посмотри сюда: RigidBodyCombiner http://panda3d.org.ru/forum/9-115-2692-16-1295432944 Спасибо, RigidBodyCombiner очень помог, отрисовка поверхности 300х300 тайлов выдаёт приличную скорость. Но я думаю что динамически генерировать текстуру для плоскости будет эффективнее, есть ли для этого у панды какие то встроенные средства? Или, может быть, есть какие то стандартные способы взаимодействия с библиотеками типа NumPy для генерации текстур "на лету"? Quote (ninth) второе - неужели у тебя видна сразу вся площадь 100 * 100 тайлов? Я думаю - нет, тогда просто стоит достраивать нужные тайлы на лету, а те, которые ушли из виду - убирать. В масштабе игры тайл - это кусок метр*метр. Видимость на 100 метров в каждую сторону, имхо, это нормально. Официальный клиент игры (косоугольная проекция, 2.5D) не показывает всю территорию, но мне хотелось бы сделать видимым всё что пересылает сервер.
|
|
| |
serg-kkz | Дата: Вторник, 21.06.2011, 09:39 | Сообщение # 7 |
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
| Меня очень сильно распирает любопытство... Ты решил написать свой клиент уже для существующей MMORPG? Но клиент не только принимает данные от сервера, но и отправляет, делает запросы... это как ты реализуешь, прежде чем получить тайл его надо запросить. О какой MMORPG идёт речь если не секрет? Всё таки я сомневаюсь что сервер пересылает ресы, хотя... впрочем Google Earth работает по такому принципу.
Quote (soos) сделать видимым всё что пересылает сервер ...Хм такое желание может быть только у игрока...
ООП -
Сообщение отредактировал serg-kkz - Вторник, 21.06.2011, 09:51 |
|
| |
soos | Дата: Вторник, 21.06.2011, 10:06 | Сообщение # 8 |
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
| Quote (serg-kkz) Ты решил написать свой клиент уже для существующей MMORPG? Да. Quote (serg-kkz) Но клиент не только принимает данные от сервера, но и отправляет, делает запросы... это как ты реализуешь, прежде чем получить тайл его надо запросить Очевидно, что я его запрошу. Дело в том, что протокол передачи данных немного странный и поэтому передача всех данных необходимых для отображения видимой области а также всех GUI элементов происходит сразу после логина, а не по запросу клиента. Клиент только подтверждает получение. Quote (serg-kkz) О какой MMORPG идёт речь если не секрет? Не секрет - это http://www.havenandhearth.com/portal/ Quote (serg-kkz) Всё таки я сомневаюсь что сервер пересылает ресы Я написал скрипт который позволяет логиниться в игру и парсер протокола обмена данными (исходники официального клиента игры открыты, так что это было не сложно сделать). Поэтому точно могу сказать, что пересылает.
|
|
| |
serg-kkz | Дата: Вторник, 21.06.2011, 10:34 | Сообщение # 9 |
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
| Дык это псевдо 3D. Обьекты и ландшафт это просто рендер изображения полученые в 3D редакторе с прозрачностью как правило png, тоесть спрайты. 3D клиент на основе их уже не получится так как сервер берет в расчёты 2D координаты. Хотя если мир в игре плоский то координату Z можно сделать постоянной. Но мир прийдётся моделить занова и ресы хранить всё таки на стороне клиента а растановку делать основоваясь на 2D координатах обьектов присланых с сервера. Тока один нюанс надо зарание что может прислать сервак, тоесть все виды обьектов и прочее.
ООП -
Сообщение отредактировал serg-kkz - Вторник, 21.06.2011, 10:46 |
|
| |
soos | Дата: Вторник, 21.06.2011, 11:00 | Сообщение # 10 |
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
| Quote (serg-kkz) 3D клиент на основе их уже не получится так как сервер берет в расчёты 2D координаты Почему это не получится? Сервер получает ID объекта (для манипуляций с объектом) или координаты на плоскости (для перемещения персонажа). Ничто не мешает мне рассчитывать эти 2D координаты.
Quote (serg-kkz) Хотя если мир в игре плоский то координату Z можно сделать постоянной. Но мир прийдётся моделить занова и ресы хранить всё таки на стороне клиента а растановку делать основоваясь на 2D координатах обьектов присланых с сервера. Всё верно. Так и задумано.
Quote (serg-kkz) Тока один нюанс надо зарание что может прислать сервак, тоесть все виды обьектов и прочее. видимо пропущено слово "знать". Да. Надо знать. По мере появления новых вещей в поле зрения, сервер присылает ID и название расурса, надо знать все названия ресурсов и иметь для них модель. Клиент может запросить у сервера изображение ещё не закешированного объекта, но для альтернативного клиента это не прокатит.
Мы "немного" отклонились от темы. Как же всё таки создавать плоскость поверхности с динамически генерируемыми текстурами на основе тайлов? Насколько я понимаю, самое лёгкое (по ресурсозатратам) и самое убого выглядещее (но на первых порах сойдёт) - это, каким то образом, сделать из карты тайлов текстуру 100х100, и наложить эту текстуру на плоскость. Как это можно реализовать?
Сообщение отредактировал soos - Вторник, 21.06.2011, 11:08 |
|
| |
serg-kkz | Дата: Вторник, 21.06.2011, 11:23 | Сообщение # 11 |
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
| Да похоже прийдётся брать модель равной размеру тайла и растанавливать основаваясь на позиции тайла, потом на модель накладовать тайл. То есть моделей будет столько же сколько и тайлов. Но опять таки нюанс перспектива с которой отрендили тайл не годится. Нужно ровно с верху для 3D. Эх получить бы исходники ресурсов контента. А размеры тайла ландшафна все одинаковые?
ООП -
|
|
| |
ninth | Дата: Вторник, 21.06.2011, 11:59 | Сообщение # 12 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Quote (soos) Насколько я понимаю, самое лёгкое (по ресурсозатратам) и самое убого выглядещее (но на первых порах сойдёт) - это, каким то образом, сделать из карты тайлов текстуру 100х100, и наложить эту текстуру на плоскость. Как это можно реализовать?
Скажем так, это наиболее очевидное решение. Насчёт убогости - не хуже других. А вот по ресурсозатратам может быть довольно тяжёлым - имются ввиду ресурсы компа. Какого разрешения предполагаются куски земли? Например 256 * 100 = 25600 Текстурка разрешением 25к Х 25к зохавает твой моск ))) В смысле съест всю оперативку. Это раз. Второе - эффективно работать с изображениями можно только через шейдеры, всё остальное довольно тормозное - для примера посмотри на скорость работы любого растрового редактора. Но если очень хочется - смотри в сторону PNMImage и PIL.
Более правильное решение - генерировать и оптимизировать поверхность на лету, назначая отдельным полигонам нужные текстуры, но здесь уже придётся лезть в дебри, к чему лучше сначала морально подготовиться )
В общем для начала я бы советовал оставить генерацию поверхности таким образом как у тебя сейчас. Подумать об оптимизации можно будет позже, иначе ты сейчас рискуешь убить очень много времени, а в итоге окажется что прирост производительности не такой уж и большой или какая-то другая вещь тормозит значительно больше.
|
|
| |
soos | Дата: Вторник, 21.06.2011, 12:45 | Сообщение # 13 |
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
| Quote (serg-kkz) Да похоже прийдётся брать модель равной размеру тайла и растанавливать основаваясь на позиции тайла, потом на модель накладовать тайл. То есть моделей будет столько же сколько и тайлов. так сейчас и делаю: Code tiles = loader.loadModel("models.egg") tile1 = tiles.find('**/tile1') tile2 = tiles.find('**/tile2') tile3 = tiles.find('**/tile3') tile4 = tiles.find('**/tile4') tile1.setPos(.0,.0,.0) tile2.setPos(.0,.0,.0) tile3.setPos(.0,.0,.0) tile4.setPos(.0,.0,.0) tiles = [tile1,tile2,tile3,tile4]
rbc = RigidBodyCombiner("rbc") terrain = NodePath(rbc) terrain.reparentTo(render)
for x in xrange(-50,50): for y in xrange(-50,50): tile = terrain.attachNewNode('tile') tile.setPos(x,y,0) random.choice(tiles).instanceTo(tile) rbc.collect()
Quote (serg-kkz) Но опять таки нюанс перспектива с которой отрендили тайл не годится Я не собираюсь использовать официальный контент (ресурсы), только состояние мира.
Quote (serg-kkz) Эх получить бы исходники ресурсов контента Без проблем, весь или почти весь контент выкачивается с сервера при сборке клиента.
Quote (ninth) Более правильное решение - генерировать и оптимизировать поверхность на лету, назначая отдельным полигонам нужные текстуры, но здесь уже придётся лезть в дебри, к чему лучше сначала морально подготовиться ) Можно попросить рассказать поподробнее об этом? Насколько я понимаю в данном случае придётся писать свой класс на С++ реализующий новый вид TerrainGenerator'а? Дело в том что динамически делать rbc.collect() - это довольно ресурсоёмкая задача, учитывая что такие grid'ы 100х100 нужно создавать довольно часто.
|
|
| |
serg-kkz | Дата: Вторник, 21.06.2011, 13:01 | Сообщение # 14 |
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
| Ну для оптимизации могу предложить использавть колизии, например повешать на камеру сферу нужного диаметра равной обзору игрока и делать проверку есть ли колизия с полигоном, если есть то вносить в рендер либо скрывать из рендера, далее получать имя полигона и накладывать на него нужный тайл, а если нет колизии то выгружать. Правда модели всё таки прийдётся всё загружать. Думаю можно попытаться.
Ещё можно попробовать повертеть base.camLens.setNearFar(1.0, 1.0), здесь устанавливается линейная видимость камеры
ООП -
Сообщение отредактировал serg-kkz - Вторник, 21.06.2011, 13:30 |
|
| |
ninth | Дата: Вторник, 21.06.2011, 14:29 | Сообщение # 15 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Quote (soos) Можно попросить рассказать поподробнее об этом? Насколько я понимаю в данном случае придётся писать свой класс на С++ реализующий новый вид TerrainGenerator'а?
Можно и так сказать, но в данном случае тебе не нужен именно террайн генератор, т.к. его задача в том числе и тесселяция поверхности (увеличение кол-ва полигонов вблизи, уменьшение вдали). У тебя должны будут укладываться 1полигон - 1 тайл. Не обязательно это всё на си - можно и на питоне для начала ) смотри в эту сторону http://www.panda3d.org/manual/index.php/Main_Page Advanced operations with Panda3D's internal structures
а касабельно rbc.collect() - можно сделать не 100 на 100, а например 4 на 4 rbc, каждый из которых содержит 25 x 25 тайлов и обновлять/добавлять только нужные. Плюс построение карты вынести в параллельный поток чтобы не тормозить перемещение пока обновляется.
|
|
| |