HLSL
HLSL(англ.High Level Shader Language) —C-подобный язык высокого уровня для программированияшейдеров.
Был создан корпорациейMicrosoftи включён в пакетDirectX9.0, выпущенный в 2002 году.
Типы данных
[править|править код]HLSL поддерживает скалярные типы, векторные типы, матрицы и структуры.
Скалярные типы
[править|править код]Название | Характеристики типа |
---|---|
bool | булевый тип |
int | 32-битовое знаковое целое |
half | 16-битовое число с плавающей точкой |
float | 32-битовое число с плавающей точкой |
double | 64-битовое число с плавающей точкой |
Векторные типы
[править|править код]Примеры:
vector<float,4>color;
float4newcolor;
floatoldcolor[4];
newcolor=float4(oldcolor[0],oldcolor[1],oldcolor[2],oldcolor[3]);
Матрицы
[править|править код]Примеры:
matrix<float,4>view_matrix;
float4x4view_matrix;
Структуры
[править|править код]Примеры:
structvs_input
{
float4pos:POSITION;
float3nor:NORMAL;
float2uv:TEXCOORD0;
};
structps_input
{
float4pos:POSITION;
float3nor:NORMAL;
float2uv:TEXCOORD0;
floatCustomVar;
texture2DCustomTexture;
//и так далее…:POSITION:NORMAL и т. д. это сентиматики, о них ниже.
};
Операторы
[править|править код]Операции | Операторы |
---|---|
Арифметические | -, +, *, /, % |
Инкремент, декремент | ++, -- |
Логические | \|,?: |
Унарные | !, -, + |
Сравнения | <, >, <=, >=, ==,!= |
Назначение | =, -=, +=, *=, /= |
Приведение типов | (тип) |
Запятая | , |
Член структуры | . |
Член массива | [индекс] |
Ветвления
[править|править код]if(выражение) <оператор> [else<оператор>]
Циклы
[править|править код]В HLSL различают 3 вида циклов:
- do<оператор>while(<выражение>);
- while(<выражение>) <оператор>;
- for(<выражение1>; <выражение2>; <выражение3>) <оператор>
Функции
[править|править код]математические функции
[править|править код]abs(x) | возвращает абсолютную величину каждого компонента x |
acos(x) | возвращает арккосинус каждого компонента x. Каждый компонент должен быть в диапазоне [-1, 1] |
asin(x) | возвращает арксинус каждого компонента x. Каждый компонент должен быть в диапазоне [-pi/2, pi/2] |
atan(x) | возвращает арктангенс каждого компонента x. Каждый компонент должен быть в диапазоне [-pi/2, pi/2] |
ceil(x) | возвращает наименьшее целое число, которое больше чем или равно x (округление вверх) |
cos(x) | возвращает косинус x |
cosh(x) | возвращает гиперболический косинус x |
clamp(x, a, b) | Если x < a, то возвращает а, если x > b, то возвращает b, иначе возвращает x. |
ddx(x) | возвращает частную производную x относительно screen-space x-координаты |
ddy(x) | возвращает частную производную x относительно screen-space y-координаты |
degrees(x) | Конвертирование x с радианы в градусы |
distance(a, b) | возвращает расстояние между двумя точками a и b |
dot(a, b) | возвращает скалярное произведение двух векторов a и b |
exp(x) | возвращает экспоненту с основанием e, или ex |
floor(x) | возвращает самое большое целое число, которое является меньше чем или равным x (округление вниз) |
frac(x) | возвращает дробную часть x. |
fwidth(x) | возвращает abs(ddx(x))+abs(ddy(x)) |
len(v) | Векторная длина |
length(v) | возвращает длину вектора v |
lerp(a, b, s) | возвращает a + s (b — a) |
log(x) | возвращает логарифм x |
log10(x) | возвращает десятичный логарифм x |
modf(x, out ip) | возвращает на дробную и целую части x, каждая часть имеет тот же знак, что и x |
mul(a, b) | делает матричное умножение между a и b |
normalize(v) | возвращает нормированный вектор v |
pow(x, y) | возвращает xy |
radians(x) | конвертирует x из градусов в радианы |
reflect(i, n) | возвращает вектор отражения |
refract(i, n, eta) | возвращает вектор преломления. |
round(x) | возвращает ближайшее целое. |
rsqrt(x) | возвращает 1 / sqrt(x) |
saturate(x) | Аналогично clamp(x,0,1) |
sin(x) | возвращает синус x. |
sincos(x, out s, out c) | возвращает синус и косинус x |
sinh(x) | возвращает гиперболический синус x |
sqrt(x) | возвращает квадратный корень каждого компонента |
step(a, x) | возвращает 1 если x >= a, иначе возвращает 0 |
tan(x) | возвращает тангенс x |
tanh(x) | возвращает гиперболический тангенс x |
Функции для работы с текстурами
[править|править код]tex1D(s, t) | Чтение из одномерной текстуры s — sampler, t — скаляр. |
tex1D(s, t, ddx, ddy) | Чтение из одномерной текстуры, с производными s — sampler, t, ddx, и ddy — скаляры. |
tex1Dproj(s, t) | Чтение из одномерной проективной текстуры s — sampler, t — 4D вектор. t делится на t.w перед выполнением функции. |
tex1Dbias(s, t) | Чтение из одномерной текстуры со смещением, s — sampler, t — 4-мерный вектор. Мип-уровень смещается на t.w до того, как производится поиск. |
tex2D(s, t) | Чтение из двухмерной текстуры s — sampler, t — 2D вектор. |
tex2D(s, t, ddx, ddy) | Чтение из двухмерной текстуры, с производными. s — sampler, t — 2D текстурные координаты. ddx, ddy- 2D вектора. |
tex2Dproj(s, t) | Чтение из двумерной проективной текстуры. s — sampler, t — 4D вектор. t делится на t.w перед выполнением функции. |
tex2Dbias(s, t) | Чтение из двумерной текстуры со смещением. s — sampler, t — 4-мерный вектор. Мип-уровень смещается на t.w до того, как производится поиск. |
tex3D(s, t) | Чтение из трёхмерной текстуры. s — sampler, t — 3D вектор. |
tex3D(s, t, ddx, ddy) | Чтение из трёхмерной текстуры, с производными. s — sampler, t — 2D текстурные координаты, ddx, ddy — 3D вектора. |
tex3Dproj(s, t) | Чтение из трёхмерной проективной текстуры. s — sampler, t — 4D вектор. t делится на t.w перед выполнением функции. |
tex3Dbias(s, t) | Чтение из трёхмерной текстуры со смещением. s — sampler, t — 4-мерный вектор. Мип-уровень смещается на t.w до того, как производится поиск. |
texCUBE(s, t) | Чтение из кубической текстуры. s — sampler, t — 3D текстурные координаты. |
texCUBE(s, t, ddx, ddy) | Чтение из кубической текстуры. s — sampler, t — 3D текстурные координаты, ddx, ddy — 3D вектора. |
texCUBEproj(s, t) | Чтение из кубической проективной текстуры. s — sampler, t — 4D вектор. t делиться на t.w перед выполнением функции. |
texCUBEbias(s, t) | Чтение из кубической текстуры. sampler, t — 4D вектор. Мип-уровень смещается на t.w до того, как производится поиск. |
Входящие и исходящие данные для вершинного и пиксельного шейдеров
[править|править код]Вершинные и фрагментные шейдеры имеют два типа входящих данных:varyingиuniform.
Uniform— данные, которые постоянны для многократного использования в шейдере. Объявление uniform данных в HLSL можно сделать двумя способами:
1)Объявить данные как extern переменную. Например:
float4value;
float4main():COLOR
{
returnvalue;
}
2)Объявить данные через определитель uniform. Например:
float4main(uniformfloat4value):COLOR
{
returnvalue;
}
Uniform переменные задаются через таблицу констант. Таблица констант содержит все регистры, которые постоянно используются в шейдере.
Varying— данные, которые являются уникальными для каждого вызова шейдера. Например: позиция, нормаль и т. д. В вершинном шейдере такая семантика описывает varying данные, которые передаются из вершинного буфера, а во фрагментном шейдере — интерполированные данные, полученные из вершинного шейдера.
Основные входящие семантические типы:
BINORMAL | Бинормаль |
---|---|
BLENDWEIGHT | Весовой коэффициент |
BLENDINDICES | Индекс весовой матрицы |
COLOR | Цвет |
NORMAL | Нормаль |
POSITION | Позиция |
PSIZE | Размер точки |
TANGENT | Тангент |
TESSFACTOR | Фактортесселяции |
TEXCOORD | Текстурные координаты |
Использование varying данных во фрагментном шейдере определяет состояние одного фрагмента. Основные входящие семантические типы:
COLOR | Цвет |
---|---|
TEXCOORD | Текстурные координаты |
Исходящие данные для вершинного шейдера:
POSITION | Позиция |
---|---|
PSIZE | Размер точки |
FOG | Коэффициент «туманности» для вершины |
COLOR | Цвет |
TEXCOORD | Текстурные координаты |
Исходящие данные для фрагментного шейдера:
COLOR | Цвет |
---|---|
DEPTH | Значение глубины |
Программы для создания шейдеров
[править|править код]Для облегчения написания шейдеров существует ряд программ, позволяющих составлять шейдеры и тут же просматривать результат
- RenderMonkeyотATI(ATI 3D Application Research Group)
- ShaderWorksотMad Software Inc
- FXComposerотNvidia
- Shader Config
Также пиксельные шейдеры используются визуализаторами, например,
Примеры
[править|править код]Стиль этого разделанеэнциклопедичен или нарушает нормы литературного русского языка. |
Простейший шейдер «Texture mapping»
[править|править код]Код в этом листинге работает в ATI Rendermonkey и Nvidia FX composer. Для использования в кастомном движке нужно указать SamplerState и technique.
/* ========== ВЕРШИННЫЙ ШЕЙДЕР ========== */
/* world_matrix, view_matrix, proj_matrix необходимо получить из приложения, установив константы шейдера.
Константы шейдера загружаются в регистры. */
float4x4world_matrix;// мировая матрица
float4x4view_matrix;// матрица вида
float4x4proj_matrix;// матрица проекции
structVS_OUTPUT// экземпляр этой структуры будет возвращать вершинный шейдер
{
float4Pos:POSITION0;/* POSITION0 и TEXCOORD0 - семантики, обозначающие слоты, из которых пиксельный
шейдер будет в дальнейшем получать данные. Семантики, указанные здесь должны совпадать с семантиками во
входных данных пиксельного шейдера. Имена переменных и их порядок может различаться.*/
float2TexCoord:TEXCOORD0;
};
VS_OUTPUTVS_Main(float4InPos:POSITION0,float2InTexCoord:TEXCOORD0)/* Вершинный шейдер выполняется
для каждой вершины выводимого объекта. InPos и InTexCoord получены из данных stream-mapping'a */
{
VS_OUTPUTOut;
float4x4worldViewProj_matrix=mul(world_matrix,view_matrix);
worldViewProj_matrix=mul(worldViewProj_matrix,proj_matrix);
Out.Pos=mul(InPos,worldViewProj_matrix);// трансформируем вершину в clip-space
Out.TexCoord=InTexCoord;// текстурные координаты мы получаем извне, ничего модифицировать не нужно
returnOut;
}
/* ========== ПИКСЕЛЬНЫЙ ШЕЙДЕР ========== */
sampler2DbaseMap;// sampler2D - специальный слот "текстурный слот" в который можно загрузить текстуру.
float4PS_Main(float2texCoord:TEXCOORD0):COLOR0/* пиксельный шейдер всегда возвращает цвет выводимого
пикселя с семантикой COLOR0 в формате float4. Пиксельный шейдер выполняется для каждого пикселя выводимого
на экран изображения (а не для каждого текселя текстуры) */
{
returntex2D(baseMap,texCoord);/* tex2d(sampler2D, float2) читает из текстурного сэмплера
(из текстуры) цвет её текселя с заданными текстурными координатами. Это и будет цвет выводимого пикселя. */
}
Простой шейдер «Головокружение»
[править|править код]float4x4view_proj_matrix:register(c0);
structVS_OUTPUT
{
float4Pos:POSITION;
float2texCoord:TEXCOORD0;
};
VS_OUTPUTVS_Dizzy(float4Pos:POSITION)
{
VS_OUTPUTOut;
Pos.xy=sign(Pos.xy);
Out.Pos=float4(Pos.xy,0,1);
Out.texCoord=Pos.xy;
returnOut;
}
floattime_0_X:register(c0);
floatrings:register(c1);
floatspeed:register(c2);
floatexponent:register(c3);
float4PS_Dizzy(float2texCoord:TEXCOORD0):COLOR
{
floatang=atan2(texCoord.x,texCoord.y);
floatrad=pow(dot(texCoord,texCoord),exponent);
return0.5*(1+sin(ang+rings*rad+speed*time_0_X));
}
Шейдер, имитирующий электрический разряд
[править|править код]structVS_OUTPUT
{
float4Pos:POSITION;
float2texCoord:TEXCOORD;
};
VS_OUTPUTVS_Electricity(float4Pos:POSITION)
{
VS_OUTPUTOut;
// Clean up inaccuracies
Pos.xy=sign(Pos.xy);
Out.Pos=float4(Pos.xy,0,1);
Out.texCoord=Pos.xy;
returnOut;
}
float4color:register(c1);
floatglowStrength:register(c2);
floatheight:register(c3);
floatglowFallOff:register(c4);
floatspeed:register(c5);
floatsampleDist:register(c6);
floatambientGlow:register(c7);
floatambientGlowHeightScale:register(c8);
floatvertNoise:register(c9);
floattime_0_X:register(c0);
samplerNoise:register(s0);
float4PS_Electricity(float2texCoord:TEXCOORD):COLOR
{
float2t=float2(speed*time_0_X*0.5871-vertNoise*abs(texCoord.y),speed*time_0_X);
// Sample at three positions for some horizontal blur
// The shader should blur fine by itself in vertical direction
floatxs0=texCoord.x-sampleDist;
floatxs1=texCoord.x;
floatxs2=texCoord.x+sampleDist;
// Noise for the three samples
floatnoise0=tex3D(Noise,float3(xs0,t));
floatnoise1=tex3D(Noise,float3(xs1,t));
floatnoise2=tex3D(Noise,float3(xs2,t));
// The position of the flash
floatmid0=height*(noise0*2-1)*(1-xs0*xs0);
floatmid1=height*(noise1*2-1)*(1-xs1*xs1);
floatmid2=height*(noise2*2-1)*(1-xs2*xs2);
// Distance to flash
floatdist0=abs(texCoord.y-mid0);
floatdist1=abs(texCoord.y-mid1);
floatdist2=abs(texCoord.y-mid2);
// Glow according to distance to flash
floatglow=1.0-pow(0.25*(dist0+2*dist1+dist2),glowFallOff);
// Add some ambient glow to get some power in the air feeling
floatambGlow=ambientGlow*(1-xs1*xs1)*(1-abs(ambientGlowHeightScale*texCoord.y));
return(glowStrength*glow*glow+ambGlow)*color;
}
Пластилиновая модель
[править|править код]float4x4view_proj_matrix:register(c0);
float4view_position:register(c4);
structVS_OUTPUT
{
float4Pos:POSITION;
float3normal:TEXCOORD0;
float3viewVec:TEXCOORD1;
};
VS_OUTPUTVS_Plastic(float4Pos:POSITION,float3normal:NORMAL)
{
VS_OUTPUTOut;
Out.Pos=mul(view_proj_matrix,Pos);
Out.normal=normal;
Out.viewVec=view_position-Pos;
returnOut;
}
float4color:register(c0);
float4PS_Plastic(float3normal:TEXCOORD0,float3viewVec:TEXCOORD1):COLOR
{
floatv=0.5*(1+dot(normalize(viewVec),normal));
returnv*color;
}
Ссылки
[править|править код]- Программирование шейдеров на HLSL. / Графика / Статьи / Программирование игр / GameDev.ru — Разработка игр
- Шейдерная революция Nvidia: десять лет спустя
Для улучшения этой статьижелательно:
|