Текстурные декали на ландшафте (демо) (10.07.2009)
WSAD - управление камерой
QE - камера вверх/вниз
Пробел - показать/скрыть decal map
1 - включить/выключить анимацию декалей
1) Программа не выключает vsync, нужно делать это в дровах
2) Мерять FPS надо Fraps'ом
3) Программа требует поддержки OpenGL 3.0
-----
Как лучше их делать?
Я так понимаю декали можно разделить на три типа:
1) Статические дизайн-тайм - дизайнер на ландшафте понатыкал декалей в редакторе
2) Редко обновляемые - чтото взорвалось и на ландшафте чёрное "пятно", будет висеть долго, по какой причине может пропасть тут уже от фантазии зависит: количество декалей больше чем X, прошло время определённое и т.п...
3) Динамические - например курсор на ландшафте, обводка у юнитов в РТСе в виде кружочка, такие декалии могут обновляться каждый кадр, мигают, шевеляца, анимируются по всякому...
Меня мало интересует 1, больше интересуют реализации 2 и 3...
Не давно баловался новым Company of Heroes - Tales of Valor, там понравились как обводки вокруг солдат сделаны (они в более ранних также, если мне память не изменяет, давно играл)... Вот например:

Как видно вокруг солдатиков кружочки, эти кружочки не пересекаются, темболее кружочки ровные симпатяшные... Вот как это сделано?
Пока все мои потуги, в этой области, вылились в следующие мысли, которые я реализовал:
1) Берётся текстура для декалей размером (dw, dh)...
2) Очищается текстура
3) Рендерится в текстуру квад с текстурой, в матрице задаётся позиция и скейл для этого квада, чтобы спозиционировать его куда надо...
4) Повторяется для каждого декаля пункт 3... Они там блендятся или както ещё накладываются друг на друга, не суть, дело фантазии...
5) Потом получившаяся текстура используется при рендеринге ландшафта, тупо натягивается на весь ландшафт, в шейдере тоже от фантазии зависит как она с дифузной текстурой будет "дружить"... Я пока тупо сложил их...
Соответственно для редко обновляемых одна текстура, для часто обновляемых другая... Это чтобы редко обновляемые заного не перерендеривать каждый кадр... Соответственно ландшафт рендерится один раз, в нём используется базовая текстура (диффуз) + статик декал + динамик декал... Ну по вкусу там нормал мапы, спекуляр мапы и прочее, это не важно... Я реализовал пока одну текстуру для декалей, так как разницы особой в них обоих нет, просто разная частота обновления...
Вообщемто минус в этом всём один, декаль (крестик, кружочек, что угодно) у меня может быть к примеру 1024х1024, ровненькая красивенькая, а в текстуре для декалей (которая на весь ландшафт) оно будет выглядить хуже - зависит от размерности этой большой текстуры, можно конечно сделать эту текстуру гигантской 4096х4096, но както не тру помоему... Вот для примера:
dw = dh = 128:

dw = dh = 1024:

Оно вообщемто терпимо, но если начать увеличивать ландшафт (сейчас у меня 512х512), то понадобится текстура для декалей больших размеров, чтобы было сапостовимого качество...
Отсюда вопрос, как в РТСах (думаю игры этого жанра намного чаще делают то, что меня интересует) всяких всё это делается?
Executor
Вообще, классический метод построения декалей - это дублирование геометрии
в месте наложения декали и проекционное наложение текстуры на эту отдублированную
геометрию.
Я у себя использую такой алгоритм:
1.) В месте, где нужно положить декаль, строю ограничивающий объём (у меня сфера, радиус задаёт
размер декали).
2.) Ищу полигоны сцены, с которыми пересекается ограничивающий объём.
3.) Копирую эти птолигоны в структуру декали.
4.) Далее в пиксельном шейдере отсекаю фрагменты, выходящие за радиус сферы
и расчитываю проективные текстурные координаты на основе базиса, вычисленного
на основе средней нормали всех полигонов декали. Ну и накладываю текстуру.
Ну естественно, что Z-Bias нужно сделать для отрисовки декалей (glPolygonOffset).
И выключить Z-Write. Ну и альфа-блендинг настроить.
P.S: а рендеринг декалей в текстуру обычно используют только для анимированных
персонажей (например в Doom3 так сделано).
И сколько декалей таким образом у тебя? Насколько часто обновляются? Какая производительность получается? Просто я вот представляю хотя бы 10 юнитов движутся, это почти каждый кадр надо будет 10 кусков геометрии перестраивать, помоему жирно както, нет?
Executor
>> И сколько декалей таким образом у тебя? Насколько часто обновляются?
У меня декали появляются от выстрелов - следы от пуль (маленькие декальки)
и от взрывов (большие тёмные пятна). У каждого типа декали у меня введено
время жизни.. Через определённый период времени они плавно гаснут и затем
удаляются из списка..
>> Какая производительность получается?
В общем неплохая, особых тормозов не наблюдаю.. Это при том, что отсечение
их происходит в лоб по фрустуму без всяких иерархий.. Оптимизацией пока в
этом плане не занимался..
Executor
>> это почти каждый кадр надо будет 10 кусков геометрии перестраивать
То есть тебе нужны декали от перемещающихся по ландшафту объектов?
Если да - то если функция нахождения пересечения ограничивающего
объёма с ландшафтом работает быстро (использует иерархичное разбиение)
- то должно работать всё быстро...
Ещё тут давно на сайте предлагали как-то накладывать декали в пост-процессе на
основе глубины и восстановлению по ней позиции, но я точно не помню всех
аспектов этого метода, но главная суть также в проецировании текстуры...
DEN 3D
Хорошо, спасибо... Послушаем, что ещё скажут... :)
> То есть тебе нужны декали от перемещающихся по ландшафту объектов?
Да... Обводка вокруг выделенного юнита к примеру, который движется... Вот выделил армию в 10-20-30 юнитов и кудато их послал, они по ландшафту двигаются соответственно вокруг каждого кружочек/квадратик/ромбик какойнить мигает/вертится...
Executor
>Вот выделил армию в 10-20-30 юнитов и кудато их послал, они по ландшафту
>двигаются соответственно вокруг каждого кружочек/квадратик/ромбик какойнить мигает/вертится...
А зачем вообще кружочек проецировать? Можно сначала отрисовать сцену, потом просто под юнитом квад со спрайтом кружочка и отключёным Z-тестом, потом отрисовать сами юниты. Чем такой вариант не устраивает?
XIRMAC
Проективные декальки круче смотряца.
XIRMAC
> А зачем вообще кружочек проецировать? Можно сначала отрисовать сцену, потом
> просто под юнитом квад со спрайтом кружочка и отключёным Z-тестом, потом
> отрисовать сами юниты. Чем такой вариант не устраивает?
Будем не очень красиво, если этот кружочек не будет повторять рельеф ландшафта...
З.Ы. Обновил скрин из КОХ в нулевом посте...
Altair
Имхо не круче. Но вообще если так хочется можно отрендить их сначала в отдельную текстурку а потом за один проход наложить на ландшафт. Отдельной геометрией делать выделение для 200+ юнитов - это жир.
В нолевом посту, в картинке из игры "компания героев"..
Слишком подозрительно пересекается маленький камень с "декалью обруча". (слева солдатик).
Возможно, там некий вариант "нашлёпки", вместо "врисовки в землю".
Придумал как можно улучшить качество того, что я описал в посте 0... Если на экране видно только маленький кусочек ландшафта, то эту вот большую текстуру для декалей полностью отдавать вот под этот небольшой видимый кусочек, а не под весь ландшафт, по мере отдаления от ландшафта соответственно в эту текстуру будет больше влазить, и соответственно снижаться качество, но для дальнего обзора это не критично... На 1024х1024 карте для декалей, вполне нормально выглядит даже с такого близкомо расстояния, как на скрине из поста 0... Но пока не пробывал это реализовать... :)
На мой взгляд это разные сущности, с разными требованиями по производительности - первый - динамический текстурный проектор, им можно тени делать или видео играть, а второй декали, на который, к примеру спроецированы брызги крови. первый - штучные экземпляры, второй сотни на сцене. Да, алгоритмы у них внешне похожи, но как дело доходит до конкретики, все доводится под свои задачи.
какой еще рендеринг в текстуру? в играх круги выбора делаются отдельной моделью, просто высчитываются в зависимости от рельефа, разбиваются и рендерятся чуть выше ландшавта
1вот например в варкрафте3
сверху выглядит норомально, а если сбоку видно что под кругом выбора видно область что лежит дальше, т.е. круг выбора находится на маленькой высоте над рельефом
http://keep4u.ru/full/2009/06/26/56968cf2ace40dd325e285f9b08966bd/jpg
http://keep4u.ru/full/2009/06/26/97096189e564ccb6e19518e53aee65a0/jpg
Тема в архиве.