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

Создание игр » Новости » Vertex shaders

Vertex shaders

vertex shader Vertex shader (вершинный шейдер) занимается обработкой данных вершин модели. Такие данные как координаты вершины в пространстве, текстурные координаты, тангент-вектор, бинормаль, нормаль обрабатываются как раз вершинными шейдерами. Кроме того, vertex shader занимается преобразованием модели из пространства модели в пространство мира/вида/проекции. Он может сам генерировать текстурные координаты или менять форму самой модели, например, “пустить” волны по ровной поверхности воды или как-то изогнуть модель, провести трансформации в соответствии со скелетной анимацией, может почитать освещённость вершин модели и много чего ещё…

Давайте более подробно разберём тему вертексных шейдеров (vertex shaders) и научимся их применять.

Vertex shader, как и прочие виды шейдеров, представляет из себя ни что иное, как функцию, которая получает какие-то параметры на входе и отдаёт результат на выходе. В предыдущем уроке мы уже использовали достаточно простой vertex shader:

struct VS_OUTPUT // тут будет результат работы шейдера
{
	float4 Pos  : POSITION; // позиция вертекса
	float4 Color: COLOR0; // цвет вертекса
};
 
// сама функция шейдера. кстати, она может иметь любое имя.
void main(float3 Pos  : POSITION/* позиция вертекса в мире*/,
	float4 Color: COLOR0 /* цвет вертекса*/,
	out VS_OUTPUT Out /* а это результат, т.к. ключевое слово out */)
{
	// просто передём исходные параметры в пиксельный шейдер
	Out.Pos = float4(Pos, 1); // не изменяем координаты
	Out.Color = Color; // и не изменяем цвет
}

В этом примере видно, как получаются данные от vertex’а в шейдер. Но не понятно, как получать данные НЕ из vertex’а. Например, какие-то матрицы, или, скажем, цвет освещения. Не будем же мы запихивать такие данные в каждый вертекс, тем более, что эти данные общие для всех вертексов? Конечно же, не будем. Для этого существует возможность передавать данные непосредственно в шейдер их программы. Но эти данные будет нельзя изменить в шейдере, их можно только читать, но нельзя в них записывать. Потому они называются константы. И эти константы хранятся в константном буфере каждого шейдера. Кстати, этот константный буфер мы тоже уже получили в примере предыдущего урока:

D3DXCompileShader(srcVS.c_str(), srcVS.length(), NULL, NULL, "main",
	"vs_2_0", D3DXSHADER_OPTIMIZATION_LEVEL3, &pShaderBuff, 
	&pErrors, &pConstTableVS/* А вот и таблица констант шейдера*/);

Все функции для работы с таблицей констант описаны в DirectX SDK, потому я не буду дублировать информацию – если Вам интересно, просто найдите в указателе “ID3DXConstantTable” и почитайте. Я же просто покажу пример того, как работать с этой таблицей.

Давайте для начала немного усложним наш вертексный шейдер:

// vertex transformations world
float4x4 mWorld;
// vertex transformation view/projection
float4x4 mViewProjection;
 
struct VS_OUTPUT
{
	float4 Pos  : POSITION;
	float4 Color: COLOR0;
};
 
VS_OUTPUT main(float3 Pos  : POSITION0, float4 Color: COLOR0)
{
	VS_OUTPUT Out;
	// tranform vertex
	float4 pos = mul(float4(Pos, 1), mWorld);
	Out.Pos = mul(pos, mViewProjection);
	Out.Color = Color;
	return Out;
}

И после этого можно задавать константы шейдера mViewProjection и mWorld из нашего кода на плюсах:

// передаём матрицу мира в вертексный шейдер
pConstTableVS->SetMatrix(m_pd3dDevice, "mWorld", &mat);
// передаём матрицу вида/проекции в вертексный шейдер
pConstTableVS->SetMatrix(m_pd3dDevice, "mViewProjection", &matViewProj);

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

А вот и проект с исходным кодом к статье.

И небольшой видео-пример того, как vertex shader может помочь в анимации растительности:

Немного позже, в следующих уроках, я покажу и расскажу, как добиться такого эффекта.

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




Раздел: Новости

Один комментарий на "Vertex shaders"
  1. Yar пишет:

    И опять спасибо!

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

*

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