Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник по GLScene.doc
Скачиваний:
255
Добавлен:
16.12.2018
Размер:
7.18 Mб
Скачать

Глава 42. Шейдеры glsl. Использование через компонент glslShader. Часть первая – Первые шаги.

Карпенюк Алексей,

karpenyuk@bk.ru

(публикация стилизованная)

В данной статье мы научимся добавлять к нашей программе эффекты созданные при помощи шейдеров.

Итак, создадим простой проект – разместим на форме такие компоненты – из закладки

GLScene помещаем редактор GLscene, так же добавим на форму GLSceneViewer,

GLMaterialLibrary и самое главное – из закладки GLScene Shaders поместим на форму компонент GLSLShader.

Теперь выполним стандартные процедуры по созданию сцены – подберем размер формы и

GLSceneViewer1, добавим в GLscene1 камеру и TGLFreeForm в качестве нашего объекта. Не забываем связать нашу камеру с GLSceneViewer1, указав в свойствах последнего Camera = GLCamera1. Теперь немного настроим камеру – для начала стоит ее немного отодвинуть от начала координат, иначе мы не увидим наш объект, для этого просто указываем в свойствах GLCamera1.Position новые координаты (X=0;Y=0;Z=7). На этом подготовительную часть можно считать завершенной.

Переходим к выбору объекта – возьмем один из стандартных объектов, поставляемый вместе со сценой, к примеру «mushroom.3ds».

Для того чтоб загрузить этот объект в нашу сцену нам потребуется выполнить простую операцию – в событии формы onCreate пишем такие вот строчки:

procedure TForm1.FormCreate(Sender: TObject);

begin

GLFreeForm1.ObjectStyle:=[osDirectDraw];

GLFreeForm1.LoadFromFile('mushroom.3ds');

GLFreeForm1.NormalsOrientation:=mnoInvert;

GLFreeForm1.PitchAngle:=90;

end;

Это загрузит наш грибок в сцену (не забываем

указать правильный путь к этому файлу). Гриб

у нас в файле неправильно повернутый, потому мы сразу же это исправили.

Изначально гриб имеет очень большие размеры, потому можете смело выставлять у GLFreeForm1.scale по каждой из осей равным 0.05

Строка GLFreeForm1.ObjectStyle:=[osDirectDraw] избавит нас от проблем на видеокартах производства ATI. Так как изначально нормали у нашего гриба повернуты вовнутрь, то мы их сразу

же вывернем наружу строчкой:

GLFreeForm1.NormalsOrientation:=mnoInvert. Так же не стоит забывать о том, что для использования формата 3ds нам необходимо добавить к проекту соответствующий модуль: Uses GLFile3ds;

Если мы все сделали правильно, то после запуска программы мы увидим вот такой вот черный грибок.

Вы спросите почему он черный? Это потому что мы не создали в сцене никаких источников света, но на данном этапе это нам не важно.

Теперь переходим к самому интересному – подключим к нашему грибу наш шейдер. Весь этап подключения заключается в создании нового материала и связывания его с нашим шейдером и применением его к объекту.

Первым делом создадим новый материал в библиотеке материалов, для этого дважды щелкнем на значке GLMaterialLibrary1 и в появившемся окне создадим новый материал.

Назовем его ShaderMaterial. После этого нам нужно будет связать

данный материал с нашим шейдером, для этого достаточно в инспекторе объектов свойству Shader присвоить значение GLSLShader1 (можно

выбрать из списка)

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

Выбираем наш TGLFreeForm1, ищем у него свойство Material,

раскрываем свиток (жмем «+»), выбираем в открывшемся списке MaterialLibrary и указываем там GLMaterialLibrary1. Теперь нам нужно указать какой материал из этой библиотеки у нас будет использован, для этого ищем там же свойство LibMaterialName и указываем там созданный нами материал – ShaderMaterial.

Итак, половина пути пройдена, самое время заняться написанием самого шейдера.

Для того, чтоб подчеркнуть что шейдер это отдельная программа мы будем ее создавать в обычном текстовом редакторе. У такого способа есть как недостаток (нам придется периодически переключаться между окном Delphi и блокнотом, для того чтоб отредактировать код, но зато мы всегда сможем быстро получить наш шейдер. К примеру для

внесения исправлений без запуска Delphi, или вдруг захотим его кому-то передать, или же просто захотим отладить или изменить его в специализированных редакторах, на подобии

RenderMonkey от ATI.

Итак, открываем блокнот и пишем там такие вот строчки:

void main(void)

{

gl_Position = ftransform();

}

И сохраняем этот файл с именем «Shader.Vert», Это и будет наш вершинный шейдер. Как

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

void main(void)

{

gl_FragColor = vec4( 0.4, 0.0, 0.9, 1.0 );

}

Сохраняем его с именем «Shader.Frag» - это будет наш фрагментный шейдер. Как вы видите

– там пока тоже только одна трока, и тоже обязательная – она возвращает цвет для данной вершины. В нашем примере для всех вершин задан одинаковый цвет, в чем мы скоро

убедимся.

Итак, файлы шейдеров созданы, самое время запустить их. Для этого нам потребуется еще немного изменить обработчик события формы onCreate – допишем туда вот такие строчки:

GLSLShader1.LoadShaderPrograms('Shader.Vert', 'Shader.Frag'); GLSLShader1.Enabled := true;

Целиком эта процедура теперь будет выглядеть как:

procedure TForm1.FormCreate(Sender: TObject);

begin

GLFreeForm1.LoadFromFile('mushroom.3ds');

GLSLShader1.LoadShaderPrograms('Shader.Vert', 'Shader.Frag');

GLSLShader1.Enabled := true;

end;

Данным фрагментом кода мы загрузили обе наших шейдерных программы и активировали шейдер. Теперь можно попробовать запустить программу:

Если вы все сделали правильно, то как я и обещал – вы увидите грибок залитый одним цветом. Который мы указали как: vec4( 0.4, 0.0, 0.9, 1.0 );

Тут стоит немного задержаться и объяснить каким образом

здесь задается цвет – в шейдере цвет задается в виде 4-х компонентного вектора – RGBA, каждая из компонент представлена в нормированном виде (тоесть от [0..1]), причем 1 соответствует в Windows компоненте 255. Нормированное значение цвета легко получить, разделив каждую из компонент на 255. к примеру если в Windows цвет задается как (r=100, g=50; b=150), то в шейдер пойдут

значения (100/255, 50/255, 150/255), что округленно будет соответствовать строчке -

vec4(0.4,0.2,0.6,1.0). Можете проиграться с цветом, изменяя эту величину в фрагментном шейдере, только не забывайте после каждого изменения шейдера перезапускать программу

(можно просто запускать уже откомпилированный ранее файл).