High Level Shader Language

Վիքիպեդիայից՝ ազատ հանրագիտարանից
High Level Shader Language
ԵնթադասՀամակարգչային ծրագիր և subroutine?

HLSL (անգլ.՝ High Level Shader Language) — C-բարձր կարգի ծրագրավորման լեզու։

Թողարկված է Microsoft ընկերության կողմից և աշխատում է DirectX 9.0 փաթեթում[1]։

Տվյալների տիպեր[խմբագրել | խմբագրել կոդը]

HLSL- ն աջակցում է սկալյար տեսակներ, վեկտորային տեսակ, մատրիցներ և կառուցվածքներ[2]։

Սկալյար տիպեր[խմբագրել | խմբագրել կոդը]

  • 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 ծրագրային ապահովումներում[3]։ Շարժվող պատկեր ստեղծելու համար պետք է հայտարարել 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 Արխիվացված 2015-06-17 Wayback Machine (անգլ.) // Руководство пользователя Blender.
  3. [1]