Лучшие вопросы
Таймлайн
Чат
Перспективы

HLSL

Из Википедии, свободной энциклопедии

Remove ads

HLSL (англ. High Level Shader Language) — C-подобный язык высокого уровня для программирования шейдеров.

Был создан корпорацией Microsoft и включён в пакет DirectX 9.0, выпущенный в 2002 году.

Типы данных

HLSL поддерживает скалярные типы, векторные типы, матрицы и структуры.

Скалярные типы

Подробнее Название, Характеристики типа ...

Векторные типы

Примеры:

vector <float, 4> color;
float4 newcolor;
float oldcolor[4];
newcolor = float4(oldcolor[0], oldcolor[1], oldcolor[2], oldcolor[3]);

Матрицы

Примеры:

matrix <float, 4> view_matrix;
float 4x4 view_matrix;

Структуры

Примеры:

struct vs_input
{
   float4 pos:POSITION;
   float3 nor:NORMAL;
   float2 uv:TEXCOORD0;
};
struct ps_input
{
   float4 pos:POSITION;
   float3 nor:NORMAL;
   float2 uv:TEXCOORD0;
   float CustomVar;
   texture2D CustomTexture;
   //и так далее… :POSITION :NORMAL и т. д. это сентиматики, о них ниже.
};
Remove ads

Операторы

Подробнее Операции, Операторы ...

Ветвления

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 до того, как производится поиск.
Remove ads

Входящие и исходящие данные для вершинного и пиксельного шейдеров

Суммиров вкратце
Перспектива

Вершинные и фрагментные шейдеры имеют два типа входящих данных: varying и uniform.

Uniform — данные, которые постоянны для многократного использования в шейдере. Объявление uniform данных в HLSL можно сделать двумя способами:

1)Объявить данные как extern переменную. Например:

float4 value;

float4 main () : COLOR
{
  return value;
}

2)Объявить данные через определитель uniform. Например:

float4 main (uniform float4 value) : COLOR
{
  return value;
}

Uniform переменные задаются через таблицу констант. Таблица констант содержит все регистры, которые постоянно используются в шейдере.

Varying — данные, которые являются уникальными для каждого вызова шейдера. Например: позиция, нормаль и т. д. В вершинном шейдере такая семантика описывает varying данные, которые передаются из вершинного буфера, а во фрагментном шейдере — интерполированные данные, полученные из вершинного шейдера.

Основные входящие семантические типы:

Подробнее BINORMAL, BLENDWEIGHT ...

Использование varying данных во фрагментном шейдере определяет состояние одного фрагмента. Основные входящие семантические типы:

Подробнее COLOR, TEXCOORD ...

Исходящие данные для вершинного шейдера:

Подробнее POSITION, PSIZE ...

Исходящие данные для фрагментного шейдера:

Подробнее COLOR, DEPTH ...
Remove ads

Программы для создания шейдеров

Для облегчения написания шейдеров существует ряд программ, позволяющих составлять шейдеры и тут же просматривать результат

  • RenderMonkey от ATI (ATI 3D Application Research Group)
  • ShaderWorks от Mad Software Inc
  • FXComposer от Nvidia
  • Shader Config

Также пиксельные шейдеры используются визуализаторами, например,

  • Milkdrop от Nullsoft — Этот плагин позволяет создавать шейдеры, зависящие от музыки.
Remove ads

Примеры

Суммиров вкратце
Перспектива

Простейший шейдер «Texture mapping»

Код в этом листинге работает в ATI Rendermonkey и Nvidia FX composer. Для использования в кастомном движке нужно указать SamplerState и technique.

/* ========== ВЕРШИННЫЙ ШЕЙДЕР ========== */
/* world_matrix, view_matrix, proj_matrix необходимо получить из приложения, установив константы шейдера. 
Константы шейдера загружаются в регистры. */
float4x4 world_matrix; // мировая матрица
float4x4 view_matrix;  // матрица вида
float4x4 proj_matrix;  // матрица проекции

struct VS_OUTPUT // экземпляр этой структуры будет возвращать вершинный шейдер
{
   float4 Pos: POSITION0; /* POSITION0 и TEXCOORD0 - семантики, обозначающие слоты, из которых пиксельный 
шейдер будет в дальнейшем получать данные. Семантики, указанные здесь должны совпадать с семантиками во 
входных данных пиксельного шейдера. Имена переменных и их порядок может различаться.*/
   float2 TexCoord: TEXCOORD0;
};

VS_OUTPUT VS_Main(float4 InPos: POSITION0, float2 InTexCoord : TEXCOORD0) /* Вершинный шейдер выполняется 
для каждой вершины выводимого объекта. InPos и InTexCoord получены из данных stream-mapping'a */
{
   VS_OUTPUT Out;

   float4x4 worldViewProj_matrix = mul(world_matrix, view_matrix);
   worldViewProj_matrix = mul(worldViewProj_matrix, proj_matrix);

   Out.Pos = mul(InPos,  worldViewProj_matrix); // трансформируем вершину в clip-space
   Out.TexCoord = InTexCoord; // текстурные координаты мы получаем извне, ничего модифицировать не нужно

   return Out;
}

/* ========== ПИКСЕЛЬНЫЙ ШЕЙДЕР ========== */

sampler2D baseMap; // sampler2D - специальный слот "текстурный слот" в который можно загрузить текстуру.

float4 PS_Main(float2 texCoord: TEXCOORD0) : COLOR0 /* пиксельный шейдер всегда возвращает цвет выводимого 
пикселя с семантикой COLOR0 в формате float4. Пиксельный шейдер выполняется для каждого пикселя выводимого 
на экран изображения (а не для каждого текселя текстуры) */
{
   return tex2D( baseMap, texCoord ); /* tex2d(sampler2D, float2) читает из текстурного сэмплера 
(из текстуры) цвет её текселя с заданными текстурными координатами. Это и будет цвет выводимого пикселя. */
}

Простой шейдер «Головокружение»

Thumb
float4x4 view_proj_matrix: register(c0);

struct VS_OUTPUT 
{
   float4 Pos: POSITION;
   float2 texCoord: TEXCOORD0;
};

VS_OUTPUT VS_Dizzy(float4 Pos: POSITION)
{
   VS_OUTPUT Out;

   Pos.xy = sign(Pos.xy);

   Out.Pos = float4(Pos.xy, 0, 1);
   Out.texCoord = Pos.xy;

   return Out;
}

float time_0_X: register(c0);
float rings: register(c1);
float speed: register(c2);
float exponent: register(c3);

float4 PS_Dizzy(float2 texCoord: TEXCOORD0) : COLOR 
{
   float ang = atan2(texCoord.x, texCoord.y);
   float rad = pow(dot(texCoord, texCoord), exponent);

   return 0.5 * (1 + sin(ang + rings * rad + speed * time_0_X));
}

Шейдер, имитирующий электрический разряд

Thumb
struct VS_OUTPUT 
{
   float4 Pos: POSITION;
   float2 texCoord: TEXCOORD;
};

VS_OUTPUT VS_Electricity(float4 Pos: POSITION)
{
   VS_OUTPUT Out;

   // Clean up inaccuracies
   Pos.xy = sign(Pos.xy);

   Out.Pos = float4(Pos.xy, 0, 1);
   Out.texCoord = Pos.xy;

   return Out;
}

float4 color: register(c1);
float glowStrength: register(c2);
float height: register(c3);
float glowFallOff: register(c4);
float speed: register(c5);
float sampleDist: register(c6);
float ambientGlow: register(c7);
float ambientGlowHeightScale: register(c8);
float vertNoise: register(c9);
float time_0_X: register(c0);
sampler Noise: register(s0);

float4 PS_Electricity(float2 texCoord: TEXCOORD) : COLOR 
{
   float2 t = 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
   float xs0 = texCoord.x - sampleDist;
   float xs1 = texCoord.x;
   float xs2 = texCoord.x + sampleDist;

   // Noise for the three samples
   float noise0 = tex3D(Noise, float3(xs0, t));
   float noise1 = tex3D(Noise, float3(xs1, t));
   float noise2 = tex3D(Noise, float3(xs2, t));

   // The position of the flash
   float mid0 = height * (noise0 * 2 - 1) * (1 - xs0 * xs0);
   float mid1 = height * (noise1 * 2 - 1) * (1 - xs1 * xs1);
   float mid2 = height * (noise2 * 2 - 1) * (1 - xs2 * xs2);

   // Distance to flash
   float dist0 = abs(texCoord.y - mid0);
   float dist1 = abs(texCoord.y - mid1);
   float dist2 = abs(texCoord.y - mid2);

   // Glow according to distance to flash
   float glow = 1.0 - pow(0.25 * (dist0 + 2 * dist1 + dist2), glowFallOff);

   // Add some ambient glow to get some power in the air feeling
   float ambGlow = ambientGlow * (1 - xs1 * xs1) * (1 - abs(ambientGlowHeightScale * texCoord.y));

   return (glowStrength * glow * glow + ambGlow) * color;
}

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

Thumb
float4x4 view_proj_matrix: register(c0);

float4 view_position: register(c4);

struct VS_OUTPUT 
{
	float4 Pos: POSITION;
	float3 normal: TEXCOORD0;
	float3 viewVec: TEXCOORD1;
};

VS_OUTPUT VS_Plastic(float4 Pos: POSITION, float3 normal: NORMAL)
{
	VS_OUTPUT Out;

	Out.Pos = mul(view_proj_matrix, Pos);

	Out.normal = normal;
	Out.viewVec = view_position - Pos;

	return Out;
}

float4 color: register(c0);

float4 PS_Plastic(float3 normal: TEXCOORD0, float3 viewVec: TEXCOORD1) : COLOR 
{
	float v = 0.5 * (1 + dot(normalize(viewVec), normal));

	return v * color;
}
Remove ads

Ссылки

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads