Пример - костер
Устанавливаем пиксельный и вершинных шейдеров и для компиляции обоих выбираем вторую версию. В самом начале инициализирован трех переменных, две для хранения матрицы (суммарную и вида) и одна переменная сохраняет счетчик, благодаря которому будет происходить анимация сцены, то есть огонь будет гореть. Далее идут три константы:
Первая определяет затухание огня (высоту), вторая ширину пламени, а последняя (xwind) - ветер. Структура, которая связывает входные и выходные данные, содержит позицию вершины и текстурные координаты: float4 Pos: POSITION; float2 tex_coord: TEXCOORDO;
Огонь будет краситься на основе двух текстур. В шейдеров необходимо только объявить переменную для данной текстуры и описать параметры ее отображения:
- Texture meshTexture; sampler Flame = sampler_state {
- texture = <meshTexture>; mipfilter = LINEAR;
- ...
- ...
- };
Вторая текстура может содержать любой узор или просто изображение шума. На ее основе градиент будет превращаться в огонь. В качестве этой текстуры выберем файл LobbyCube.dds из библиотеки DirectX SDK.
Теперь посмотрим на пиксельный шейдер. В самом начале заводим вектор из трех полей с именем coord: float3 coord. Теперь заполняем параметры этого вектора (x, y, z).
Координата X вектора coord будет соответствовать координате X пикселя А от значения Y нужно немного скорректировать на значение переменной viewAngle, чтобы происходил эффект движения текстуры снизу вверх, то есть эффект горения. Координата Z не будет использоваться, так как очаг двумерное.
Затем рассчитываем форму костер с помощью следующего кода: float shape = WidthFactor * (0.5 - sideFade * tex_coord.x * tex_coord.x)
Таким образом, получили общую форму, но это еще не все. С этой формы нужно определить область, которая будет более "горячей" (находится ближе к источнику горения):
float heat = saturate (shape + noisy - tex_coord.у)
Необходимо загрузить объект, внутри которого будет гореть огонь, точнее сказать, огонь будет рисоваться на поверхности текстуры этого объекта.
Кроме этого, в примере понадобятся две переменные для хранения текстуры:
Первая текстура будет содержать градиент огня, а вторая - текстуру шума.
Загрузим соответствующие текстуры на этапе инициализации следующим образом:
D3DXCreateTextureFromFile (pD3DDevice, "flame.bmp", & Texture)
D3DXCreateTextureFromFile (pD3DDevice, "LobbyCube.dds", & TextureNoice)
Загрузка шейдера должно выглядеть так:
D3DXCreateEf fectFromFile (pL) 3DDevice, "simple, vsh", 0,0,0,0, & pEffect, q ") pEffect-> SetTechnique (" PixeiLight ") pEffect-> SetValue (" meshTexture ", & Texture, D3DX_DEFAULT ) pEffect-> SetValue ("noiceTexture", sTextureNoice, D3DX_DEFAULT)
В первой строке загружаем шейдер из файла, а во втором - выбираем функцию Technique, которая будет использоваться для вывода графики. После этого заполняем переменные meshTexture и noiceTexture в шейдеры. Далее, должен идти описание вершин. Он ничем не отличается от предыдущих примеров и включает в себя две структуры - описание позиции и нормали.