Создание игр » DirectX 9, Featured » Pixel Shaders
Pixel Shaders
Pixel shaders, для чего же они используются в компьютерной графике и играх? Пиксельный (или фрагментный) шейдер – это шейдерная программа, которая занимается обработкой отдельных пикселей изображения. В конечном итоге, по большей части, именно pixel shader определяет насколько красиво и естественно будет выглядеть конечное изображение. Причём, пиксельные шейдеры могут использоваться не только для формирования самого изображения, но и для его пост-процессинга, т.е. для создания некоторых спец-эффектов.
В современных играх pixel shader’ы активно используются для создания динамического освещения, в том числе очень большим количеством источников света:
Но мы с вами начнём, конечно же, с начала, т.е. с чего-то более простого. А со временем научимся делать и более сложные, интересные и красивые эффекты с помощью pixel shaders.
Алгоритм работы pixel shader аналогичен принципам работы vertex shader. Главное отличие этих шейдеров состоит в том, что pixel-шейдер, помимо прочих параметров, принимает так же параметры, переданные ему vertex shader’ом. Как это происходит? Вертексный шейдер передаёт данные в pixel shader через специальные регистры, коих немало – в большей части видеокарт их от 256 штук и больше. Каждый из регистров хранит 4 float значения, т.е. 4мерный вектор.
В уроке Shaders (Шейдеры) мы уже использовали возможности передачи данных в пиксекльный шейдер из вертексного. Структура VS_OUTPUT в вертексном шейдере как раз содержит данные, которые являются результатом работы вертексного шейдера и, следовательно, именно они передадутся в качестве параметров pixel shader’а. Параметр пиксельного шейдера float4 Color: COLOR0 содержит в себе то значение, которое передал вертексный шейдер как результат своей работы.
Но пиксельный шейдер может, помимо этих значений, использовать другие, переданные ему программой, значения – это могут быть как матрицы или вектора, так и текстуры. Давайте попробуем сделать простейший пиксельный шейдер, отображающий текстуру:
sampler2D tex0 : register(s0); // текстура для pixel shader // основная функция pixel shader'а float4 pixel_shader_main(float2 tc:TEXCOORD0) : COLOR { return tex2D(tex0, tc); } |
И зададим в C++ ту текстуру, которую будет использовать наш шейдер:
m_pd3dDevice->SetTexture(0/*номер сэмплера*/, pTex/*наша текстура*/); // настраиваем фильтрацию текстуры m_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); m_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); m_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); |
Сама текстура выглядит вот так. Я взял её с сайта cgtextures.com , на котором есть большая коллекция бесплатных текстур. После установки этой текстуры в нулевой сэмплер, она станет доступна из нашего пиксельного шейдера. Вообще шейдер можно передать достаточно много текстур сразу – большинство видео-карт позволяют использовать в пиксельных шейдерах по меньшей мере 4 текстуры, а значительная часть вообще позволяет использовать 8 и более текстур. Хотя, конечно же, должно быть понятно, что чем меньше текстур – тем лучше, потому как шейдер будет работать быстрее.
Кстати, для загрузки текстур форматов BMP, PNG, DDS и JPG в библиотеке D3DX есть специальная фнукция. Вот как я её использовал для загрузки текстуры:
LPDIRECT3DTEXTURE9 m_pTex = NULL; D3DXCreateTextureFromFile(m_pd3dDevice, "Data/stone-ground-diff.dds", &m_pTex); |
Ну и сделал ещё некоторые менее существенные правки кода – смотрите в исходниках, там всё понятно и с комментариями на русском языке. На картинке вы видите, что получилось в итоге.
Возможно, вы заметите, что я немного изменил и вертексный шейдер, причём, передаю в нём цвет вертекса в пиксельный шейдер уже под видом текстурных координат. Так делать можно и, даже более того, так часто делают. В будущих уроках я расскажу вам зачем. В качестве эксперимента и развития собственных знаний в pixel shaders, Вы можете попробовать самостоятельно сделать так, что бы в шейдер передавались именно текстурные координаты, а не цвет, и вся работа шла именно с ними.
Как обычно, Вы можете скачать проект, включая все исходники шейдеров и текстуру.
Немного больше информации о пиксельных шейдерах Вы можете поулчить на
Раздел: DirectX 9, Featured · Теги: Pixel shader, Shader
Правильно ли вместо
sampler2D tex0 : register(s0); // текстура для pixel shader
// основная функция pixel shader’а
float4 pixel_shader_main(float2 tc:TEXCOORD0) : COLOR
{
return tex2D(tex0, tc);
}
использовать такой способ?
Texture2D tDepthMap:register (s4);
sampler TestTextureSampler =
sampler_state
{
Texture = ;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
…
shadowMapDepth = tDepthMap.SampleLevel(TestTextureSampler,float2( vScreenCoord.x, vScreenCoord.y ),0);
…
В Microsoft Visual C++ исходник не открывался весь (только по частям), так, как нет файла DSW, есть выход – его надо создать. Сделать простой проект Hello word с названием к примеру Tutorial-03 и из него скопировать созданные файлы DSW DSP.
В них внести изменения
(1) переименовать их именем своего проекта,
(2)в DSW изменить в этом месте Project: 1″=”\Tutorial-03.dsp” ( Tutorial-03.dsp-на имя своего проекта.dsp).(3)в DSP после # Begin Target изменить все Tutorial-03-на имя своего проекта и добавить по аналогии не прописанные файлы из папки проекта к примеру эти
SOURCE=.\ps.hls
# End Source File
# Begin Source File
SOURCE=.\vs.hls
# End Source File
# Begin Source File
Если Вам не сложно – уточните пожалуйста, “исходник открывался только по частям” – это как? Я плохо понимаю…
Уже интереснее. Спс