HLSL

Материал из Seo Wiki - Поисковая Оптимизация и Программирование

Перейти к: навигация, поиск

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

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

Содержание

Типы данных

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

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

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

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

Пример: 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;


структуры

Операторы

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

Ветвления

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 Значение глубины

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

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

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

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

Примеры

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

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
Источник — «http://www.sbup.com/wiki/HLSL»
Личные инструменты

Served in 0.204 secs.