HLSL

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

Был создан корпорацией Microsoft и включён в пакет DirectX9.0

Содержание

Типы данных

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

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

  • bool - булев тип
  • int - 32 битовое знаковое целое
  • half - 16 битовое число с плавающей точкой
  • float - 32 битовое число с плавающей точкой
  • double - 64 битовое число с плавающей точкой

векторые типы

Пример: vector <float, 4> color;

Пример: float4 color;

Пример: float color[4]


матрицы

Пример: matrix <float, 4> view_matrix;

Пример: float 4x4 view_matrix;


структуры

Операторы

Операции Операторы
Арифметические -, +, *, /, %
Инкремент, декремент ++, --
Логические &&, или, ?:
Унарные !, -, +
Сравнения <, >, <=, >=, ==, !=
Назначение =, -=, +=, *=, /=
Привидение типов (тип)
Комма ,
Член структуры .
Член массива [индекс]

Ветвления

if (выражение) then <оператор> [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
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
floor(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
mul(a, b) делает матричное умножение между a и b
normalize(v) возвращает нормализированный вектор v
pow(x, y) возвращает xy
radians(x) конвертирует x из градусов в радианы
reflect(i, n) возвращает вектор отражения
refract(i, n, eta) возвращает вектор преломления.
rsqrt(x) возвращает 1 / sqrt(x)
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 – 2D текстурные координаты.
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 переменную. Например:

float4 value;

float4 main () : COLOR
{
  return value;
}

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

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

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


Примеры

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

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

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

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


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

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


имитация деревянной поверхности

float trunk_wobble_frequency;

float4x4 view_matrix;
float4x4 view_proj_matrix;

float4x4 texture_matrix0;
float4x4 texture_matrix1;
float4x4 texture_matrix2;

struct VS_OUTPUT
{
        float4 Pos     : POSITION;
        float3 TCoord0 : TEXCOORD0;
        float3 TCoord1 : TEXCOORD1;
        float3 TCoord2 : TEXCOORD2;
        float3 TCoord3 : TEXCOORD3;
        float3 TCoord4 : TEXCOORD4;
        float3 TCoord6 : TEXCOORD6;
        float3 TCoord7 : TEXCOORD7;
};


VS_OUTPUT VS_Wood (float4 vPosition: POSITION, float3 vNormal: NORMAL)
{
        VS_OUTPUT Out = (VS_OUTPUT) 0;
        float4 TransformedPshade;

        // Transform position to clip space
        Out.Pos = mul (view_proj_matrix, vPosition);

        // Transform Pshade (using texture matrices) and output to pixel shader
        TransformedPshade = mul (texture_matrix0, vPosition);
        Out.TCoord0 = TransformedPshade;
        Out.TCoord1 = mul (texture_matrix1, vPosition);
        Out.TCoord2 = mul (texture_matrix2, vPosition);

        // Create two coordinates for sampling noise volume to get wobble
        Out.TCoord3 = float3(trunk_wobble_frequency * TransformedPshade.z, 0.0f, 0.0f);
        Out.TCoord4 = float3(trunk_wobble_frequency * TransformedPshade.z + 0.5f, 0.0f, 0.0f);

        // Transform position and normal to eye space
        Out.TCoord6 = mul (view_matrix, vPosition);
        Out.TCoord7 = mul (view_matrix, vNormal);

        return Out;
}
float4 light_pos;
float4 eye_pos;
float4 light_wood_color;
float4 dark_wood_color;

float noise_amplitude;
float trunk_wobble_amplitude;
float ring_freq;

sampler noise_volume;
sampler pulse_train;
sampler variable_specular;

float4 PS_Wood (float3 Pshade0  : TEXCOORD0,
                                float3 Pshade1  : TEXCOORD1,
                                float3 Pshade2  : TEXCOORD2,
                                float3 zWobble0 : TEXCOORD3,
                                float3 zWobble1 : TEXCOORD4,
                                float3 Peye     : TEXCOORD6,
                                float3 Neye     : TEXCOORD7) : COLOR
{
        float3 coloredNoise;
        float3 wobble;

        // Construct colored noise from three samples
        coloredNoise.x = tex3D (noise_volume, Pshade0);
        coloredNoise.y = tex3D (noise_volume, Pshade1);
        coloredNoise.z = tex3D (noise_volume, Pshade2);

        wobble.x = tex3D (noise_volume, zWobble0);
        wobble.y = tex3D (noise_volume, zWobble1);
        wobble.z = 0.5f;

        // Make signed
        coloredNoise = coloredNoise * 2.0f - 1.0f;
        wobble       = wobble       * 2.0f - 1.0f;

        // Scale noise and add to Pshade
        float3 noisyWobblyPshade = Pshade0 + coloredNoise * noise_amplitude + wobble * trunk_wobble_amplitude;

        float scaledDistFromZAxis = sqrt(dot(noisyWobblyPshade.xy, noisyWobblyPshade.xy)) * ring_freq;

        // Lookup blend factor from pulse train
        float4 blendFactor = tex1D (pulse_train, scaledDistFromZAxis);

        // Blend wood colors together
        float4 albedo = lerp (dark_wood_color, light_wood_color, blendFactor.x);

        // Compute normalized vector from vertex to light in eye space  (Leye)
        float3 Leye = (light_pos - Peye) / length(light_pos - Peye);

        // Normalize interpolated normal
        Neye = Neye / length(Neye);

        // Compute Veye
        float3 Veye = -(Peye / length(Peye));

        // Compute half-angle
        float3 Heye = (Leye + Veye) / length(Leye + Veye);

        // Compute N.H
        float NdotH = clamp(dot(Neye, Heye), 0.0f, 1.0f);

        // Scale and bias specular exponent from pulse train into decent range
        float k = blendFactor.z;

        // Evaluate (N.H)^k via dependent read
        float specular = tex2D (variable_s
 
Начальная страница  » 
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 Home