Programi za sjenčanje (vertex shaders)
Shader je, jednostavno rečeno, program koji se koristi za sjenčanje – proizvodnju odgovarajućih razina svjetlosti i boje na slici, kao i za proizvodnju specijalnih efekata ili post-procesiranje (postprocessing). Većina shadera se programira za grafičku karticu. Sjenčanje se obično dijeli na:
- sjenčanje vrhova (vertex shaders)
- sjenčanje geometrije (geometry shaders)
- sjenčanje fragmenata (fragment shaders)
U prethodnom poglavlju, na slici grafičkog cjevovoda, je vidljivo da se sjenčanje vrhova obavlja na početku. Programi za sjenčanje vrhova (vertex shaders) jesu specijalne funkcije koje se koriste za manipulaciju podataka o vrhu (pozicija, boja i sl.) koristeći matematičke operacije. Tipični primjeri programa za sjenčanje vrhova su magla, motion blur i sl. Vertex shader radi na pojedinačnim vrhovima, obrađujući vrhove jedan po jedan. Shader nema znanje o drugim vrhovima od kojih su sastavljeni grafički primitivi. Za svaki ulazni vrh, shader daje jedan izlazni vrh. U računalnoj grafici postoje dva smjera jezika za sjenčanje:
- iscrtavanje posrednim režimom – slike su velike kvalitete, vrijeme računanja pojedine slike nije ograničavajući faktor (koriste se za fotorealistične slike i scene)
- iscrtavanje u stvarnom vremenu – slike se računaju više puta u sekundi. Nastali su kako bi se postigla veća kontrola nad radom grafičkog cjevovoda u grafičkim karticama.
U ovom radu će se detaljnije obrađivati iscrtavanje u stvarnom vremenu. U tom smjeru su najpoznatiji programski jezici HLSL (High Level Shading Language), koji je razvio Microsoft u suradnji sa nVidiom te GLSL (OpenGL Shading Language). HLSL programi se koriste jedino iz DirectX okruženja. Primjer vertex shadera ćemo detaljnije razraditi na GLSL-u. GLSL se nalazi u OpenGL jeziku od verzije 2.0.
GLSL Vertex Shader
Kao što je prije navedeno, vertex shader se nalazi na početku cjevovoda te obrađuje pojedinačne vrhove, jedan po jedan.
Varijable koje se definiraju u vertex shaderu se mogu nazvati atributima. Predstavljaju vrijednosti koje aplikacija često prosljeđuje procesoru vrhova.
Budući da se ovaj tip varijable koristi samo za podatke od aplikacije koji definiraju vrhove, dozvoljeni su samo kao dio vertex shadera.
Dva su tipa varijabli atributa: ugrađeni te korisnički. Standardne vrijednosti atributa uključuju boju, normale, koordinate tekstura i slično.
Uz korisnički definirane varijable GLSL definira i set atributa po vrhu:
in int gl_VertexID; in int gl_InstanceID;gl_VertexID se odnosi na indeks vrha u nizu atributa. Kada se koriste instance shader se izvršava n puta po ulaznom vrhu, gdje je n broj specificiranih instanci u glDraw* OpenGL rutini. Varijabla gl_InstanceID govori indeks instance te je uvijek nula ukoliko se ne koriste instance. Vertex shader prima ulazne atribute te izlazne vrhove, računajući njihove atribute. Sljedeći izlazni atributi su dostupni za pisanje u vertex shaderu:
out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; };Pisanje bilo kojih od ovih atributa je opcionalno. Shader može kao izbaciti korisnički definirane varijable po vrhu (ver vertex variables).
layout (std140) uniform Matrices { mat4 projModelViewMatrix; mat3 normalMatrix; }; in vec3 position; in vec3 normal; in vec2 texCoord; out VertexData { vec2 texCoord; vec3 normal; } VertexOut; void main() { VertexOut.texCoord = texCoord; VertexOut.normal = normalize(normalMatrix * normal); gl_Position = projModelViewMatrix * vec4(position, 1.0); }U gore navedenom primjeru vertex shader prima tri korisnički definirana atributa po vrhu: position, normal i texCoord. Prima uniformni blok nazvan Matrices koji sadrži dvije zajedničke matrice za transformaciju normale i vrha. Izlazi vertex shadera su korisnički definirani atributi texCoordOut i normal te atribut gl_Position.
Važno je primjetiti da se izlazne varijable također nalaze u zatvorenom bloku. Izlazi se računaju u main funkciji. Svaki tip shadera mora imati main funkciju i može definirati ostale pomoćne funkcije, slično kao i bilo koji drugi C program.
Usporedba programa sa i bez GLSL: