OpenGL Shading Language/Procesor wierzchołków

Procesor wierzchołków odpowiedzialny jest za transformacje wierzchołków (ang. vertex). Dane, którymi manipulują programy dla niego, zwane vertex shaderami to współrzędne punktów, kolory, normalne, oraz ewentualne inne atrybuty definiowane i wysyłane przez konkretną aplikację OpenGL dla każdego wierzchołka w obrębie pojedynczego prymitywu.

Dla przykładu, poniższy fragment kodu źródłowego wysyła do procesora wierzchołków kolor i pozycję wierzchołków, które definiują trójkąt:

glBegin(GL_TRIANGLES);

    glColor3f(1.0f, 0.5f, 0.2f);
    glVertex3f(0.0, 1.0, 0.0);

    glColor3f(0.2f, 0.5f, 8.0f);
    glVertex3f(-1.0, -1.0, 0.0);

    glColor3f(0.0f, 0.5f, 1.0f);
    glVertex3f(1.0, -1.0, 0.0);

glEnd();

W vertex shaderze możesz pisać kod, który spełniałby na przykład poniższe zadania:

  • Transformowanie pozycji werteksów z użyciem matryc modelu widoku oraz projekcji
  • Transformacja normalnych, i jeżeli to konieczne, ich normalizacja
  • Generowanie koordynatów tekstur i ich transformacja
  • Obliczanie oświetlenia poszczególnych wierzchołków (w połączeniu z fragment shaderem można dokonywać obliczeń dla pojedynczych pikseli)
  • Obliczanie koloru

Nie trzeba wykonywać wszystkich operacji wymienionych powyżej, ale należy pamiętać o tym, że pisząc kod vertex shadera zastępuje się nim dotychczasową domyślną funkcjonalność OpenGL w zakresie operacji na wierzchołkach. Zatem konieczne jest zdefiniowanie całej funkcjonalności, która jest wymagana do poprawnego działania tworzonej aplikacji.

Należy pamiętać, że procesor werteksów nie ma pojęcia jak poszczególne wierzchołki łączą się tworząc prymityw. Dla przykładu procesor werteksów nie może być wykorzystany do usuwania niewidocznej geometrii. Operacje wykonywane są na każdym z wierzchołków osobno, bez żadnych informacji o pozostałych. Takie podejście pozwala na maksymalne zrównoleglenie obliczeń, a w konsekwencji przyspieszenie akceleracji sprzętowej.

Poprawnie napisany vertex shader powinien wykonać co najmniej jedną operację: zapisać wartość do zmiennej gl_Position, która definiuje ostateczne położenie wierzchołka przed procesem rasteryzacji. Jeśli program oczekuje jedynie standardowego przekształcenia przez macierz widoku modelu i rzutowania, to całą tę procedurę można wykonać wywołując standardową funkcję ftransform(), zatem najprostszy vertex shader, rzutujący model na ekran ma postać:

main() { gl_Position = ftransform(); }

Należy wspomnieć o tym, że procesor wierzchołków ma pełen dostęp do stanu OpenGL-a. Może więc, dla przykładu, wykonywać obliczenia z użyciem materiałów. Ma też dostęp do tekstur (jedynie w najnowszych kartach graficznych, zgodnych ze specyfikacją Shader Model 3.0 lub nowszą), które wraz z rozszerzeniem EXT_framebuffer_objects mogą służyć jako bufor ramki, drastycznie zwiększając zakres zastosowań technologii shaderów we współczesnych aplikacjach obliczeniowych – nie tylko graficznych (patrz GPGPU).