Shadery Artur Staszczyk www.astaszczyk.com Bartłomiej Filipek www.bartlomiejfilipek.pl Bartlomiej.filipek@gmail.com
Potok graficzny Vertex shader Fragment shader GLSL Przykłady Inne shadery?
Vertex shader Dane o wierzchołkach i atrybuty Obcinanie (clipping) Transformacje Oświetlenie?? Generacja współrzędnych tekstur oraz ich transformacje Pomysły artystów rasteryzacja
Fragment Shader Teksturowanie, łączenie kilku tekstur mgła Pomysły artystów Operacje na fragmentach jak testy głębi, alpha, blending, etc. Zapisz do bufora ramki gdy fragment zaakceptowany Antyaliasing
Pozycja gl_vertex Normalna gl_normal Współrzędne tekstur(y) Kolor gl_color Vertex Shader Obliczenia gl_position gl_frontcolor gl_texcoord[n] Stałe jak gl_modelviewmatrix, gl_lightsource*n+, stale od użytkownika, textury, bufory
Wykonywane dla każdego wierzchołka, wiec może byd wiele shaderów wykonywanych równolegle, dla kilku wierzchołków naraz! Może: Przekształcid wierzchołki z przestrzeni obiektu do przestrzeni obcinania (clip-space) Przekazad kolor, normalne i inne atrybuty do pixel shadera. Obliczyd współrzędne tekstur I wiele innych obliczeo. Minimum to ustawid wartośd dla gl_position Obliczone wartości (jak kolor, normale ) są interpolowane i przekazywane do fragment shader a
Fragment Shader gl_color gl_texcoord[n] Obliczenia gl_fragcolor gl_fragdata[] Stałe, gl_lightsource*n+, stale od użytkownika, etc
void main() { gl_fragcolor = gl_color; gl_fragcolor.g = 1.0; } gl_fragcolor minimum które trzeba wykonad w Pixel shaderze ustawid kolor fragmentu Gl_Color interpolowana wartośd pochodząca od gl_frontcolor ustawionej w vertex shaderze
Gdy już zdecydujemy się na użycie jakiegoś shadera to w całości musimy zastąpid dany etap potoku renderowania. Na przykład nie możemy tylko obliczyd pozycji wierzchołka i żądad od OpenGL a aby sam sobie policzył dla tego samego wierzchołka oświetlenie. Lub też obliczyd kolor w pixel shaderze i chcied aby mgła policzyła się sama.
aplikacja GPU dane
Język wysokiego poziomu Alternatywy: HLSL, CG
GLSL Version 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 OpenGL Version
Język bardzo podobny składniowo do C/C++, dlatego uczy się go bardzo szybko i sprawnie W związku z tym, że jest bardzo specjalizowany głównie skupiono się na łatwości obliczeo, mamy więc do dyspozycji multum funkcji matematycznych. na pewno nie ma umiejętności otwierania i zapisywania do pliku, czy wyrzucania wyjścia na konsole Gotowe klasy/struktury dla wektorów (vec2, vec3, vec4 ) i macierzy (mat2, mat3 ) wraz z wszelkimi operacjami na nich. Wbudowana obsługa czytania z tekstur za pomocą tzw. sampler a Instrukcje warunkowe i pętle, instrukcje break, continue, return Można pisad funkcje, tworzyd struktury. Specjalna instrukcja discard dla fragmentów, powoduje odrzucenie fragmentu i nie zapisanie go do bufora (*) Oczywiście można się komunikowad s shaderami i ustawiad im odpowiednie wartości z głównego naszego programu.
Uniform można ustawid przed narysowaniem geometrii obiektu, innymi słowy: stała dla konkretnego obiektu. Varying gdy ustawimy ją w vertex shaderze to fragment shader otrzyma tą wartośd, ale odpowiednio interpolowaną. Np. normal, position, etc Attrib (dla wierzchołków) atrybut dla pojedynczego wierzchołka jak gl_color, gl_normal Const stała na potrzeby wewnętrzne shadera Bez kwalifikatora zmienna zwykła globalna lub lokalna.
void InitShaders() { GLint vertex_shader = glcreateshader(gl_vertex_shader); GLint fragment_shader= glcreateshader(gl_fragment_shader); char *vs = ReadAllTextFromFile("shaders/basic.vert"); char *fs = ReadAllTextFromFile("shaders/basic.frag"); const char * vv = vs; const char * ff = fs; glshadersource(vertex_shader, 1, &vv,null); glshadersource(fragment_shader, 1, &ff,null); glcompileshader(vertex_shader); glcompileshader(fragment_shader);...... }
Glint shader_program = glcreateprogram(); glattachshader(shader_program, vertex_shader); glattachshader(shader_program, fragment_shader); gllinkprogram(shader_program); GLint timeelapsed = glgetuniformlocation(shader_program, "time"); Glint texture = glgetuniformlocation(shader_program, "texture"); glbindtexture(gl_texture_2d, gtexsample); gluniform1i(texture, 0);
gluseprogram(0); gldeleteprogram(shader_program);
void printshaderinfolog(gluint obj) { int infologlength = 0; int charswritten = 0; char *infolog; glgetshaderiv(obj, GL_INFO_LOG_LENGTH, &infologlength); } if (infologlength > 0) { infolog = (char *)malloc(infologlength); glgetshaderinfolog(obj, infologlength, &charswritten, infolog); printf("%s\n",infolog); free(infolog); }
glgetprogramiv(p, GL_LINK_STATUS, &success); if (!success) { int infologlength = 0; int charswritten = 0; char *infolog; } glgetprogramiv(p, GL_INFO_LOG_LENGTH, &infologlength); if (infologlength > 0) { infolog = (char *)malloc(infologlength); glgetprograminfolog(p, infologlength, &charswritten, infolog); utlog_error("error in building program! \n%s",infolog); free(infolog); return false; }
Jak to wygląda w kodzie? Projekt: Basic_shaders
130/330 core profile Nie ma predefinowanych uniformów od OpenGL Nie ma varying i attribute
Inne shadery? Compute Shader lighthouse3d.com//opengl-4-1-pipeline/
https://www.opengl.org/registry/ www.lighthouse3d.com/tutorials/glut-tutorial/ opengl.org/sdk/docs/man3 www.opengl.org/documentation/specs openglbook.com - darmowa książka o nowoczesnym OpenGL www.arcsynthesis.org/gltut/ - darmowa książka o nowoczesnym OpenGL www.songho.ca/opengl/gl_vbo.html - tutorial o VBO
Artur Staszczyk www.astaszczyk.com Bartłomiej Filipek www.bartlomiejfilipek.pl Bartlomiej.filipek@gmail.com