пятница, 4 февраля 2011 г.

Как ковалось железо, или "параллакс меппинг и использование изнутри".

В предыдущем посте я рассказал и показал пример parallax oclusssion mapping. Как это используется в реальности, что там происходит... Короче, для интересующихся расскажу как добиваюсь эффекта по шагам.

Шаг1:
В рендертаргет (в примере равный размеру окна) рендерится диффузная карта местности.

Шаг2:
В тот же рендертаргет через multiply рендерятся "тени" от объектов. Пока они плоские, также как и сама карта диффуза, но она исказится чуть позже.
Шаг3:
Во второй рендертаргет рендерится карта высот для всего ландшафта.
Шаг4:
В третий рендертаргет рендерится карта нормалей для всего ландшафта.
  
Шаг5:
Тут начинается все самое интересное. Сразу забыл оговориться, что три рендертаргета используемых в предыдущих шагах это три текстуры в трех разных стейтах и ипользуются они одновременно.
Эти три текстуры прогоняются через шейдер (о нём позже), который создает эффект "вдавливания" текстуры. Но так как в особо сильно вдавленных местах информация о текстуре заканчивается, мы получаем неприятные артефакты вокруг результата, в зависимости от степени вдавленности (в нашем случае максимальное вдавливание равно 128 пикселям). К сожалению, избавиться от эффекта невозможно, однако можно немножко считерить. 
Вариантов решения проблемы два. Первый — научить шейдер не вдавливать текстуру, а выдавливать. Второй — затекстурировать полигон так, чтобы текстурные координаты были не 0,0 - 1,1, а что-то вроде 0.1,0.1 - 0.9,0.9 или же просто увеличить полигон за пределы экрана в каждую сторону на 128 пикселей. Я избрал метод вдавливания так как при вдавленном методе не искажаются самые высокие участки, которые больше всего и видны игроку. Поэтому использовал второй метод решения проблемы.
Собственно что получится без коррекции  при попытки "вдавить":
 Когда текстурные координаты поправлены и артефактов нет, получаем то, что хотели, но чуточку побольше размером. А так как мы в диффузный рендертаргет нарисовали и тени — получаем еще и тени, причем с учетом искажения по рельефу:
Шаг 6:
Осталось дорисовать сами объекты поверх ландшафта, делая это привычным методом. Тут уже никаких секретов нет.

Шейдер:
Шейдер заслуживает отдельной статьи так как достаточно объемен. Сначала в программе высчитывается TBN для вершин (в quad-engine делается автоматом), далее TBN, матрица проекции и позиция источника света передаются в вершинный шейдер. Вершинный шейдер переводит все полученные параметры в тангент-спейс полигона и дальнейшая работа уже идет с ним. На выхлопе для каждого пикселя вектор света и вектор вида.
Пиксельный шейдер. Из карты высот берется значение высоты и учитывая вектор вида в данной точке ищется пересечение луча вида с плоскостью с учетом поправки на высоту (взятую из карты высот). Далее идет 8 итераций на корректировку текстурных координат, точнее на поиск более близкого значения к желаемому. После нахождения производится ленейная интерполяция в пределах 1\8 глубины (для этого и делается 8 проходов). Таким образом получается достаточно точное значение, которое и берется как реальные текстурные координаты. Пиксель из этих текстурных координат уже и выводится. Также по этим текстурным координатам берется вектор из карты нормалей и производится затенение картинки, согласно расположению источника света (в примере ровно по центру экрана). Добавляется спекуляр и эмбиент по вкусу и результат готов.

Подробно с кодом почитать о Parallax mapping можно вот здесь.

четверг, 3 февраля 2011 г.

Всем доброго вечера. Сегодня спешу представить сильно доработанную, но пока не финальную версию параллакс мэппинга в исполнении quad. 
Идея возникла следующая. Что, если фон состоит из тайлов ( в примере из 6 по 512х512 ) и они скроллируются? Должен возникнуть эффект параллакса. То что выше — двигается быстрее, то что ниже — медленнее. К тому же более высокие части ландшафта должны перекрывать более низкие при соотвествующих углах зрения. 
Более того, что если над этим ландшафтом летит самолёт и он должен отбрасывать честную тень на ландшафт с учетом изменения формы (высоты) ландшафта? Разумеется, тень должна "плыть" по ландшафту. Искажаться. Вуаля:
В данном демо источник света установлен ровно по центру экрана, а уровень спекуляра минимален для всей сцены (около 15%). Используется 3 карты — диффузная, нормали и карта высот. Рендеринг осуществляется в 4 прохода. Комбинирование всех диффузных карт (сюда же входит и "плывущий" логотип), комбинирование карт высот, комбинирование карт нормалей и финальный рендер с наложением шейдера.
Для гибкой настройки по скорости выполнения предусмотрена возможность менять размеры рердертаргета и получать прирост в скорости в до 4х раз при скромном размере рендертаргета. (в демонстрации размер рендертаргета соотвествует размеру окна).
Скачать пример (670Кб)

пятница, 28 января 2011 г.

Доброго дня всем. Пришло время очередного гениального изобретения. Разумеется, все уже изобрели до меня. Я лишь использовал. Итак, Parallax steep (occlusion) mapping:
Для запуска необходима поддержка шейдеров версии 3.0.
Что имеется - честное попиксельное освещение, блики, изменение "геометрии" по карте высот. 
Качаем, смотрим:

четверг, 20 января 2011 г.

Доработал эффект bloom (3 прохода). Много расписывать не буду, лучше покажу:

вторник, 11 января 2011 г.

Последнее нововведение — QuadLog. Лог, позволяет как писать в него самому, так и передав любому quad классу писать в него автоматически. Мелочь, да. Давно надо было сделать — тоже да. Но в нормальный вид удалось привести только на днях.

Результат выглядит примерно следующим образом:

17:33:13 : Quad Engine v0.1.1
17:33:13 : QuadRender Initialization
17:33:13 : Resolution: 1024x768
17:33:14 : Driver: ati2dvag.dll
17:33:14 : Description: ASUS EAH4350 series
17:33:14 : Device: \\.\DISPLAY1
17:33:14 : Multisample: Off
17:33:14 : Fullscreen: Off
17:33:14 : Vsync: Off
17:29:46 : Vertex processing: Software
17:29:46 : Thread model: Multithreaded
17:29:46 : Max VB count: 594
17:29:46 : Max Texture size: 8192x8192
17:29:46 : Max Anisotropy: 16


Использование, как и в случае с остальными quad модулями безумно простое.

вторник, 21 декабря 2010 г.

Решил узнать какого качества игру можно сделать на quad. Для того, чтобы не замахиваться на что-то огромное, было решено накидать пакмана. Да не простого — а золотого!

Идея:
Классический пакман, но в темноте. Пакман — солнышко, которое подзаряжается точечками и светит ярче. Солнышко освещает всё вокруг, но свет не проходит сквозь стены.

Реализация:
Сложности реализации дали о себе знать с первых минут разработки. Если с полом всё понятно — там normalmapping, то со светом всё сложнее на порядок. Как делался свет. Итак, для затенения мы накладываем через умножение (multiply) карту освещенности. В карту освещенности должны попасть светящиеся точки (они слегка мерцают), небольшая область в пару пикселей вокруг точек (эффект свечения) и, собственно, свет от солнышка. Свет от солнышка заслуживает отдельной большой статьи. Обмолвлюсь лишь, что рендеринг в данном случае 17-ти проходный. Да, да! Однако результат превосходит ожидания. Свет не проходит сквозь препятствия, угасает с дальностью и более того — рассеивается с дальностью.

После окончания разработки света было решено оформить его дополнительным модулем и поставлять с движком, чтобы не было у простых смертных проблем с реализацией подобного эффекта. Чик и готово. Чуть больше прогресса покажу позже, пока только один скриншот.

вторник, 14 декабря 2010 г.

Длительное время не писал сюда. Думал что делать с блогом. В итоге решил переименовать и исправить  названия (старое название Joy3D Framework кануло в лету). За это время движок успел заметно подрасти и научиться рисовать довольно хитрые картинки. Обзавелся собственным сайтом http://quad-engine.com и даже парой игр, сделанных с его использованием. Но обо всём по порядку.

Скриншот, прикрепленный к этому посту показывает результат работы шейдеров и quad engine в целом. Результатом является честный raytracing теней от выбранных объектов сцены. Рендеринг многопроходный (сейчас около 17 проходов), но это будет оптимизироваться. На машинах с видеокартами класса GeForce7600 дает около 210fps. Мило?