**HLSL** (անգլ.՝ High Level Shader 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;

### Կառուցվածքներ

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 и т. д. это сентиматики, о них ниже.
};

Օպերատորներ
-----------

| Գործողություններ | Օպերատորներ |
| --- | --- |
| Թվաբանական | -, +, \*, /, % |
| Ինկրեմենտ, նվազեցում | ++, -- |
| Տրամաբանական | \|, ?: |
| Ունար | !, -, + |
| Համեմատման | <, >, <=, >=, ==, != |
| Արժեքային | =, -=, +=, \*=, /= |
| Տեսակավորման | (տիպ) |
| Ստորակետ | , |
| Կառույցի տարր |. |
| Մասիվի տարր | [ինդեքս] |

Պայման
------

**if** (արտհյտություն) <օպերատոր> [**else** <օպերտոր>]

Ցիկլեր
------

HLSL կոդում տարբերում են ցիկլի երեք գրռումներ։

* **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)** | վերադարձնում է y- ի մասնակի ածանցյալը 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 փոփոխականներ, օրինակ.

```
float4 value;

float4 main () : COLOR
{
  return value;
}

```

2)Հայտարարել տվյալները uniform որոշիչի միջոցով, օրինակ.

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

```

Uniform փոփոխականները սահմանվում են հաստատուն աղյուսակում։ Հաստատուն աղյուսակը պարունակում է այն բոլոր ռեգիստորները, որոնք մշտապես օգտագործվում են shader- ում։

**Varying** — Տվյալներ, որոնք յուրահատուկ են յուրաքանչյուր shader կանչի համար։ Օրինակ։ դիրք, նորմալ և այլն։   

Հիմնական մուտքային semantic տիպեր։  


|  |  |
| --- | --- |
| BINORMAL | Binw8mal |
| BLENDWEIGHT | Քաշային հարաբերակցություն |
| BLENDINDICES | Քաշային մատրիցի ինդեքս |
| COLOR | - | NORMAL | Նորմալ |
| POSITION | Դիրք |
| PSIZE | Կետի չափսը |
| TANGENT | Տանգենտ |
| TESSFACTOR | Գործոն Տեսլական |
| TEXCOORD | Տեքստուրայի կոորդինատն |

Կիրառելով varying անցում է կատարվում այլ վիճակի.
Հիմնական մուտքային semantic տիպեր։

|  |  |
| --- | --- |
| COLOR | Գույն |
| TEXCOORD | Տեքստուրայի կոորդինատներ |

Մուտքային տվյալներ։

|  |  |
| --- | --- |
| POSITION | Դիրք |
| PSIZE | Կետի չափը |
| FOG | Ստվերային ֆոնի գործակից |
| COLOR | Գույն |
| TEXCOORD | Տեքստուրայի կոորդինատ |

Արտածման տվյալներ։

|  |  |
| --- | --- |
| COLOR | Գույն |
| DEPTH | Խորքային տվյալներ |

Օրինակներ
---------

### Պարզագույն շեյդեր «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 /\* Պիկսելային շեյդերը միշտ վերադարձնում են պատկերի գույնը
pixel- ը semantics- ի COLOR0 ձեւաչափով float4: Պատկերի յուրաքանչյուր պիքսելի համար կատարվում է պիքսելային ստվեր
պատկերի մակերեսին (և ոչ թե տեքստելի կառուցվածքների համար) \*/
{
 return tex2D( baseMap, texCoord ); /\* tex2d(sampler2D, float2) կարդում է 
տեքստուրայից նշված փիքսելի գույնը։ \*/
}

```

### պարզագույն շեյդեր «Գլխապտույտ»

```
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

```

Ծանոթագրություններ
------------------

1. ↑   Исходный код компилятора «oslc», библиотеки «liboslexec» и др. компонентов (անգլ.) // github.com. Компилятор «oslc» преобразует код OSL в промежуточный код, напоминающий язык ассемблера. Библиотека «liboslexec», используя LLVM, преобразует промежуточный код в машинный код для процессоров x86.
2. ↑  Open Shading Language Archived 2015-06-17 at the Wayback Machine. (անգլ.) // Руководство пользователя Blender.
3. ↑