Vertex Shader är ett programmerbart steg i grafikpipelinen (graphics pipeline) som bearbetar varje vertex i en tredimensionell modell. Enligt Khronos Group, 2025, tar vertex shadern emot vertexattribut — koordinater, normaler, färg och texturkoordinater — och omvandlar dem enligt angiven logik. Vertex Shader exekveras för varje vertex oberoende, vilket möjliggör effektiv parallellisering av beräkningar på tusentals GPU-kärnor.
Huvudpunkter
Vertex Shader är ett programmerbart steg i grafikpipelinen (graphics pipeline) som bearbetar varje vertex i en tredimensionell modell individuellt. En vertex är en punkt i tredimensionellt utrymme som innehåller attribut: xyz-koordinater, normaler, färg och UV-texturkoordinater.
Till skillnad från fixed-function pipeline, där transformationer utfördes enligt en fast algoritm, ger Vertex Shader utvecklaren full kontroll över vertexomvandling. Detta möjliggör implementering av procedurell animation, modelldeformation, skeletalskinning och alla matematiska transformationer på GPU-sidan.
OpenGL ES grafikpipeline omfattar en sekvens av steg från indata till slutlig bild. Vertex Shader finns efter steget för vertexmontering (vertex assembly) och före rasteriseringssteget. Varje vertex som skickas från CPU:n via vertexbufferten passerar genom Vertex Shader exakt en gång, och resultatet skickas vidare till nästa steg för montering av primitiver.
| Pipelinsteg | Ändamål |
|---|---|
| Vertex Specification | Överföring av vertexdata och attribut från VBO |
| Vertex Shader | Bearbetning av varje vertex, koordinatomvandling |
| Tessellation | Valfri uppdelning av geometri i underprimitiver |
| Geometry Shader | Valfri generering eller borttagning av primitiver |
| Rasterization | Omvandling av primitiver till fragment för fyllning |
Vertex Shader tar emot vertexattribut från vertexbufferten (VBO) via vertexattributpekare (vertex attribute pointers) konfigurerade i CPU-koden. Utvecklaren skriver shaderkod i GLSL (OpenGL Shading Language) eller liknande språk, som kompileras av GPU-drivrutinen till maskininstruktioner för det specifika chipet.
För varje vertex utför Vertex Shader sekventiellt tre operationer: läsning av indataattribut — tillämpning av transformationer definierade av utvecklaren — skrivning av resultat till utdatavariabler. Minsta obligatoriska utdata är vertexens position i klipprymden (gl_Position). Alla andra utdata (färg, normaler, texturkoordinater) interpoleras och skickas vidare till nästa steg — 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 löser ett brett spektrum av grafikpipelinsuppgifter relaterade till geometriomvandling. Varje uppgift implementeras genom matematiska operationer på vektorer och matriser, som utförs parallellt för tusentals vertex samtidigt.
Den grundläggande och vanligaste uppgiften är multiplikation av vertexkoordinater med model-, view- och projectionsmatriser (MVP). MVP-matrisen omvandlar vertex från modellens lokala rymd till klipprymden (clip space), som sedan normaliseras och omvandlas till skärmkoordinater i automatiska pipelinsteg.
För animerade karaktärer implementerar Vertex Shader skelettanimation (skinning). Varje vertex är bunden till flera ben med specifika vikter. Vertex blending — den viktade summan av transformationer från bundna ben — möjliggör smidig deformation av karaktärens hud när skelettet rör sig.
Vertex Shader kan modifiera geometri baserat på tid eller andra uniform-parametrar utan CPU-deltagande. Wave deformation, brusförskjutningar baserade på Perlin-brus och vattenkrusningseffekter — alla dessa effekter implementeras i vertex shadern utan att ladda om geometri från RAM.
Även om båda shadertyperna är programmerbara steg i grafikpipelinen, löser Vertex Shader och Fragment Shader fundamentalt olika uppgifter och arbetar i olika stadier av bildbearbetning.
| Egenskap | Vertex Shader | Fragment Shader |
|---|---|---|
| Indata | Vertexattribut från VBO | Interpolerad data från VS |
| Antal anrop | Antal vertex | Antal fragment |
| Huvuduppgift | Geometriomvandling | Beräkning av pixelfärg |
| Beräkningsbelastning | Geometrikomplexitet | Skärmupplösning |
| Åtkomst till texturer | Begränsad (via texture lookup) | Full åtkomst |
Den viktigaste skillnaden är anropsfrekvensen. Vertex Shader anropas en gång per vertex, medan Fragment Shader anropas för varje fragment (pixel). I en scen med hög upplösning överstiger antalet Fragment Shader-anrop antalet Vertex Shader-anrop tusentals gånger, vilket gör optimering av pixel shaders ännu mer kritisk.
Vertex Shader-prestanda är kritisk för realtidsapplikationer, särskilt inom mobilutveckling med begränsad energiförbrukning. De viktigaste prestandafaktorerna är antalet vertex, shaderkodens komplexitet och GPU-minnets bandbredd.
För att minska belastningen på Vertex Shader tillämpas följande tillvägagångssätt. Level of Detail (LOD) — växla till förenklade versioner av modeller när kameran rör sig bort från objektet. Instancing — upprepad ritning av samma geometri med olika transformationsmatriser i ett enda ritningsanrop (draw call).
// Vertex Shader med instansieringsstöd
in vec3 aPosition;
in mat4 aInstanceMatrix;
uniform mat4 uViewProjection;
void main() {
vec4 worldPos = aInstanceMatrix * vec4(aPosition, 1.0);
gl_Position = uViewProjection * worldPos;
}
Vertex Shader i olika grafik-API:er har liknande logik men olika syntax och namngivningskonventioner. Låt oss titta på implementeringen av en grundläggande vertex shader i GLSL för OpenGL ES 3.0 och i Metal Shading Language för iOS och 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;
}
Vanliga frågor
Vertex Shader är ett program på GPU:n som bearbetar varje vertex i en 3D-modell och omvandlar dess koordinater till skärmkoordinater. Föreställ dig modellen som ett rutnät av punkter; vertex shadern flyttar dessa punkter enligt specificerade matematiska regler.
Vertex Shader bearbetar vertex och ansvarar för geometrin, medan Fragment Shader bestämmer färgen på varje pixel. Den första anropas för varje vertex (tusentals), den andra för varje pixel (miljontals).
Vertex Shader skrivs på det språk som motsvarar grafik-API:et: GLSL för OpenGL ES, Metal Shading Language för Metal API på iOS/macOS, HLSL för Direct3D. Konceptuellt utför de alla samma operationer på vertex.
Vertex shaderns komplexitet påverkar direkt FPS: fler instruktioner per vertex = längre bearbetning. Optimering inkluderar minskning av antalet vertex genom LOD, användning av instancing och minimering av villkorliga hopp i shaderkoden.
Huvuduppgifter i spel: koordinatomvandling via MVP-matriser, skinning av animerade karaktärer, procedurell deformation av kläder och hår, morphing mellan ansiktsuttryck och partikeleffekter med animation på GPU:n.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också