A GLSL programozási nyelv

Szabványos könyvtárak

Beépített változók és konstansok

A shaderek-nek kommunikálnia kell az OpenGL csővezeték nem programozható részeivel és más shaderek-kel is. A nyelv beépítetten rengeteg változót kínál, amelyekkel bejövő adatokat lehet fogadni vagy kimenő adatokat lehet küldeni.

Minden shader típusban más beépített változók használhatóak. Néhány példa:

in int gl_VertexID; in vec4 gl_FragCoord; in vec4 gl_Color; out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; };

A nyelv több beépített konstanst is tartalmaz, amelyek bármely shaderben használhatóak. A konstansok értékei implementáció függőek, de értékük legalább annyi, mint a meghatározott érték. Néhány példa:

const int gl_MaxVertexAttribs = 16; const int gl_MaxVertexOutputComponents = 64; const int gl_MaxViewports = 16;

További beépített változók és konstansok leírása a nyelv specifikációjában található: GLSL 4.2 specifikáció

Beépített függvények

A nyelvben számos beépített függvény szerepel különböző műveletekhez. Legtöbbjük több típusú shader-ben is használható, de vannak olyanok is, amelyek csak egy adott shader-ben használhatóak.

A beépített függvények három fő csoportba tartoznak:

Az alkalmazásokban ajánlott használni a beépített függvényeket a saját függvények helyett, mivel optimalizáltak. A beépített függvények újradeklarálhatóak ugyanazzal a névvel és argumentumlistával. Néhány példa:

float radians (float degrees); // fokot radiánba vált float sin (float angle); // egy szög sin-a float pow (float x, float y); // x hatványozása az y kitevőre float abs (float x); // x abszolútértékét adja vissza vec3 normalize (vec3 x); // x normál vektorát adja vissza mat2 inverse (mat2 m); // m inverzét adja vissza
Az alábbi függvények deklarációjában a genType float, vec2, vec3, vagy vec4 típusnak felel meg. genIType az egész értékű változatot, genUType az előjel nélkülit, genBType a bool, genDType pedig a double változatokat jelöli.s

Szög és trigonometriai függvények

Ahol a függvény egy szöget vár paramétereként azt radiánban kell megadni. Semmilyen esetben sem történik 0-val való osztás esetén hiba, ezesetben az eredmény nem definiált.

genType radians (genType degrees) // a megadott fokot radiánban adja vissza genType degrees (genType radians) // a megadott radián értéket fokban adja vissza genType sin (genType angle) // az általános szinusz függvény genType cos (genType angle) // az általános koszinusz függvény genType tan (genType angle) // az általános tangens függvény genType asin (genType x) // az általános arkusz szinusz függvény // visszadja azt a szöget amelynek a szinusza // az eredmény nem definiált |x| > 1 esetén genType acos (genType x) // az általános arkusz koszinusz függvény // visszadja azt a szöget amelynek a koszinusza x // az eredmény nem definiált |x| > 1 esetén genType atan (genType y, genType x) // az általános arkusz tangens függvény // visszadja azt a szöget amelynek a tangense x/y // az eredmény nem definiált ha x és y is 0 genType atan (genType a) // visszadja azt a szöget amelynek a tangense a genType sinh (genType x) // az általános hiperbolikus szinusz függvény genType cosh (genType x) // az általános hiperbolikus koszinusz függvény genType tanh (genType x) // az általános hiperbolikus tangens függvény genType asinh (genType x) // a sinh inverze genType acosh (genType x) // a cosh inverze, nem definiált x < 1-re genType atanh (genType x) // a tanh inverze, nem definiált |x| > 1-re

Exponenciális függvények

genType pow (genType x, genType y) // visszadja x-nek az y-adik hatványát // nem definiált x < 0 vagy x = 0 és y <= 0 esetekben genType exp (genType x) // visszadja az e szám x-edik hatványát genType log (genType x) // visszadja x természetes alapú logaritmusát, // x <= 0 esetben nem definiált genType exp2 (genType x) // 2 x-edik hatványat adja vissza genType log2 (genType x) // x-nek a 2-es alapú logaritmusát adja vissza, // x <= 0 esetben nem definiált genType sqrt (genType x) // x négyzetgyökét adja vissza, x < 0 esetben nem definiált genDType sqrt (genDType x) genType inversesqrt (genType x) // x inverz négyzetgyökét adja vissza, // x <= 0 esetben nem definiált genDType inversesqrt (genDType x)

Általános függvények

// x abszolútértékét adja vissza genType abs (genType x) genIType abs (genIType x) genDType abs (genDType x) // x előjelét adja vissza, értéke 1.0, ha x pozitív, // 0.0 ha x 0, -1.0 ha x negatív genType sign (genType x) genIType sign (genIType x) genDType sign (genDType x) // x-nek az egészértékét adja vissza genType floor (genType x) genDType floor (genDType x) // x abszolútértékéhez tartozó legközelebbi egész szám abszolút értékét adja vissza genType trunc (genType x) genDType trunc (genDType x) // x egeszre való kerekítését adja vissza genType round (genType x) genDType round (genDType x) // x paráos egészre való kerekétését adja vissza // pl. 3.5 és 4.5 bemenetre 4.0 lesz az eredmény genType roundEven (genType x) genDType roundEven (genDType x) // a legközelebbi x-nél nagyobb egész számot adja vissza genType ceil (genType x) genDType ceil (genDType x) // x – floor (x) genType fract (genType x) genDType fract (genDType x) // modulus, x – y * floor (x/y) genType mod (genType x, float y) genType mod (genType x, genType y) genDType mod (genDType x, double y) genDType mod (genDType x, genDType y) // mint a mod, csak i kimeneti paraméter a egész értékű osztás eredménye lesz genType modf (genType x, out genType i) genDType modf (genDType x, out genDType i) // x és y közül a kisebb lesz az eredménye genType min (genType x, genType y) // x és y közül a nagyobb lesz az eredménye genType max (genType x, genType y) // min (max (x, minVal), maxVal) genType clamp (genType x, genType minVal, genType maxVal) // x*(1−a)+y*a genType mix (genType x, genType y, genType a) // 0.0, ha x < edge, különben 1.0 genType step (genType edge, genType x) // 0.0, ha x <= edge0 és 1.0 ha x >= edge1 // edge0 < x < edge1 esetében pedig 0 és 1 közötti Hermite interpoláció genType smoothstep (genType edge0, genType edge1, genType x) genBType isnan (genType x) // igaz, ha x NaN genBType isinf (genType x) // igaz, ha x végtelen // olyan integerrel tér vissza amelynek értéke a megadott float változót tartalmazza genIType floatBitsToInt (genType value) genType intBitsToFloat (genIType value) // mint az előző, csak fordítva genType fma (genType a, genType b, genType c) // a*b+c // x=s*2^exp, s a visszatérési érték és [0.5, 1.0) intervallumba esik genType frexp (genType x, out genIType exp) genType ldexp (genType x, in genIType exp) // s*2^exp-el tér vissza

Lebegőpontos csomagoló és kicsomagoló műveletek

Az alábbi függvények a következőt csinálják: Átkonvertálják minden komponensét v-nek 8 vagy 16 bites egészekre, majd ezeket egy 32 bites előjel nélküli egészbe rakja össze.
uint packUnorm2x16 (vec2 v) uint packSnorm2x16 (vec2 v) uint packUnorm4x8 (vec4 v) uint packSnorm4x8 (vec4 v)
A fentebbi műveletek fordítottját a következő függvények végzik:
vec2 unpackUnorm2x16 (uint p) vec2 unpackSnorm2x16 (uint p) vec4 unpackUnorm4x8 (uint p) vec4 unpackSnorm4x8 (uint p)
Kétszeres pontosságú lebegőpontos szám előállítása egy 2 dimenziós vektorból valamint fordítva:
double packDouble2x32 (uvec2 v) uvec2 unpackDouble2x32 (double v)
2 dimenziós lebegőpontos vektorból 32 bites előjel nélkül integer előállítása és fordítva:
uint packHalf2x16 (vec2 v) vec2 unpackHalf2x16 (uint v)

Geometriai műveletek

// x vektor hossza: sqrt(x[0]^2 + x[1]^2...) float length (genType x) // p0 és p1 közötti távolság, length(p0-p1) float distance (genType p0, genType p1) float dot (genType x, genType y) // x és y skaláris szorzata vec3 cross (vec3 x, vec3 y) // x és y 3D-s vektorok vektoriális szorzata // x normalizáltjával tér vissza(ugyanolyan irányú mint x, csak 1 hosszúságú) genType normalize (genType x) // ha dit(Nref, I) < 0, akkor N-el, különben -N-el tér vissza genType faceforward (genType N, genType I, genType Nref) // I beesési vektor, és N felület orientációra a tülrüződést adjva vissza, I-2*dot(N,I)*N genType reflect (genType I, genType N) // mint ez előbbi, csak eta a fénytörési mutató genType refract (genType I, genType N, float eta)

Mátrix műveletek

A következő mátrixműveletek mind egyszeres és kétszeres pontosságű lebegőpontos számokat tartalmaző mátrixokra valamint különböző méretű mátrixokra is értelmezve vannak.

mat matrixCompMult (mat x, mat y) // x és y elemeit komponensenként szorozza össze mat2 outerProduct (vec2 c, vec2 r) // c mátrix elemeit egy oszlopnak véve, // r mátrix elemeit pedig egy sornak véve elvégzi // a lineáris algebrából ismert c * r mátrixszszorzást mat2 transpose (mat2 m) // a bemeneti m mátrix transzponáltjával tér vissza float determinant (mat2 m) // a bemeneti m mátrix determinánsával tér vissza mat2 inverse (mat2 m) // a bemeneti m mátrix inverzével tér vissza

Vectorok relációs műveletei

Skaláris típusokra a relációs operátor mind értelmezve vannak. Vektorok elemenkénti összehasonlítására az alábbi beépített függvényeket használhatjuk.

bvec lessThan (vec x, vec y) // x < y bvec lessThanEqual (vec x, vec y) // x <= y bvec greaterThan (vec x, vec y) // x > y bvec greaterThanEqual (vec x, vec y) // x >= y bvec equal (vec x, vec y) // x == y bvec notEqual (vec x, vec y) // x != y bool any (bvec x) // igaz, ha x legalabb egy eleme igaz bool all (bvec x) // igaz, ha x minen eleme igaz bool not (bvec x) // igaz, ha x minden eleme hamis

Egészekkel végezhető műveletei

// (x+y) mod 2^32, carry 1, ha az osszeg nagyobb 2^32-nél genUType uaddCarry (genUType x, genUType y,out genUType carry) // x-y, ha ez nem negatív, különben ehhez még hozzáad 2^32-t és borrow értéke 1 lesz genUType usubBorrow (genUType x, genUType y, out genUType borrow) // x és y 32 bites egészek szorzása, az eredmény alsó része lsb-be, míg a felső része msb-be kerül bele void umulExtended (genUType x, genUType y, out genUType msb, out genUType lsb) void imulExtended (genIType x, genIType y, out genIType msb, out genIType lsb) // bitenkénti kivonás a következő módon: [offset, offset + bits - 1], az alsó bitekkel tér vissza genIType bitfieldExtract (genIType value, int offset, int bits) genUType bitfieldExtract (genUType value, int offset, int bits) // insert-ből az alsó bits-et beleilleszi base-be genIType bitfieldInsert (genIType base, genIType insert, int offset, int bits) genUType bitfieldInsert (genUType base, genUType insert, int offset, int bits) // visszatér a bitek megfordított sorrendjéból adódó értékkel genIType bitfieldReverse (genIType value) genUType bitfieldReverse (genUType value) // 1 értékű biteg számával tér vissza genIType bitCount (genIType value) genIType bitCount (genUType value) // 1 értékű bitek száma az alső részben genIType findLSB (genIType value) genIType findLSB (genUType value // 1 értékű bitek száma a felső részben genIType findMSB (genIType value) genIType findMSB (genUType value)

Atomi számláló műveletek

A számlálót egy 32 bites előjel nélküli egész ábrázolja, ebből következendően az értéke a [0, 2^32-1] tartományba esik.

// megnoveli a c számláló értékét, majd visszatér növelés elötti értékkel uint atomicCounterIncrement (atomic_uint c) // csökkenti a c számláló értékét, majd visszatér az előző értékével uint atomicCounterDecrement (atomic_uint c) // visszatér c számláló értékével uint atomicCounter (atomic_uint c)

Atomi memóriaműveletek

Az atomi memóriaműveletek atomi műveletet végeznek egy előjeles vagy előjel nélküli egészértéken, amely a buffer-objektumban vagy a megosztott tárolón van. Minden ilyen művelet kiolvassa az értéket a memóriából, kiszámolja az új értékét, majd beleírja a memóriába, valamint a kiolvasott értékkel tér vissza.

// data értéket hozzáadja, a mem tartalmához uint atomicAdd (inout uint mem, uint data) int atomicAdd (inout int mem, int data) // mem tartalma és a data értéke közül a kisebb lesz az új érték uint atomicMin (inout uint mem, uint data) int atomicMin (inout int mem, int data) // mem tartalma és a data értéke közül a nagyobb lesz az új érték uint atomicMax (inout uint mem, uint data) int atomicMax (inout int mem, int data) // mem tartalma és data értékén végzett bitenkénti ÉS művelet éesz az új érték uint atomicAnd (inout uint mem, uint data) int atomicAnd (inout int mem, int data) // mem tartalma és data értékén végzett bitenkénti VAGY művelet éesz az új érték uint atomicOr (inout uint mem, uint data) int atomicOr (inout int mem, int data) // mem tartalma és data értékén végzett bitenkénti KIZÁRÓ VAGY művelet éesz az új érték uint atomicXor (inout uint mem, uint data) int atomicXor (inout int mem, int data) // data lesz az új érték uint atomicExchange (inout uint mem, uint data) int atomicExchange (inout int mem, int data) // összehasonlítja compare értékét a mem tartalmával, ha egyenlőek data lesz az új érték uint atomicCompSwap (inout uint mem, uint compare, uint data) int atomicCompSwap (inout int mem, int compare, int data)

Fragment shader függvények

Ezeket a függvényeket csak a fragment shaderekben tudjuk használni.

Deriválás
Ezezek a függvények a valódi derivált közelítő értékét számolják ki, gyorsak, viszont nem teljesen pontosak.
// p argumentum x szerinti deriváltját számolja ki genType dFdx (genType p) // p argumentum y szerinti deriváltját számolja ki genType dFdy (genType p) // p argumentum x és y szerinti deriváltjainak összegét adja meg genType fwidth (genType p)
Interpolációs műveletek
Interpolációs műveleteket a következő függvények segítségével végezhetjük el.
float interpolateAtCentroid (float interpolant) float interpolateAtSample (float interpolant, int sample) float interpolateAtOffset (float interpolant, vec2 offset)

Geometry shader függvények

Ezeket a függvényeket csak a geometry shaderekben tudjuk használni.

float interpolateAtCentroid (float interpolant) float interpolateAtSample (float interpolant, int sample) float interpolateAtOffset (float interpolant, vec2 offset)
// A kimenő változók aktuális értékét az megadott kimenő folyamra írja. void EmitStreamVertex (int stream) // Befejezi az aktuális primitívet és egy újat kezd. void EndStreamPrimitive (int stream) // A kimenő változók aktuális értékét az aktuális kimenő primitívbe írja. void EmitVertex () // Befejezi az aktuális primitív számítását és újat kezd. void EndPrimitive ()

További beépített függvények leírása a nyelv specifikációjában található: GLSL 4.2 specifikáció