vykreslovací pajplajnTakégrafická pipeline, graphics pipeline, renderovací řetězec, render pipelinePokročilý
Definice
Vykreslovací pipeline je posloupnost pevně daných kroků, kterými grafická karta promění popis 3D scény (vrcholy, transformace, materiály) na barvy jednotlivých pixelů ve výsledném obrazu. Zahrnuje zpracování vrcholů, sestavení primitiv, ořez, rasterizaci, výpočet barvy fragmentů a zápis do framebufferu. Programovatelné části pipeline řídí shadery, zbytek obstarává pevná logika hardwaru.
Nezaměňujte: V grafice označuje vykreslovací pipeline cestu geometrie na obrazovku, zatímco v prohlížeči se stejné slovo používá pro fáze zpracování HTML a CSS (styl, layout, paint, composite).
Proč se vykreslování dělí na etapy
Vykreslovací pipeline vznikla proto, že převod trojrozměrné geometrie na dvojrozměrný rastr je masivně paralelní úloha s velmi opakovanou strukturou. Miliony vrcholů se transformují stejným vzorcem, miliony fragmentů se stínují stejným kódem. Rozdělení práce na pevné etapy umožňuje, aby GPU zpracovávala tisíce prvků najednou a aby každá etapa běžela na jiné dávce dat, zatímco ostatní pokračují dál. Grafická karta je tedy doslova výrobní linka, ne procesor vykonávající jeden krok po druhém.
Jaké etapy postupně proběhnou
Etapy jdou v ustáleném pořadí. Aplikace nejprve dodá vertex buffer s vrcholy a stavem vykreslování, pak nastupuje samotná pipeline:
- Vertex shader: každý vrchol se transformuje z modelového do clip prostoru, počítají se normály a interpolované atributy.
- Volitelné etapy geometrie: teselace a geometry shader mohou vrcholy přidávat nebo odebírat.
- Sestavení primitiv a ořez: vrcholy se pospojují do trojúhelníků, ořežou se části mimo pohledový objem a zahodí se odvrácené strany (back-face culling).
- Rasterizace: trojúhelník se pokryje fragmenty, tedy kandidáty na pixely, a atributy vrcholů se mezi nimi interpolují.
- Fragment shader: pro každý fragment se spočítá barva ze vzorkovaných textur a osvětlovacího modelu.
- Per-fragment operace: hloubkový test, stencil, míchání průhlednosti a zápis do framebufferu.
Programovatelné jsou dnes jen některé etapy, a právě ty píše vývojář jako shader. Rasterizace, hloubkový test i blending zůstávají pevnou hardwarovou logikou, kterou lze pouze konfigurovat.
Kde se pipeline nejčastěji zadrhne
Protože etapy běží zřetězeně, celkový výkon určuje ta nejpomalejší. Scéna s obrovským počtem drobných objektů bývá omezená režií na straně CPU a počtem draw callů, scéna s několika velkými plochami a drahým osvětlením naopak fragment shaderem. Překreslování stejného pixelu vícekrát (overdraw) se řeší předřazeným depth prepassem nebo řazením neprůhledné geometrie zepředu dozadu. Profiler v ovladači nebo nástroji typu RenderDoc ukáže, která etapa je úzké hrdlo, což je jediný rozumný způsob, jak optimalizaci začít.
Pevná linka, moderní API a alternativy
Starší OpenGL nabízelo takzvanou fixed-function pipeline: osvětlení a transformace se jen nastavovaly parametry. Moderní API (Vulkan, Direct3D 12, Metal, WebGPU) jdou opačným směrem a nutí celou konfiguraci pipeline sestavit dopředu do neměnného objektu, tzv. pipeline state object. Změna stavu pak nestojí ovladač téměř nic, ale za cenu ukecanějšího kódu při inicializaci.
Rasterizační pipeline není jediná cesta k obrazu. Ray tracing sleduje paprsky scénou a řeší viditelnost úplně jinak, compute shadery umožňují napsat si vlastní vykreslování mimo pevné etapy. V praxi se přístupy míchají: rastr určí viditelné povrchy a paprsky doplní odrazy nebo stíny.
Příklady z praxe
Minimální dvojice shaderů ve WebGL
Nejjednodušší průchod pipeline potřebuje vertex shader, který vrchol umístí do clip prostoru, a fragment shader, který vrátí barvu. Vše mezi tím (ořez, rasterizaci, hloubkový test) obstará hardware. Ukázka vykreslí jednobarevný trojúhelník z předaných pozic.
// vertex shader (GLSL ES) attribute vec3 aPosition; uniform mat4 uMVP; void main() { gl_Position = uMVP * vec4(aPosition, 1.0); } // fragment shader precision mediump float; void main() { gl_FragColor = vec4(0.9, 0.3, 0.2, 1.0); }Hra běží na 40 FPS kvůli overdrawu
Tým řeší propad snímkování v lesní scéně. Profiler ukáže, že fragment shader se pro každý pixel spustí v průměru šestkrát, protože se listí vykresluje v náhodném pořadí a průhledné plochy nejdou seřadit. Zavedení depth prepassu pro neprůhledné kmeny a řazení listů zepředu dozadu sníží počet vykonaných fragment shaderů zhruba na polovinu a snímkování se vrátí nad 60 FPS.
Časté omyly
- MýtusCelou pipeline si dnes napíšu v shaderech, jak chci.
- Ve skutečnostiProgramovatelné jsou jen některé etapy. Rasterizace, hloubkový a stencil test i blending zůstávají pevnou hardwarovou logikou, kterou lze nastavit, ale ne přepsat. Vlastní vykreslovací algoritmus mimo tyto etapy vyžaduje compute shadery nebo ray tracing API.
- MýtusFragment a pixel jsou to samé.
- Ve skutečnostiFragment je kandidát na pixel vzniklý rasterizací jednoho primitiva. Na jeden pixel může připadnout mnoho fragmentů z různých trojúhelníků a část z nich hloubkový test zahodí dřív, než se cokoli zapíše do framebufferu.
- MýtusSilnější grafická karta vyřeší nízké FPS vždycky.
- Ve skutečnostiÚzkým hrdlem bývá často CPU, konkrétně počet draw callů a změn stavu pipeline. Pokud GPU čeká na příkazy, rychlejší čip nepomůže; pomůže dávkování geometrie, instancing nebo API s nižší režií ovladače.
Časté dotazy
- Jaký je rozdíl mezi vykreslovací pipeline a ray tracingem?
- Vykreslovací pipeline v klasickém pojetí rasterizuje: pro každý trojúhelník najde pixely, které pokrývá, a viditelnost řeší hloubkovým bufferem. Ray tracing postupuje opačně, od pixelu vysílá paprsek do scény a hledá nejbližší zásah, takže odrazy, lomy a měkké stíny vycházejí přirozeně z principu. Rasterizace je výrazně levnější na běžnou geometrii a zůstává základem her v reálném čase. V praxi se dnes obojí kombinuje: rastr určí viditelné povrchy a paprsky doplní odrazy nebo globální osvětlení.
- Proč moderní API vyžadují pipeline state object dopředu?
- Pipeline state object sdružuje kompletní konfiguraci vykreslování: použité shadery, formát vrcholů, nastavení rasterizace, hloubkového testu i blendingu. Starší API dovolovala měnit každý stav zvlášť, takže ovladač musel před každým kreslením kontrolovat kombinaci nastavení a případně kompilovat nové varianty shaderů. Předkompilovaný objekt tuto práci přesune na start aplikace. Výsledkem je předvídatelnější snímkování a menší zátěž CPU za cenu delší inicializace a nutnosti spravovat větší množství variant.
- Jak zjistím, která etapa pipeline brzdí moji aplikaci?
- Nejspolehlivější cestou je zachycení snímku nástrojem pro ladění grafiky, například RenderDoc, Nsight Graphics nebo profilerem v herním enginu. Tyto nástroje ukážou čas strávený v jednotlivých průchodech, počet draw callů, počet vykonaných vertex a fragment shaderů i objem přenesených textur. Praktická zkratka je snížit rozlišení: pokud snímkování výrazně stoupne, brzdí fragment shader nebo šířka pásma paměti. Když se nezmění nic, hrdlo leží na straně CPU nebo ve zpracování geometrie.
- Potřebuje 2D vykreslování také pipeline?
- Vykreslovací pipeline se používá i pro dvourozměrnou grafiku. Prohlížeče, herní enginy i UI knihovny posílají na GPU obdélníky složené ze dvou trojúhelníků, na které nanášejí textury s obrázky nebo vyrenderovaným textem. Vertex shader řeší umístění a měřítko, fragment shader vzorkuje texturu a míchá průhlednost. Rozdíl proti 3D je hlavně v tom, že se obvykle vypíná hloubkový test a pořadí kreslení určuje viditelnost přímo.
Zdroje
- Khronos OpenGL Registry(otevře se v novém okně)
- WebGL API(otevře se v novém okně)
- Graphics pipeline(otevře se v novém okně)