Террейн – базовые фичи и проблемы
Прежде всего, даже беглый взгляд на vterrain.org показывает, как страшно далеки их проблемы от народа.
У народа совсем более другие проблемы. Особенно у того народа, который делает не авиасимы со спутниковой картой, а что-то более другое.
Итак, в игре должен быть террейн. На нем должен стоять и бегать персонаж, на террейн надобно ставить домики и деревца, красить его надо по-разному, гнуть, вырезать в террейне дырки под пещеры.
Как поступает грамотный пацан? Грамотный пацан выносит проблемы из своего scope. Поэтому у грамотных пацанов редактирование террейна происходит в CAD-CAM тулах ( которые будут именоваться далее кратко - ”майка” ). Грамотные художники режут геометрию на куски и потом хреначат по ней vertex paint ( не более 4 весов на вертекс, максимум пять текстур ). У совсем достигших просветления пацанов даже preview нету в майке, потому что дизайнеры и так кабаны. И LOD тоже нету, ибо и так быстро работает, а сабпиксельные треугольники Edge отбросит. Задача переделывать карту, переразбивать и перекрашивать тоже очевидно не стоит. А если стоит, то дизайнер выполнит ее с закрытыми глазами, на области в 100 квадратных километров игровой карты. Проблемы у грамотных пацанов настолько суровы, что хомячка разрывают на куски…
Рассказывать я буду про другой случай, про случай самописного редактора. Игра, повторюсь, в стиле WoW, состоит из сотни квадратных километров террейна. Для которого пишется собственный редактор. Базовое требование очень простое – берет художник кисточку из палитры инструментов. И красит ей с шагом 0.5 – 1.0 метр террейн какой-то текстурой, или выгибает сетку высот. Над этим может быть построен более высокоуроневый редакторский функционал, скажем, берет дизайнер, огораживает poly-line область на карте, говорит: “сгенери мне тут гору!” Гордо вздымается фрактальная херня, красится в зависимости от высот, градиента высот и фазы луны разными текстурами.
Над картами работают дизайнеры, параллельно. Карты заливаются внешними аутсорсерами во внешний SVN, происходит их приемка, конвертация скриптами, разные билдеры по ночам карты обрабатывают ( билдер лайтмапов, билдер серверных данных для pathfinding ). Поэтому идея “у нас будет двухгигабайтный блоб для террейна” сразу идет нафиг. Карты режутся маленькими кусочками, по 256×256 метров каждый. Это единица загрузки и единица гранулярности на диске. Редактор грузит сразу маску 4×4 ( ровно 1024 x 1024 метров с шагом 256 метров ) и там как-то живет.
Исходно единица рендеринга – патч террейна размером 32×32 метра. Дизайнер провел кисточкой – в карту сплаттинга добавился слой террейна. Информация о слоях террейна в точке задается примерно вот такой структуркой:
[code]
struct TerraInfo { uint8 weghts[4]; uint8 indices[4]; };
[/code]
В каждой точке максимум 4 слоя, слой с меньшей интенсивностью вытесняется при редактировании, веса нормализуются. Тут все просто. Проблема состоит в том, что на куске 32×32 метра совокупное число текстур таким образом не лимитировано. Каков бы ни был предел N ( который кажется нам разумным ), дизайнер умудрится провести кисточкой N + 1 раз с разными текстурами. И превед – черные пятна. Я долго мучался, в голове крутилось: “И тут надо вытеснять слой с меньшим совокупным весом, по всему тайлу 32×32 метра”. Крутилось-крутилось, да я что-то не реализовывал. Потом реализовал и был чуть ли не расцелован угрюмыми обычно дизайнерами карт. Слои вытеснялись красиво, артистично. Никаких ровных полосок по стыкам больших тайлов почему-то не наблюдалось. И внезапно оказалось, что дизайнерам и надо, чтобы удалялись лишние слои. Ибо, находясь в творческом поиске, перерабатывая карту по несколько раз, они рисовали рандомные текстуры. Которые лучше бы исчезали в процессе работы с карты, а не светились мелкими чужеродными пятнами. Это была победа в 10 строк кода – сами понимаете, что и в рендере 4 слоя лучше, чем 24.
Теперь про рендер. Писал я не заморачиваясь, год-полтора назад. Чтобы работало, на коленке. У дизайнеров были очень простые желания, оттуда рождались пины шейдерной системы.
Пин 0.) Слои террейна. До 4 слоев ( все что больше – накладывается аддитивно ), веса в текстурке ( 32×32, per patch терейна ).
Пин 1.) Морфинг. Тут все просто. Геоморфинг, кольца детализации, юниформный грид.
Пин 2.) Устранение потяжек на вертикальных склонах. Текстурирование в зависимости от xyz компонент нормали, веса увожу в 0 при угле наклона нормали меньше 45 градусов. В результате те куски террейна, где есть вершина с normal.z < 0.71, рисуются специальным шейдером с тройным чтением текстуры, по .xy, .yz, .zx.
Пин 3.) Мегафича. Два слоя террейна, в пиксельном шейдере есть if( height0 – height1 < 0.0f ){ discard; }. Красивые получаются такие обрывы и острова, ни у кого такого нет. В рендере, на уровне кусков 32×32 метра – опять пин. Забавным образом работает с морфингом и не видно мерцающих пикселей. Почему – сам не знаю.
Был такой замечательный редакторский террейн, предназначенный для быстрой модификации, были у него проблемы. Очень простые:
0.) Общая заточенность на рантайм-изменения. Множественные уступки перфомансу.
1.) Юниформный грид, излишняя плотность треугольников на плоских кусках.
2.) LOD шейдер, который тянет тяжелый FVF. И меняется очень часто.
3.) Гранулярность куска в 32×32 метра форсирует излишне тяжелые шейдеры. Один маленький бугорок форсирует тройное чтение из текстуры, одно пятнышко текстуры форсирует лишний слой во всем куске.
Самая злая проблема конечно последняя. Попытаться решить ее уменьшением рендер-куска неразумно. DIPs взлетят к небесам. Думал я думал, как победить. И решился. Сидел неделю, усиленно фигачил код, словно мне 20 лет, а не 30. И написал Новый Прекрасный Террейн. Форк для статической релизной ROAM-like версии террейна, которая заботливо строится по ночам билдером.
Напишу пожалуй на блоге скоро.
Pingback: highly professional scums » Blog Archive » Ландшафтный дизайн, часть два.()