Přeskočit na obsah

OpenGL Shading Language

Z Wikipedie, otevřené encyklopedie

OpenGL Shading Language(zkráceněGLSLnebo takéGLslang) jevyšší programovacíjazyk pro psaní shaderů,který vychází ze syntaxejazyka Cprovšeobecné použití.Jazyk GLSL byl vytvořen konsorciemOpenGL ARB.

Jazyk vznikl v rámci procesu postupné transformacefixního vykreslovacího řetězcenařetězec programovatelnýa stal se jednou z vyspělejších alternativ k tehdy používanýmnižším programovacím jazykůmpro psaní shaderů.

Nová funkcionalita (nebo funkcionalita specifická pro určitého výrobce čihardware) je do GLSL často doplňována nejprve v podobě tzv. rozšíření (např. podpora geometry shaderu), které je třeba vkóduexplicitně aktivovata v pozdějších verzích se významná rozšíření stávají součástí funkcionality základní.

Tabulka shrnující jednotlivé verze OpenGL a příslušné verze GLSL, které byly v rámci dané specifikace představeny:[1]

Verze GLSL Verze OpenGL
1.10.59 2.0
1.20.8 2.1
1.30.10 3.0
1.40.08 3.1
1.50.11 3.2
3.30.6 3.3
4.00.9 4.0
4.10.6 4.1
4.20.6 4.2

Jazyk GLSL poskytuje operátory známé zjazyka C.Výjimku tvoří operátory související sukazateli,které nejsou v jazyce GLSL podporovány. V prvních verzích rovněž nebylo možné používatbitové operátory— jejich podpora byla zavedena ve verzi 1.30.[2]Oproti jazyku C je navíc k dispozici speciální operátorswizzle.

Datové typy

[editovat|editovat zdroj]

GLSL podporujeskalárnídatové typyjazyka C. Lze použít i datový typvoidovšem pouze jako typ návratové hodnotyfunkcí.Podporastrukturapolíumožňuje tvorbuuživatelských datových typů.

Skalární typy

[editovat|editovat zdroj]
  • bool— pravdivostní datový typ (true/false)
  • int— 32bit,celé číslose znaménkem
  • uint— 32bit, celé číslo bez znaménka
  • float— 32bit, číslo s plovoucí desetinnou čárkou
  • double— 64bit, číslo s plovoucí desetinnou čárkou a dvojnásobnou přesností

Vektorové typy

[editovat|editovat zdroj]

Vektorje homogenní datový typ. GLSL má vestavěnou podporu pro jedno- až čtyř-složkové vektory. Název vektorového datového typu (např.dvec4) se skládá zprefixučásti "vec" asufixu.Prefix určuje datový typ složek vektoru[p 1]a sufix určuje jejich počet. Příklad použití (včetně inicializace):

vec4color0=vec4(1.0,0.0,0.0,0.0);

K jednotlivým složkám vektoru lze pak přistupovat pomocí definovaných složek x, y, z a w (např.color0.x = 0.5;).[3]

GLSL poskytuje podporu pro práci s maticemi o rozměrech 2x2 až 4x4, přičemž matice nemusí být pouze čtvercová (k dispozici jsou všechny kombinace uvedených rozměrů). Názvy maticových datových typů jsou tvořeny obdobně jako u vektorů — název začínáprefixemnásleduje část "mat" a je ukončensufixem.Prefix určuje datový typ prvků matice[p 1]a sufix určuje rozměr matice (např. mat3x4; u čtvercových matic je použit zkrácený zápis např. mat3 pro matici o rozměrech 3x3). Příklad použití (včetně inicializace):

K jednotlivým prvkům matice přistupujeme obdobně jako k prvkůmpolev jazyce C:[3]

mat3matrix;
matrix[1]=vec3(3.0,3.0,3.0);
matrix[2][0]=16.0;

Další datové typy

[editovat|editovat zdroj]

GLSL nabízí i tzv.opaque(českyněkdy též "transparentní" )datové typy.Opaque datový typ je ve skutečnosti pouzehandler(handle) na nějaký jiný objekt. Přístup k takovému objektu probíhá přes sadu vestavěnýchfunkcí(přímé čtení či zápis hodnotyproměnnétakového typu není možné). Při deklaraci jednoho opaque datového typu jsou ve skutečnosti deklarovány objekty dva, handler samotný i vnitřní objekt ke kterému handler přistupuje. Deklarace těchto typů je možná pouze na některých místech kódu — typicky bývají deklarovány např. jako parametry funkcí.[4]

Do kategorie opaque datových typů spadají v GLSL tzv.Samplery(např.sampler2D) a jedná se o handler k jedno-, dvou- či tří-rozměrnétextuře,hloubkové textuře, cube-mapě apod.

Imageje další třídou opaque datových typů (např.image1D,image2D,image2DMSa další). jedná se o handler k jedno-, dvou- či tří-rozměrnému obrázku (image), které se používají pro načítání či ukládánísouborůobsahujících statický obraz (případně pro další atomické operace).

Řídící struktury a funkce

[editovat|editovat zdroj]

Jazyk GLSL využívá stejnou konstrukciřídících struktur(větvení, cyklů, skoků) afunkcíjako jazyk C. Kromě podpory uživatelských funkcí disponuje GLSL i sadou funkcí vestavěných. Některé z nich jsou podobné funkcím jazyka C (zejména matematickým) — např. funkce exp() nebo abs(), zatímco jiné jsou určeny speciálně pro práci s grafikou — např. smoothstep() nebo texture2D().

Direktivy preprocesoru

[editovat|editovat zdroj]

Pro řízení předzpracovánízdrojového kódu,je k dispozici sadapreprocesorovýchdirektiv známých zjazyka C.Navíc jsou k dispozici speciální direktivy#versiona#extension.[4]

Direktiva version

[editovat|editovat zdroj]

Direktiva#versionse musí nacházet na začátku každého zdrojového souboru a určuje verzi GLSL, která bude při překladu použita.

#version 150

Direktiva extension

[editovat|editovat zdroj]

Chování GLSL lze dále ovlivnit pomocí tzv.rozšíření OpenGL(OpenGL extensions). Tato rozšíření lze řídit právě pomocí direktivy#extension:

#extension jmeno_rozsireni: chovani

Kde položka "jmeno_rozsireni" definuje název konkrétního rozšíření nebo nabývá hodnoty "all" chceme-li pracovat se všemi rozšířeními. Dané rozšíření lze v části "chovani" povolit nebo zakázat a dále pak definovat chování v případě, kdy rozšíření není dostupné.

Komentáře lze zapisovat ve stejném formátu jako v jazycích C,C++.

/* krátká verze */
// celořádková verze

Proces překladu

[editovat|editovat zdroj]

Kód shaderu může být umístěn v samostatnémsouborunebo jakotextový řetězecv rámci hlavního programu. Vlastnípřekladprobíhá až za běhu aplikace. Nejprve je třeba vytvořitshader objekta definovat jeho typ (např. GL_VERTEX_SHADER) voláním OpenGL funkceglCreateShader().Vlastní překlad je vyvolán funkcíglCompileShader()(jako parametr je předán řetězec s kódem shaderu). Dalším krokem jesestavenípřeložených shaderů ve výsledný program. Opět je nejprve nutné vytvořit speciálníobjekt programfunkcíglCreateProgram().Následuje připojení přeložených shader objektů —glAttachShader()a potom již vlastní proces linkování —glLinkProgram(),v rámci kterého dochází rovněž k mapování proměnných hlavního programu a proměnných GLSL shaderů.[5]

Ukázka vertex shaderu

[editovat|editovat zdroj]

Uvedený vertex shader realizuje stejnou transformaci vstupu jakofixní vykreslovací řetězec.

#version 120

voidmain(void)
{
gl_Position=ftransform();
}

Použitá funkceftransform()není od verze GLSL 1.40 dostupná. Při použití novější specifikace GLSL musíprogramátormísto použití této funkce explicitně vykonatnásobenívertexuprojekčníamodelviewmaticí.

#version 140

uniformTransformation
{
mat4projection_matrix;
mat4modelview_matrix;
};

invec3vertex;

voidmain()
{
gl_Position=projection_matrix*modelview_matrix*vec4(vertex,1.0);
}

Ukázka geometry shaderu

[editovat|editovat zdroj]

Následujícíkódrealizuje jednoduchý průchozí geometry shader pro barvu a pozici vertexu.

#version 120
#extension GL_EXT_geometry_shader4: enable

voidmain()
{
for(inti=0;i<gl_VerticesIn;++i)
{
gl_FrontColor=gl_FrontColorIn[i];
gl_Position=gl_PositionIn[i];
EmitVertex();
}
}

Od verze GLSL 1.50 nejsou již geometry shadery rozšířením, ale staly se součástí základní funkcionality GLSL. V souvislosti s tím došlo i k mírné změněsyntaxe.

#version 150

layout(triangles)in;
layout(triangle_strip,max_vertices=3)out;

voidmain()
{
for(inti=0;i<gl_in.length();i++)
{
gl_Position=gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}

Ukázka fragment shaderu

[editovat|editovat zdroj]

Jednoduchý shader, jehož výstupem bude fragment červené barvy.

#version 120

voidmain(void)
{
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}

Při použití specifikace GLSL 1.30 nebo pozdější je třeba shader upravit.

#version 150

outvec4MyFragColor;
voidmain(void)
{
MyFragColor=vec4(1.0,0.0,0.0,1.0);
}

V hlavním programu je potřeba provést navázání proměnné:

glBindFragDataLocation(Program,0,"MyFragColor");

kde:

  • Program— handler použitého shader programu
  • 0— index barvového bufferu
  • "MyFragColor"— uživatelsky definovaný název barvového bufferu

Ukázka Tessellation control shaderu

[editovat|editovat zdroj]

Příklad tessellation control shaderu pracujícího strojúhelníky.[6]

#version 400

layout(vertices=3)out;
invec3vPosition[];
outvec3tcPosition[];
uniformfloatTessLevelInner;
uniformfloatTessLevelOuter;

voidmain()
{
tcPosition[gl_InvocationID]=vPosition[gl_InvocationID];
if(gl_InvocationID==0)
{
gl_TessLevelInner[0]=TessLevelInner;
gl_TessLevelOuter[0]=TessLevelOuter;
gl_TessLevelOuter[1]=TessLevelOuter;
gl_TessLevelOuter[2]=TessLevelOuter;
}
}

Ukázka Tessellation evaluation shaderu

[editovat|editovat zdroj]

Příklad tessellation evaluation shaderu pracujícího s trojúhelníky.[6]

#version 400

layout(triangles,equal_spacing,cw)in;
invec3tcPosition[];
outvec3tePosition;
outvec3tePatchDistance;
uniformmat4Projection;
uniformmat4Modelview;

voidmain()
{
vec3p0=gl_TessCoord.x*tcPosition[0];
vec3p1=gl_TessCoord.y*tcPosition[1];
vec3p2=gl_TessCoord.z*tcPosition[2];
tePatchDistance=gl_TessCoord;
tePosition=normalize(p0+p1+p2);
gl_Position=Projection*Modelview*vec4(tePosition,1);
}
  1. abU názvů datových typů (vektorů a matic) jejichž složky jsou typu float, se prefix v neuvádí.

V tomto článku byl použitpřekladtextu z článkuGLSLna anglické Wikipedii.

Související články

[editovat|editovat zdroj]
Ostatní jazyky pro psaní shaderů

Externí odkazy

[editovat|editovat zdroj]
IDE
Příklady a ukázky