Уроки Коммент.

Создание игр » DirectX 9, Featured » Pixel Shaders

Pixel Shaders

Pixel Shader 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 Shader Ну и сделал ещё некоторые менее существенные правки кода – смотрите в исходниках, там всё понятно и с комментариями на русском языке. На картинке вы видите, что получилось в итоге.

Возможно, вы заметите, что я немного изменил и вертексный шейдер, причём, передаю в нём цвет вертекса в пиксельный шейдер уже под видом текстурных координат. Так делать можно и, даже более того, так часто делают. В будущих уроках я расскажу вам зачем. В качестве эксперимента и развития собственных знаний в pixel shaders, Вы можете попробовать самостоятельно сделать так, что бы в шейдер передавались именно текстурные координаты, а не цвет, и вся работа шла именно с ними.

Как обычно, Вы можете скачать проект, включая все исходники шейдеров и текстуру.

Немного больше информации о пиксельных шейдерах Вы можете поулчить на MSDN и, конечно, в наших будущих уроках на этом блоге!

Ещё по этой теме:




Раздел: DirectX 9, Featured · Теги: Pixel shader, Shader

4 комментариев на "Pixel Shaders"
  1. Ander пишет:

    Правильно ли вместо

    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);

  2. lena пишет:

    В 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

    1. Вячеслав пишет:

      Если Вам не сложно – уточните пожалуйста, “исходник открывался только по частям” – это как? Я плохо понимаю…

  3. Yar пишет:

    Уже интереснее. Спс

Оставить комментарий

*

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>