Когда карта компилируется с помощью vvis.exe, для каждой точки
определяются объекты, которые могут быть видны из нее во время игры.
Размер этих потенциально видимых областей (PVS - potentially visible
set) напрямую влияет на производительность игры. Данная статья
расскажет о работе некоторых инструментов для левел-дизайна, которые
помогают контролировать видимость и улучшать производительность, таких
как ареапорталы (areaportals), хинт-браши (hint brushes), окклудеры
(occluders) и detail-браши. Некоторые из них при правильном
использовании могут значительно уменьшить время компиляции vvis`ом и
увеличить производительность игры.
Содержание
1 Листья 2 Glview 3 Hint-браши 4 Ареапорталы 5 Окклудеры 6 Техника создания геометрии 7 Detail-браши 8 Вода 9 Модельная геометрия против брашевой 10 Дальность видимости геометрии 11 Разрез и затуманивание 12 Выбор материала и скорость рендеринга 13 Решение проблем со скоростью прорисовки 14 Разрешение лайтмэпов 15 Примеры карт с использованием описанных технологий
Листья
Откомпилированная
карта поделена на секции, называемые листьями(leaf или visleaf). Каждый
лист - это часть карты, содержащая некоторое количество геометрии в
себе, и если из текущего листа будет видна любая часть другого листа,
то вся его геометрия тоже будет прорисована (просчитана) движком игры.
Вы можете просмотреть эти самые листья, набрав в консоли "mat_leafvis
1”. Красный каркас - это то, что прорисовывается в данный момент.
Другой способ просмотра листьев - использование инструмента glview.
Glview
Чтобы использовать glview, напишите в командной строке (или bat-файле) "%sourcesdk%\bin\vbsp -glview .gl"
и glview покажет все листья на карте (саму карту он прорисовывать,
конечно же, не будет). Теперь используйте клавиши W, S, A, D для
перемещения и просмотра карты.
Hint-браши
Хинт-браши
- это невидимые в игре браши, с помощью которых вручную создаётся
деление листьев. Хинты как бы "подсказывают" (hint - подсказка), как
карта должна быть поделена на листья.
Хинт-браш - это один браш
покрытый материалом tools\\toolshint с одной или более сторон,
остальные стороны должны быть покрыты материалом tools\\toolsskip.
Сторона/стороны с материалом toolshint будут использоваться в качестве
секущих плоскостей, вдоль которых и будут проходить границы листьев.
Система хинт-брашей может использоваться в синглплеерной карте, и они
могут даже пересекаться.
Правильное использование этих брашей на
больших, открытых картах может значительно повлиять на время
компиляции. Большое количество листьев с множеством детализированных
объектов в них увеличат время их обработки компиляторами. Используйте
хинты для отделения больших секций с малым количеством деталей от зон с
высоким уровнем детализации. Примером может быть каньон: размещение
хинт-браша посередине карты создаст один большой пустой лист - небо и
отделит его от листа со всеми деталями - каньон.
Посмотрите карту sourcesdk_content\hl2\mapsrc\sdk_hints.vmf, чтобы увидеть пример размещения хинтов.
Ареапорталы
Ареапортал
- это браш-энтитя - func_areaportal, которая используется для
"запечатывания" (изолирования) листьев друг от друга и контроля
видимости. Ареапорталы похожи на дверные проемы, которые могут быть или
открыты или закрыты. Когда ареапортал закрыт, он блокирует обзор
геометрии за собой, когда же он открыт, то все, что за ним, становится
видимым. Они могут динамически открываться и закрываться во время игры,
обычно это делается через систему I/O (input/output), например, с
помощью trigger_multiple.
В некоторой степени не интуитивно в
ареапорталах то, что они состоят не из одной поверхности, а из
нескольких (так как это все-таки браш-энтитя, и у нее несколько
сторон), и, несмотря на то, что ареапорталы могут быть любых размеров,
многим хочется сделать их как можно тоньше (шириной в 1 юнит). Не
забудьте каждую его сторону покрыть текстурой tools\toolsareaportal.
Вам также следует не забывать, что ареапортал должен быть окружен
простыми брашами, а не detail-брашами, также не подойдут и
displacement-браши: это общая ошибка в левел-дизайне - не закрывать
полностью листья. В этом случае vbsp автоматически находит "утечку"
(leak) в ареапорталах, вам лишь нужно загрузить поинтфайл (load the
pointfile) в Хаммер, сгенерированный vbsp, и вы все увидите: красная
линия протянется прямиком к этой самой утечке. Для большей информации
об утечках вы можете прочитать в статье Leaks Explained.
Ареапорталы
также могут использоваться во всегда открытом состоянии (always-open
state), которое включается в настройках энтити, а именно - "Initial
State". Ареапорталы (открыты ли они постоянно или через триггеры)
работают в режиме избирательной геометрии: только те листья, которые
напрямую видны из окна, будут рендериться (просчитываться) движком.
Таким образом, наружная геометрия будет грубо отобрана под размер окна,
тем самым, уменьшая количество обрабатваемых объектов и увеличивая
производительность. Вследствие этого всегда открытые ареапорталы
используют в дверных проемах, ведущих в большие открытые пространства.
Например, всегда открытый ареапортал в конце коридора, ведущего в
широкую долину, может существенно повысить производительность игры. В
этих случаях часто используется энтитя func_areaportalwindow. Эта
энтитя - разновидность ареапортала, которая открывается/закрывается не
от триггеров, а в зависимости от расстояния, на котором от нее
находится игрок.
Несмотря на то, что арепорталы могут
значительно повысить производительность игры, не ставьте их слишком
много в тех местах, где они будут видны все сразу - слишком большая
нагрузка ляжет на плечи процессора, так как нужно будет обрабатывать
одновременно функции нескольких ареапорталов. В таких случаях в
некоторых местах разумнее будет вообще не ставить ареапорталы.
Еще
одна вещь, о которой вы бы никогда не догадались: ареапорталы никогда
не должны пересекать водную поверхность. В этом случае вам придется
размещать два ареапортала: один над водой, другой - под, а встречаться
они будут в месте касания водной поверхности. Но можно сделать и
наоборот: создать один ареапортал и разрезать его в месте пересечения с
водой (главное не забыть обе части превратить в ареапорталы).
Окклудеры
Окклудеры
похожи на ареапорталы тем, что они тоже браш-энтити, контролирующие
видимость геометрии за собой. А различаются они вот чем: a) окклудеры
скрывают только модельную геометрию, а браш-геометрию - нет b)
окклудеры в отличие от арепорталов не должны отделять листья друг от
друга - они могут находиться в любом месте на карте. Так же, как и
ареапорталы, окклудеры могут динамически активироваться во время игры.
Окклудеры
- это браш-энтити func_occluder, имеющие текстуру tools\toolsoccluder
на тех сторонах, которые должны блокировать видимость, и текстуру
tools\toolsnodraw на всех остальных сторонах. Наложение текстуры
toolsoccluder на ненужные стороны приведет к понижению
производительности окклудеров.
Еще одно предостережение:
чрезмерное использование окклудеров также понижает производительность.
Каждый окклудер должен скрывать достаточно геометрии на карте: если он
скрывает более чем несколько сложных моделей, то его использование
оправдано - иначе окклудеры будут тратить на себя больше ресурсов, чем
та геометрия, которую они скрывают. Для определения оправданности
использования окклудеров используйте консольную команду bindtoggle в
сочетании с командой r_occlusion, которая включает-выключает
использование системы окклудеров (например, напишите в консоли
"bindtoggle o r_occlusion"). Естественно, не забудьте в это время
проверить количество fps, набрав в консоли "cl_showfps 2".
Для примера использования окклудеров можете посмотреть карту sourcesdk_content\hl2\mapsrc\sdk_occluder.vmf.
Техника создания геометрии
Правильная
техника создания браш-геометрии также может дать ощутимый прирост в
производительности. Основная задача при создании эффективной геометрии
в Хаммере - создавать как можно меньше "разрывов" полигонов.
Эффективный способ здесь - использование 2D сетки для выравнивания
объектов, когда это возможно. Дополнительные разрезы создаются, когда
геометрия плохо выровнена или вообще не выравнивалась, тогда vbsp
приходится разрезать поверхности для правильного рендеринга. Если же
геометрия выровнена по сетке, то количество разрезов уменьшится. Также
старайтесь уменьшить количество брашей, повернутых на определенный угол.
Также
следует заметить, что vbsp автоматически режет геометрию через каждые
1024 юнита относительно абсолютных координат, поэтому дополнительные
разрезы могут быть предотвращены, если браши будут иметь границы на
этих линиях. Для этого в Хаммере откройте меню
Options>Tools>вкладка 2D Views и выберите "Highlight every 1024
units”. Enabling this will display DeepSkyBlue shaded grid lines in
1024 increments in the Hammer 2D views. Это вовсе не означает, что всю
карту нужно переделывать под эти линии, но некоторые вещи теперь можно
делать, учитывая эти сведения, например, неигровые объекты.
Detail-браши
Detail-браши
- это такие браши, которые сгруппированы и созданы во избежание
ненужных разрезов, когда они соприкасаются с большими поверхностями.
Detail-браши - это браш-энтити func_detail. Они, в отличие от простых
брашей, не разрезают браши, с которыми соприкасаются. Примером может
послужить колонна на полу - будучи обычным брашем, она, соприкасаясь с
полом, разбивает его на большое количество фейсов:
Если же превратить ее в detail-браш, то никакого разбиения не произойдет:
Также повернутые браши являются отличными кандидатами для превращения в detail-браши.
Detail-браши
не блокируют видимость и не могут запечатывать листья, как ареапорталы,
поэтому же они упрощают процесс создания видимости. Правильное
использование detail-брашей может прямо-таки колоссально уменьшить
процесс компиляции vvis`ом.
Конечно detail-браши - это энтити,
но только когда они в Хаммере: после обработки vbsp`ом вся их
энтити-информация отбрасывается для экономии памяти, занимаемой
геометрией, так как она больше не нужна vbsp после уменьшения
количества разрезов. В самом же движке игры стороны detail-брашей
обрабатываются так же, как и стороны обычных брашей.
Detail-брашами
следует делать маленькие или комплексные объекты, например, столбы,
ворота, маленькие скалы, ограда, осколки, пирсы, волнорезы и т.п. Чтобы
определить, превращать или нет объекты в detail-браши, просто
посмотрите в glview те места, где очень высокая плотность фейсов, и
причину превратите в detail.
Для примера использования detail-брашей можете посмотреть карту sourcesdk_content\hl2\mapsrc\sdk_func_detail.vmf.
Вода
Здесь
есть пара трюков по увеличению производительности. Вода - очень
ресурсоемкий шейдер, и вам часто придется сталкиваться с ограничением
скорости прорисовки (fillrate). Это можно увидеть, набрав в консоли
"+showbudget" и посмотрев графу Swap Buffers - если значение очень
высоко, то вы столкнулись с этой проблемой. Для ее избежания вам
придется обрезать водный браш так, чтобы пересекался с как можно
меньшим количеством других брашей или дисплейсементов (displacements).
Еще
одна проблема с производительностью - когда какой-нибудь объект
частично под водой и частично над ней, он рендериться дважды: под водой
и над ней. Чтобы увидеть, какие объекты рендерятся через воду, напишите
в консоли "mat_showwatertextures 1". Также, набрав "mat_wireframe 1",
вы сможете увидеть проблемные участки. Попробуйте убрать из воды все
prop_static и отрезать водные браши так, чтобы они пересекали как можно
меньшее количество моделей.
Модельная геометрия против брашевой
В
основном, браши составляют большую часть карты и используются для
создания ландшафта и больших и грубых зданий. Браши блокируют видимость
всего, что за ними, поэтому они используются для создания стен,
ландшафта и склонов гор и холмов (или других объектов, закрывающих
большую часть экрана). Большие объекты, такие как мост, лучше делать
брашами с лайтмэпами (lightmaps), чем одной большой моделью.
Плохой
стороной в использования брашей является то, что они требуют больше
памяти, чем пропы (props), всегда прорисовываются и разрезают BSP,
уменьшая быстродействие. Также они не могут быть объединены в иерархии,
как пропы.
Браши следует использовать для следующих объектов: Ландшафт Склоны холмов/естественные (природные) стены
Стены Основания зданий (используйте пропы для их декорации, например, окна и проч.) Большие конструкции, как мосты, где важны аккуратность освещения и блокирование видимости Объекты, которые будут иметь ограниченное использование на карте - производительность уменьшается с каждым брашем.
Модельная
геометрия (создающаяся в таких программах, как Softimage|XSI) должны
использоваться вместо брашей везде, где это возможно. Модельная
геометрия, по-другому пропы ("props”), рендерится быстрее вследствие
пакетных способностей движка. Также они требуют меньше системных
ресурсов и имеют выгоду из сложных уровней деталей, так как уменьшается
количество рендерещяйся геометрии. Модели могут состоять из любого
набора треугольников, поэтому они имеют меньшие ограничения в форме.
Левел-дизайнеры могут использовать любое количество моделей для
заполнения игрового пространства.
Модельная геометрия не
блокирует видимость и не может использоваться для запечатывания
листьев. Кроме того, несмотря на то, что модели могут отбрасывать тень,
они не используют лайтмэпы для этого, как браши, они используют более
простое вертексное освещение для увеличения скорости.
Моделями
следует делать такие объекты, которые не запечатывают листья, и
маленькие или комплексные предметы. Например, мебель, лампы, мусор,
какое-либо оборудование, трубы, транспортные средства, канавы и т.п.
Модели используются для таких объектов: Маленькие объекты (консервные банки, мебель, компьюьтерное оборудование, двери), Объекты,
больше, чем того требует уровень деталей - разместите внутри больших
пропов браши, такой же формы, но меньших размеров, чтобы их не было
видно, Все, что должно имитировать физику (поднято, брошено, ударено и т.д.), Не вступающая в контакт органика, например, растительность (трава, саженцы), Объекты, которые появляются много раз на карте.
Посмотрите статью Overview of Prop Types для объяснения разницы в типах пропов.
Дальность видимости геометрии
Пропы
имеют минимальную и максимальную дальности исчезновения, которые могут
быть настроены в их энтити-свойствах. Это позволяет левел-дизайнерам
указывать дистанцию относительно игрока, после которой модели начнут
исчезать, таким образом увеличивая производительность. На компьютерах с
DirectX 7 пропы будут исчезать раньше для увеличения быстродействия
игры. Это можно проконтролировать с помощью файла dxsupport.cfg в
директории вашего мода или с помощью консольных команд "cl_detaildist"
и "cl_detailfade".
Разрез и затуманивание
Использование
разрезания по расстоянию может уменьшить количество видимых объектов и
увеличить скорость рендеринга. Также для этого нужен будет туман, чтобы
карта просто так не исчезала. Установить и контролировать туман и
разрезание вы можете при помощи размещения на карте энтити
env_fog_controller.
Выбор материала и скорость рендеринга
Работая
с материалами, вам следует помнить, что здесь есть два узких места:
скорость прорисовки (которая обычно касается всех версий DirectX) и
сокращение обработки вертексов (это касается только DirectX7). Как
левел-дизайнеру, вам предстоит выбрать, как бороться с этой проблемой:
или уменьшить количество "затратных" материалов в поле зрения игрока,
или отключить некоторые ресурсоемкие эффекты в материалах (такие, как
бамп). Заметьте, что вы можете выбрать различные способы решения для
каждого уровня DirectX.
Еще одним узким местом является то,
что вам придется следить за количеством fps на вашей карте, чтобы
определить, насколько хорошо у вас все получилось. Для Half-Life 2 мы
использовали три машины для измерения производительности, необходимой
для различных уровней DirectX. Вот, что получилось:
Уровень DX (DirectX)
Минимальные требования
DX9 - ATI 9800, 1 GB, P4 3.0 GHz
DX8 - NVidia GeForce4 Ti4600, 512 MB, P4 2.0 GHz
DX7 - NVidia GeForce2 MX, 256MB, P4 1.2 GHz
Как
вы успели заметить, здесь есть различные параметры материалов для
различных уровней поддержки DirectX: каждый шейдер имеет специальный
"аварийный" (fallback) шейдер, которым он заменяется, если
обнаруживается, что он не может быть использован в определенной версии
DirectX, на которой работает данная видеокарта. Для этого вам в
свойствах вашего материала нужно будет добавить некоторые поля,
определяющие какие аварийные шейдеры где использовать. Список самых
распространенных из них приведен ниже. Вот пример:
"LightmappedGeneric"
{
"$basetexture" "Metal/metalwall063a"
"$surfaceprop" "metal"
"$envmap" "env_cubemap"
"LightmappedGeneric_DX9"
{
"$bumpmap" "metal/metalwall063a_normal"
"$normalmapalphaenvmapmask" 1
}
"LightmappedGeneric_DX8"
{
"$basetexture" "metal/citadel_metalwall063a"
"$basealphaenvmapmask" 1
}
"LightmappedGeneric_DX6"
{
"$fallbackmaterial" "metal/metalwall063b"
}
}
В
этом примере поле $envmap используются во всех случаях, не смотря на
версию DirectX. В поле $basetexture значение "metal/metalwall063a"
используется для каждого аварийного шейдера кроме
LightmappedGeneric_dx8 (использующегося в DX8), который использует
"metal/citadel_metalwall063a" для $basetexture. Также только для
DirectX 8 мы добавили поле, в котором указали, что его специальная
текстура (metal/citadel_metalwall063a) имеет свою собственную envmap
маску в своем альфа-канале. Когда же мы описывали
"LightmappedGeneric_DX9" шейдер (естественно, использующийся для
DirectX9), мы добавили бамп (bumpmap) и указали, что envmap маска
находится в альфа-канале бампа. Заметьте, что также возможно заставить
систему материалов использовать совершенно другой материал с уже
другими настройками в нем, указав его в строке $fallbackmaterial, что и
было сделано в описании свойств материала для DirectX6 (в поле
"LightmappedGeneric_DX6", которое будет применено для DX7 и DX6).
Если
вы ничего не поняли (что очень возможно при моем переводе=)) или хотите
больше узнать об "аварийных шейдерах", то посмотрите эту статью
Half-Life 2 Shader Fallbacks.
Решаем проблемы со скоростью прорисовки
Самыми
ресурсоемкими материалами в Сорсе являются водные и преломляющие
(refract) шейдеры, а также любой материал, использующий бамп. Как
говорилось выше, узнать о том, что у вас проблемы со скоростью
прорисовки (fillrate), вы можете, набрав в консоли +showbudget и увидев
сильно забитую шкалу Swap Buffers. Мы с вами поговорим о самых частых
"обидчиках" скорости прорисовки: преломляющих, водных и бамп шейдерах.
Единственное,
что вы можете сделать для преломляющих шейдеров, это использовать
$fallbackmaterial, чтобы сделать шейдер не преломляющим для тех версий
DirectX, на которых искажение/преломление становится проблемным. Водные
шейдеры: здесь проблемы со скоростью прорисовки связаны с
использованием отражений и преломлений. Вы можете отключить их обоих,
написав $forcecheap 1 в vmt-файле вашего водного материала. Вы также
можете отключить их по одному, не указав либо $refracttexture
(преломление), либо $reflecttexture (отражение) в vmt-файле. Если же
вам наплевать на производительность, вы можете принудительно сделать
вашу воду локальные отражения (не обращая внимания на настройки видео),
написав $forceexpensive 1, и заставить воду отражать еще и энтити,
написав в vmt-файле $reflectentities 1.
Теперь о бампе. Обычно
"слабым звеном" здесь является LightmappedGeneric, и имеется несколько
способов увеличения производительности. Написав в vmt-файле
$nodiffusebumplighting 1, вы выключите рассеивающий бамп, но отражающий
бамп останется. Его выключение также увеличит производительность, и
производится оно при помощи замены LightmappedGeneric на
LightmappedGeneric_NoBump_dx8. Это аварийное выражение автоматически
используется на DirectX8-компьютерах, определенных, как
mat_DeepSkyBlueucefillrate 1, в файле dxsupport.cfg. В некоторых
материалах в Цитадели (ХЛ2) мы использовали этот метод, чтобы позволить
себе установку бампа для DirectX9 и DirectX8, но не для более ранних
версий с меньшей скоростью прорисовки.
В картах low-end класса
(DX7) также отключены бамп-отраженияе из расчета скорости прорисовки и
обработки вертексов. Как результат, по умолчанию зеркальность отключена
на DirectX7-картах. Чтобы активировать отражения для этих материалов в
DirectX7, вам нужно добавить строку $multipass 1 в ваш vmt-файл.
Шейдеры LightmappedGeneric_dx6, VertexLitGeneric_dx6,
VertexLitGeneric_dx7 и UnlitGeneric_dx6 полностью зависят от этого
параметра.
Разрешение лайтмэпов
Движок Сорс (Source)
использует лайтмэпы (lightmap) для имитации света и тени на
браш-геометрии. Чем больше разрешение лайтмэпов, тем больше точность
наложения теней, и тем больше становятся требования к оперативной
памяти. Соответственно уменьшение разрешения ведет к увеличению
производительности игры.
Скейл (scale) лайтмэпов изменяется в
панели Texture Application, измеряется оно в люкселях (luxels) на один
юнит. Чем меньше значение, тем меньше разрешение, по умолчанию для всех
материалов устанавливается скейл, равный 16 люкселям.
Большее
разрешение увеличивает время, используемое VRAD`ом на обработку карты.
Ускорить работы VRAD`а и уменьшить требования к памяти вы можете,
уменьшив разрешение лайтмэпов фейсов, не нуждающихся в хорошей
детализации теней. Такими фейсами могут быть фейсы, полностью
находящиеся в тени, или полностью освещенные (без теней на них), или
находящиеся на далеком расстоянии от игрока, где он не сможет их
увидеть..
Посмотрите статью Texture Application для получения большей информации.
Для примера правильного использования лайтмэпов посмотрите карту sourcesdk_content\hl2\mapsrc\sdk_lightmaps.vmf.
Примеры карт с использоанием описанных технологий
sourcesdk_content\hl2\mapsrc\sdk_func_detail.vmf
sourcesdk_content\hl2\mapsrc\sdk_hints.vmf
sourcesdk_content\hl2\mapsrc\sdk_occluders.vmf
sourcesdk_content\hl2\mapsrc\sdk_prop_types.vmf
sourcesdk_content\hl2\mapsrc\sdk_lightmaps.vmf
Взято с http://collective.valve-erc.com/
|