Смотрел TRON:legacy и зацепил меня эффект в титрах фильма. Чем описывать, лучше покажу:
Эффект хорошо виден по краям, несколько замутняющий изображение, делающий его светлее и работающий как призма, раскладывая цвет на составляющие вдали от центра изображения.
Впечатлил он меня именно с точки зрения реализовать в реалтайме самому. Что я и сделал:
Скриншот неравносильный и эффект усилен, но думаю, оценить можно.
воскресенье, 10 апреля 2011 г.
пятница, 8 апреля 2011 г.
среда, 9 марта 2011 г.
Сегодня всё кратко — открылась wiki по quad-engine. Справка, по большому счету.
http://quad-engine.com/wiki/
А также форумом.
http://quad-engine.com/bb/
http://quad-engine.com/wiki/
А также форумом.
http://quad-engine.com/bb/
среда, 2 марта 2011 г.
Good news everyone!
Продолжается экспансия в сторону интерфейсов. Перевод почти закончен и все работает просто отлично. Наисправлял много мелочей. Там затюнил, здесь подрихтовал. В частности добавил возможность запуска в полноэкранном режиме на любом из имеющихся в системе мониторов. В процессе доделывание автоопределения размеров изображения до загрузки. Текстурный блок вот-вот научится загружать DXT1, DXT3 и DXT5 форматы файла DDS. Вообщем 0.1.4 не за горами :)
Продолжается экспансия в сторону интерфейсов. Перевод почти закончен и все работает просто отлично. Наисправлял много мелочей. Там затюнил, здесь подрихтовал. В частности добавил возможность запуска в полноэкранном режиме на любом из имеющихся в системе мониторов. В процессе доделывание автоопределения размеров изображения до загрузки. Текстурный блок вот-вот научится загружать DXT1, DXT3 и DXT5 форматы файла DDS. Вообщем 0.1.4 не за горами :)
среда, 16 февраля 2011 г.
quad engine 0.1.3
Закончен перевод базовых классов на интерфейсы. Создан заголовочный файл. Как только все работы по переводу будут завершены, quad можно будет использовать в любом языке программирования, поддерживающем интерфейсы. К сожалению, жертвой интерфейсам стала необходимость запечь весь quad в dll. Хотя, на текущий размер скромен — 280Кб. В масштабах современных разработок размер более чем скромный, не так ли?
К счастью, подход имеет больше плюсов, чем минусов. И еще один из таких плюсов — ООП подход.
На текущий момент реализованы 4 базовых интерфейса: IQuadRender, IQuadTexture, IQuadFont и IQuadShader. Боюсь, что до завершения переделки движка на интерфейсы, новостей не будет. Также надеюсь что переделка не займет много времени.
Закончен перевод базовых классов на интерфейсы. Создан заголовочный файл. Как только все работы по переводу будут завершены, 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Кб. Вполне доволен результатом. Оу... забыл. Добавил дополнительные поля в лог при инициализации. Теперь движок "знает" о аспекте, количестве и разрешении мониторов в системе.
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:
В третий рендертаргет рендерится карта нормалей для всего ландшафта.
Шаг 6:
Осталось дорисовать сами объекты поверх ландшафта, делая это привычным методом. Тут уже никаких секретов нет.
Шейдер:
Шейдер заслуживает отдельной статьи так как достаточно объемен. Сначала в программе высчитывается TBN для вершин (в quad-engine делается автоматом), далее TBN, матрица проекции и позиция источника света передаются в вершинный шейдер. Вершинный шейдер переводит все полученные параметры в тангент-спейс полигона и дальнейшая работа уже идет с ним. На выхлопе для каждого пикселя вектор света и вектор вида.
Пиксельный шейдер. Из карты высот берется значение высоты и учитывая вектор вида в данной точке ищется пересечение луча вида с плоскостью с учетом поправки на высоту (взятую из карты высот). Далее идет 8 итераций на корректировку текстурных координат, точнее на поиск более близкого значения к желаемому. После нахождения производится ленейная интерполяция в пределах 1\8 глубины (для этого и делается 8 проходов). Таким образом получается достаточно точное значение, которое и берется как реальные текстурные координаты. Пиксель из этих текстурных координат уже и выводится. Также по этим текстурным координатам берется вектор из карты нормалей и производится затенение картинки, согласно расположению источника света (в примере ровно по центру экрана). Добавляется спекуляр и эмбиент по вкусу и результат готов.
Подробно с кодом почитать о Parallax mapping можно вот здесь.
В предыдущем посте я рассказал и показал пример 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 можно вот здесь.
Ярлыки:
HowTo,
QuadRender,
QuadShader,
QuadTexture,
Void Story
Подписаться на:
Сообщения (Atom)









