High Level Shader Language

Վիքիպեդիայից՝ ազատ հանրագիտարանից
Jump to navigation Jump to search

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