Vertex Shader to programowalny etap potoku graficznego (graphics pipeline), który przetwarza każdy wierzchołek modelu trójwymiarowego. Według Khronos Group, 2025, shader wierzchołków przyjmuje na wejściu atrybuty wierzchołków — współrzędne, normalne, kolor i współrzędne tekstury — i przekształca je zgodnie z zadaną logiką. Vertex Shader jest wykonywany dla każdego wierzchołka niezależnie, co pozwala efektywnie zrównoleglać obliczenia na tysiącach rdzeni GPU.
Najważniejsze
Vertex Shader to programowalny etap potoku graficznego (graphics pipeline), który przetwarza każdy wierzchołek modelu trójwymiarowego osobno. Wierzchołek (vertex) to punkt w przestrzeni trójwymiarowej zawierający atrybuty: współrzędne xyz, normalne, kolor i współrzędne tekstury UV.
W przeciwieństwie do potoku stałego (fixed-function pipeline), gdzie przekształcenia były wykonywane według sztywno zadanego algorytmu, Vertex Shader daje programiście pełną kontrolę nad transformacją wierzchołków. Pozwala to na implementację animacji proceduralnych, deformacji modeli, szkieletowego skiningu i dowolnych przekształceń matematycznych po stronie GPU.
Potok graficzny OpenGL ES obejmuje sekwencję etapów od danych wejściowych do końcowego obrazu. Vertex Shader znajduje się po etapie składania wierzchołków (vertex assembly), a przed etapem rasteryzacji. Każdy wierzchołek przesłany z CPU przez bufor wierzchołków przechodzi przez Vertex Shader dokładnie raz, a wynik jest przekazywany do następnego etapu w celu składania prymitywów.
| Etap potoku | Przeznaczenie |
|---|---|
| Vertex Specification | Przekazywanie danych wierzchołków i atrybutów z VBO |
| Vertex Shader | Przetwarzanie każdego wierzchołka, transformacja współrzędnych |
| Tessellation | Opcjonalny podział geometrii na podprymitywy |
| Geometry Shader | Opcjonalne generowanie lub usuwanie prymitywów |
| Rasterization | Przekształcanie prymitywów w fragmenty do wypełnienia |
Vertex Shader otrzymuje na wejściu atrybuty wierzchołka z bufora wierzchołków (VBO) przez wskaźniki atrybutów (vertex attribute pointers) skonfigurowane w kodzie CPU. Programista pisze kod shadera w GLSL (OpenGL Shading Language) lub podobnym języku, który jest kompilowany przez sterownik GPU na instrukcje maszynowe dla konkretnego układu.
Dla każdego wierzchołka Vertex Shader sekwencyjnie wykonuje trzy operacje: odczyt atrybutów wejściowych — zastosowanie transformacji określonych przez programistę — zapis wyników do zmiennych wyjściowych. Minimalnym obowiązkowym wyjściem jest pozycja wierzchołka w przestrzeni obcinania (gl_Position). Wszystkie pozostałe dane wyjściowe (kolor, normalne, współrzędne tekstury) są interpolowane i przekazywane do następnego etapu — Fragment Shader.
#version 300 es
in vec3 aPosition;
in vec2 aTexCoord;
uniform mat4 uMVP;
out vec2 vTexCoord;
void main() {
gl_Position = uMVP * vec4(aPosition, 1.0);
vTexCoord = aTexCoord;
}
Vertex Shader rozwiązuje szeroki zakres zadań potoku graficznego związanych z transformacją geometrii. Każde zadanie jest realizowane przez operacje matematyczne na wektorach i macierzach, wykonywane równolegle dla tysięcy wierzchołków jednocześnie.
Podstawowym i najczęstszym zadaniem jest mnożenie współrzędnych wierzchołków przez macierze model, view i projection (MVP). Macierz MVP przekształca wierzchołek z lokalnej przestrzeni modelu do przestrzeni obcinania (clip space), która następnie jest normalizowana i przekształcana na współrzędne ekranowe w automatycznych etapach potoku.
Dla animowanych postaci Vertex Shader realizuje animację szkieletową (skinning). Każdy wierzchołek jest przypisany do kilku kości z określonymi wagami. Vertex blending — ważona suma transformacji od przypisanych kości — pozwala płynnie deformować skórę postaci podczas ruchu szkieletu.
Vertex Shader może modyfikować geometrię na podstawie czasu lub innych parametrów uniform bez udziału CPU. Wave deformation, przesunięcia szumowe oparte na szumie Perlina i efekty fal na wodzie — wszystkie te efekty są realizowane w shaderze wierzchołków bez przeładowywania geometrii z pamięci RAM.
Chociaż oba typy shaderów są programowalnymi etapami potoku graficznego, Vertex Shader i Fragment Shader rozwiązują zasadniczo różne zadania i pracują na różnych etapach przetwarzania obrazu.
| Cecha | Vertex Shader | Fragment Shader |
|---|---|---|
| Dane wejściowe | Atrybuty wierzchołków z VBO | Dane interpolowane z VS |
| Liczba wywołań | Liczba wierzchołków | Liczba fragmentów |
| Główne zadanie | Transformacja geometrii | Obliczanie koloru piksela |
| Obciążenie obliczeniowe | Złożoność geometrii | Rozdzielczość ekranu |
| Dostęp do tekstur | Ograniczony (przez texture lookup) | Pełny dostęp |
Kluczowa różnica to częstotliwość wywołań. Vertex Shader jest wywoływany raz na wierzchołek, podczas gdy Fragment Shader — dla każdego fragmentu (piksela). W scenie o wysokiej rozdzielczości liczba wywołań Fragment Shader przewyższa liczbę wywołań Vertex Shader tysiące razy, co czyni optymalizację shaderów pikselowych jeszcze bardziej krytyczną.
Wydajność Vertex Shader jest krytyczna dla aplikacji czasu rzeczywistego, szczególnie w rozwoju mobilnym z ograniczonym zużyciem energii. Główne czynniki wydajności to liczba wierzchołków, złożoność kodu shadera i przepustowość pamięci GPU.
Aby zmniejszyć obciążenie Vertex Shader, stosuje się następujące podejścia. Level of Detail (LOD) — przełączanie na uproszczone wersje modeli przy oddalaniu się kamery od obiektu. Instancing — wielokrotne rysowanie tej samej geometrii z różnymi macierzami transformacji w jednym wywołaniu rysowania (draw call).
// Vertex Shader z obsługą instancjonowania
in vec3 aPosition;
in mat4 aInstanceMatrix;
uniform mat4 uViewProjection;
void main() {
vec4 worldPos = aInstanceMatrix * vec4(aPosition, 1.0);
gl_Position = uViewProjection * worldPos;
}
Vertex Shader w różnych interfejsach API grafiki ma podobną logikę, ale różną składnię i konwencje nazewnictwa. Rozważmy implementację podstawowego shadera wierzchołków w GLSL dla OpenGL ES 3.0 i w Metal Shading Language dla iOS i macOS.
#version 300 es
in vec4 position;
in vec3 normal;
in vec2 texcoord;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
out vec3 vNormal;
out vec2 vTexCoord;
out vec3 vPosition;
void main() {
vec4 mvPosition = modelViewMatrix * position;
vPosition = mvPosition.xyz;
vNormal = normalMatrix * normal;
vTexCoord = texcoord;
gl_Position = projectionMatrix * mvPosition;
}
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float3 position [[attribute(0)]];
float3 normal [[attribute(1)]];
};
struct VertexOut {
float4 position [[position]];
float3 worldNormal;
};
vertex VertexOut
vertexMain(VertexIn in [[stage_in]],
constant float4x4& mvp [[buffer(1)]]) {
VertexOut out;
out.position = mvp * float4(in.position, 1.0);
out.worldNormal = in.normal;
return out;
}
Często zadawane pytania
Vertex Shader to program na GPU przetwarzający każdy wierzchołek modelu 3D i przekształcający jego współrzędne na współrzędne ekranowe. Wyobraź sobie model jako siatkę punktów; shader wierzchołków przesuwa te punkty zgodnie z zadanymi regułami matematycznymi.
Vertex Shader przetwarza wierzchołki i odpowiada za geometrię, a Fragment Shader określa kolor każdego piksela. Pierwszy jest wywoływany dla każdego wierzchołka (tysiące), drugi dla każdego piksela (miliony).
Vertex Shader pisze się w języku odpowiadającym API graficznemu: GLSL dla OpenGL ES, Metal Shading Language dla Metal API na iOS/macOS, HLSL dla Direct3D. Koncepcyjnie wszystkie wykonują te same operacje na wierzchołkach.
Złożoność shadera wierzchołków bezpośrednio wpływa na FPS: więcej instrukcji na wierzchołek = dłuższe przetwarzanie. Optymalizacja obejmuje zmniejszenie liczby wierzchołków przez LOD, użycie instancjonowania i minimalizację skoków warunkowych w kodzie shadera.
Główne zadania w grach: transformacja współrzędnych przez macierze MVP, skining animowanych postaci, proceduralna deformacja ubrań i włosów, morphing między wyrazami twarzy i efekty cząsteczek z animacją na GPU.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również