воскресенье, 10 апреля 2011 г.

Смотрел TRON:legacy и зацепил меня эффект в титрах фильма. Чем описывать, лучше покажу:

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

 Впечатлил он меня именно с точки зрения реализовать в реалтайме самому. Что я и сделал:




 Скриншот неравносильный и эффект усилен, но думаю, оценить можно.

пятница, 8 апреля 2011 г.

Версия quadfont доведена до вменяемого состояния. Утилита теперь поддерживает большие шрифты, сама подбирает размер текстуры и имеет более дружественный интерфейс:

среда, 9 марта 2011 г.

Сегодня всё кратко — открылась wiki по quad-engine. Справка, по большому счету.
http://quad-engine.com/wiki/

А также форумом.
http://quad-engine.com/bb/

среда, 2 марта 2011 г.

Good news everyone!
Продолжается экспансия в сторону интерфейсов. Перевод почти закончен и все работает просто отлично. Наисправлял много мелочей. Там затюнил, здесь подрихтовал. В частности добавил возможность запуска в полноэкранном режиме на любом из имеющихся в системе мониторов. В процессе доделывание автоопределения размеров изображения до загрузки. Текстурный блок вот-вот научится загружать DXT1, DXT3 и DXT5 форматы файла DDS. Вообщем 0.1.4 не за горами :)

среда, 16 февраля 2011 г.

quad engine 0.1.3
Закончен перевод базовых классов на интерфейсы. Создан заголовочный файл. Как только все работы по переводу будут завершены, quad можно будет использовать в любом языке программирования, поддерживающем интерфейсы. К сожалению, жертвой интерфейсам стала необходимость запечь весь quad в dll. Хотя, на текущий размер скромен — 280Кб. В масштабах современных разработок размер более чем скромный, не так ли?
К счастью, подход имеет больше плюсов, чем минусов. И еще один из таких плюсов — ООП подход.
На текущий момент реализованы 4 базовых интерфейса: IQuadRender, IQuadTexture, IQuadFont и IQuadShader. Боюсь, что до завершения переделки движка на интерфейсы, новостей не будет. Также надеюсь что переделка не займет много времени.

вторник, 8 февраля 2011 г.

Наконец-то дошли руки до модуля, создающего окошко и управляющего получением сообщений. Видимо туда же перекочует и таймер. Пока в зачаточном состоянии, однако уже результат налицо. Минимальное приложение рисующее прямоугольничек на черном фоне и создающее лог выглядит так:

program Project1;

uses
  Windows, QuadWindow, QuadRender, QuadLog;

var
  qr : TQuadRender;
  ql : TQuadLog;

procedure Main;
begin
  qr.BeginRender;
  qr.Clear(0);
  qr.Rectangle(0, 0, 10, 10, Random($FFFFFFFF));
  qr.EndRender;
end;

begin
  CreateWindow;

  ql := TQuadLog.Create;

  qr := TQuadRender.Create;
  qr.Initialize(h_Wnd, 640, 480, ql);

  OnIdle := Main;
  EnterMainCycle;
end.



Ехе файл при этом 60Кб. Вполне доволен результатом. Оу... забыл. Добавил дополнительные поля в лог при инициализации. Теперь движок "знает" о аспекте, количестве и разрешении мониторов в системе.

пятница, 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 можно вот здесь.