Статьи о картостроении
Оптимизация карты
или "сделайте нам быстро"
Dzug@ru
12-VI-2003 г.
По просьбе
одного человека я написал эту статью об оптимизации
карт в Half-Life. Начнём с самого простого. Итак, движок
Халвы оперирует 2 типами объектов — энтити и браши.
Первое — все активные объекты, вторые, грубо говоря
— части уровня, т.е. блоки. Первые подгружаются из сохранялок,
вторые непосредственно из BSP-файла. Вся геометрия
разбивается на грани, которые разбиваются на треугольники —
элементы граней (почему? потому что просчёт выпуклых многоугольников проще и быстрее,
а треугольник — единственный всегда выпуклый многоугольник).
Простая логика подсказывает, что чем
больше этих треугольников, тем большую работу
приходится выполнять движку по отрисовке одного
злосчастного кадра. Как узнать количество
граней на уровне? Наберите в консоли
gl_wireframe 1 или лучше сразу
gl_wireframe 2
Впечатляет? Тогда идём дальше — как всё это привести в порядок.
Любой маппер всегда разрывается между двумя задачами
— сделать самый навороченный и одновременно самый
шустрый уровень. Сделать уровень шустрым может
либо упрощение геометрии, либо убирание паразитных
граней, образованных в результате BSP-компиляции.
Движок Халфы устроен так, что не допускает наложений
граней, поэтому любая грань объекта попадающая
в плоскость с другой, эту самую другую разбивает
на новые грани. Нетрудно подсчитать, что два пересекающихся
прямоугольника по 6 граней каждый в лучшем случае
наплодят 9х6=32 грани. Особенно много паразитных
граней вызывают колонны. Это просто бич какой-то.
Методы борьбы чрезвычайно просты. Поскольку энтити
не учавствуют в BSP компиляции, они не разбивают
геометрию. Следовательно все трубы, колонны и
объекты сложной геометрии, касающиеся стен, следует делать func_wall'ами
(а в недоступных для трогания местах даже неосязаемыми func_illusionary).
Прирост производительности иногда бывает достаточно
ощутимым. НО! параллелограммы и кубы эффективнее оставлять брашами, так как браш движком виден в пределах одного помещения, а брашевая энтить станет видна движком издалека — и за стеной в соседнем помещении и вообще через половину карты.
Рис. 1 — Изображение в игре Half-Life со включённым кодом gl_wireframe 2 показывает контуры объектов-энтитей за стеной.
Видимость энтитей движком из точки зрения игрока зависит от заданной дальности обзора. Предельная дальность задаётся в целых линейных единицах:
- А) в базовых настройках карты в редакторе: к примеру, в Hammer-е в меню Map -> Map properties... -> выставить значение параметру Max viewable distance и/или
- Б) в строке настроек компилятора hlvis добавить параметр -maxdistance с величиной через пробел.
Всё, что окажется дальше и не будет загорожено более близкими препятствиями, закрасится небом.
При создании полых труб часто делают их с помощью вырезания (carve)
меньшего цилиндра из большего. В результате получается плохо стыкующиеся косые элементы, а если
они прислонены к стене (хотя вы наверно уже оттянули где можно на 1 единицу), то появляется разлёт
рёбер на текстуре стенки, напоминающий лопатки турбины в профиль (см. Рис. 3). Трубы и другие полые цилиндры лучше делать с помощью примитива Arch — Арка:
Рис. 2 — Настройки инструмента Создание арки — Arch [arch в самих настройках переводится ещё и как дуга].
А теперь пример разбиения многогранников на бочках, стенки которых
построены слева выкраиванием цилиндра из цилиндра, а справа с помощью арки в 360° с толщиной стенки 2 единицы:
Рис. 3 — Разбиение от выкраивания и построения "арки".
Впрочем не только браши вызывают дробление геометрии,
но и обычные.. текстуры. Чем выше масштаб текстуры,
тем на большее число многоугольников разбивается многострадальная
грань. Т.е при девятикратном уменьшении масштаба
текстуры 256х256, многоугольник такого же размера превращается
в 9 многоугольников. Или если случайно на тонкий параллелепипед (например, оконного стекла) для всех сторон автоматически растянуть текстуры на грани,
то на узких гранях сверхплотное наложение текстуры вызовет ошибки.
Ладно, текстуры у вас ужасно растянуты и чуть
ли не весь уровень стал "стенками".
Что ещё?
Много чего. Начнём с того, что при BSP-компиляции
все грани с наружной стороны уровня, принадлежащие
каркасу столкновений для точечных объектов (т.н. HULL 0),
удаляются. Удаляются они, если на уровне нет дыр.
А если есть дыры, и маппер обтянул уровень большой
коробкой во избежание утечек пространства (LEAK'ов),
то удаляется лишь внешняя сторона этой самой коробки,
и уровень жутко тормозит, хотя мог бы быть обрезан
компилятором минимум вдвое. Так же хорошего прироста
производительности дает Vis, запущенный с параметром
-full, но начинающие мапперы им редко пользуются,
т.к. он долгий, и после него ужасно тормознуто
работает rad (лучше зонеровский hlrad). Хочу сказать этим маперам, что применение
Виза на завершающем этапе компиляции просто ОБЯЗАТЕЛЬНО,
хоть он и работает час-полтора.
Если карта продолжает тормозить, возможно на уровне
много ентить с большим количеством граней,
как-то монстров, высокодетализированных моделей оружия,
и импортированных моделей в объектах типа monster_furniture, monster_generic и cycler.
Простой совет: наберите в консоли r_speeds 1
Значение w_poly (world — на брашах, текстуры секторов BSP пространства) не должно в идеале превышать
800 – 1000 граней, а e-poly (ентити) — 10000 – 20000 граней. Очевидно, что чем больше отрисовывается движком,
тем вероятнее перегрузка и заметнее подтормаживание.
Если карта заполнена цилиндрами и вообще (неподвижными и иногда и подвижными) сложными деталями,
разбивающими BSP-пространство на множество невидимых подсекторов, то лучше перевести такие выкрутасы в модели.
Для экспорта объёмных структур из карты в модели Flash_AD посоветовал использовать универсальный просмотрщик карт и моделей
Crafty от Райана Грегга (также известного как Nemesis). Для этого удаляете на карте как можно больше ненужного,
открываете программой Crafty, экспортируете в файл формата .obj. И импортируете полученный файл в
редактор моделей kHED.
Там удаляете лишние грани, накладываете текстуры и экспортируете в файл модели формата .mdl.
Может быть под конец где нужно добавляете на текстуры готовой модели эффект хромированной поверхности или другие
текстурные эффекты. Выставляете на карту и прирост скорости работы. Тут могут возникнуть только две загвоздки.
Во-первых, структура модели не должна сильно заходить в другие помещения за стенками, чтобы не было такого, что выйдешь за пределы этих стен,
а там всё пропадает, так как скелетная вершина находится в предыдущем помещении, которое не видно.
А во-вторых, освещение на моделях может выглядеть хуже, и понадобится правильно перерасставить скелетные вершины,
а также кое-где выставить параметр
effects = 16, берущий освещение не с пола, а с потолка, на объектах с моделями cycler_sprite или monster_furniture
(а в некоторых случаях непроходимый cycler или env_model для модов, поддерживающих код этого объекта из мода
Spirit вроде нашего H-L Red Alert).
Вот в общем и всё. Красивых и (главное) шустрых
вам карт, товарищи мапперы! :)
|