Vyrovnávací paměť šablony - Stencil buffer

Na tomto obrázku jsou bílé oblasti a černé oblasti, které představují 1 s a 0 s ve vyrovnávací paměti vzorníku. Tvary se poté nakreslí na horní část pruhů převrácením hodnoty vyrovnávací paměti šablony. Pokud má vyrovnávací paměť na tomto pixelu hodnotu 0 (černá), vybarvujte pixel bíle (1) a naopak.

Šablony vyrovnávací paměť je navíc vyrovnávací paměť dat , kromě barevného vyrovnávací paměti a Z-bufferu , objevil na moderní grafický hardware . Vyrovnávací paměť je na pixel a pracuje na celočíselných hodnotách, obvykle s hloubkou jednoho bajtu na pixel. Z-bufferu a stencil bufferu často sdílejí stejnou oblast v paměti RAM na grafický hardware.

V nejjednodušším případě se vyrovnávací paměť vzorníku používá k omezení oblasti vykreslování (vzorování). Pokročilejší použití vyrovnávací paměti vzorníku využívá silné spojení mezi vyrovnávací pamětí Z a vyrovnávací pamětí vzorníku v kanálu vykreslování . Například hodnoty vzorníku lze automaticky zvyšovat / snižovat pro každý pixel, který selže nebo projde testem hloubky.

Jednoduchá kombinace hloubkového testu a modifikátorů šablony umožňuje obrovské množství efektů (například objemy stínů šablony , oboustranný vzorník, kompozice, obtisky, rozpouštění, vyblednutí, tahy, siluety, obrysový výkres nebo zvýraznění průsečíků mezi složitými primitivy ) i když často vyžadují několik vykreslovacích průchodů, a proto mohou grafický hardware zatěžovat.

Nejtypičtější aplikací je stále přidávání stínů do 3D aplikací . Používá se také pro planární odrazy.

Jiné techniky vykreslování, jako je vykreslování portálu , používají vyrovnávací paměť šablon jinými způsoby; lze jej například použít k vyhledání oblasti obrazovky zakryté portálem a ke správnému opětovnému vykreslení těchto pixelů.

Vyrovnávací paměť šablony a její modifikátory jsou přístupné v počítačové grafice pomocí API jako OpenGL , Direct3D nebo Vulkan .

Architektura

Stencil buffer obvykle sdílí stejný paměťový prostor jako Z-buffer a obvykle je poměr 24 bitů pro Z-buffer + 8 bitů pro stencil buffer nebo v minulosti 15 bitů pro Z-buffer + 1 bit pro stencil buffer . Další variantou je 4 + 24, kde je použito 28 z 32 bitů a 4 ignorovány. Stencil a Z-buffers jsou součástí bufferu frame, spojeného s color buffer. Prvním čipem dostupným pro širší trh byl Permedia II od 3Dlabs, který podporoval jednobitovou vyrovnávací paměť šablon.

Bity přidělené vzorkovací vyrovnávací paměti lze použít k reprezentaci číselných hodnot v rozsahu [0, 2 n -1] a také jako booleovskou matici (n je počet přidělených bitů), z nichž každý lze použít k řízení konkrétní část scény. Je také možná jakákoli kombinace těchto dvou způsobů využití dostupné paměti.

Test šablony

Stencil test or stenciling is among the operations on the pixels / fragments (Per-pixel operations), located after the alpha test , and before the depth test . Test šablony zajišťuje, že nežádoucí pixely nedosáhnou testu hloubky. To šetří čas zpracování scény. Podobně může test alfa zabránit tomu, aby odpovídající pixely dosáhly testu šablony.

Samotný test se provádí přes vyrovnávací paměť šablony na určitou hodnotu, nebo ji upravil nebo použil, a provádí se pomocí takzvané funkce šablony a operací šablony. Funkce vzorníku je funkce, pomocí které se porovnává hodnota vzorníku určitého pixelu s danou referenční hodnotou. Pokud je toto srovnání logicky pravdivé , test šablony proběhne. Jinak ne.

Přitom je možná reakce způsobená výsledkem porovnání tří různých stavových hloubek a vzorníku:

  • Test šablony neprošel
  • Test šablony je úspěšný, ale ne test hloubky
  • Oba testy jsou předány (nebo je předán test šablony a hloubka není povolena)

Pro každý z těchto případů lze nastavit různé operace nad zkoumaným pixelem. Ve vzorkovacích funkcích OpenGL definuje referenční hodnota a maska ​​funkci glStencilFunc. V Direct3D je každá z těchto komponent upravena jednotlivě pomocí metod SetRenderState zařízení aktuálně ovládaných. Tato metoda očekává dva parametry, z nichž první je nastavená podmínka a druhá její hodnota. V pořadí, které bylo použito výše, se tyto podmínky nazývají D3DRS_STENCILFUNC, D3DRS_STENCILREF a D3DRS_STENCILMASK.

Stencil operations in OpenGL adjust glStencilOp function that expectects three values. V Direct3D opět každý stát nastavuje konkrétní metodu SetRenderState. Tři stavy, které lze přiřadit chirurgickému zákroku, se nazývají D3DRS_STENCILFAIL, D3DRENDERSTATE_STENCILZFAIL a D3DRENDERSTATE_STENCILPASS.

Správa

I když je rozsah aplikací pro stencil buffery poměrně široký, můžeme zmínit několik známých aplikací.

Na obrázku nad zemí s obrázkem je těsně nad bílým povrchem, což nestačí k zabránění účinku hlubokého boje. Naproti tomu v stensilinga (nižší obrázek) je tento efekt zcela odstraněn, i když se jedná o koplanární povrchy.

Z-boje

Kvůli nedostatečné přesnosti v Z-bufferu mohou být koplanární polygony, které jsou krátkého dosahu nebo se překrývají, zobrazeny jako jedna rovina s množstvím nepravidelných průřezů. Tyto sekce se mohou lišit v závislosti na poloze kamery a dalších parametrech a rychle se mění. Tomu se říká Z-fighting. Existuje několik řešení tohoto problému:

- Přibližte vzdálenou rovinu, abyste omezili hloubku scény, čímž zvýšíte přesnost vyrovnávací paměti Z nebo zmenšíte vzdálenost, ve které jsou objekty ve scéně viditelné.

- Zvyšte počet bitů přidělených Z-bufferu, což je možné na úkor paměti pro stencil buffer.

- Přesuňte polygony dále od sebe, což omezuje možnosti umělce vytvořit propracovanou scénu.

Všechny tyto přístupy k problému mohou pouze snížit pravděpodobnost, že u polygonů dojde k boji Z, a obecně nezaručují konečné řešení.

Řešení, které obsahuje vyrovnávací paměť šablony, je založeno na znalosti toho, který polygon by měl být před ostatními. Silueta předního mnohoúhelníku je nasáván do šablony vyrovnávací paměti. Poté lze zbytek scény vykreslit pouze tam, kde je silueta záporná, takže se nebude střetávat s předním mnohoúhelníkem.

Stínový objem

Shadow volume je technika používaná ve 3D počítačové grafice k přidávání stínů k vykreslené scéně. Poprvé byly navrženy Frankem Crowem v roce 1977 jako geometrie popisující 3D tvar oblasti uzavřené ze světelného zdroje. Stínový svazek rozděluje virtuální svět na dvě části: oblasti, které jsou ve stínu, a oblasti, které nejsou.

Implementace stencil bufferu stínových svazků je obecně považována za jednu z nejpraktičtějších univerzálních stínovacích technik v reálném čase pro použití na moderním 3D grafickém hardwaru. To bylo propagováno v videohry Doom 3 , a určitá obměna techniky používané v této hře se stala známou jako Carmack je vzad .

Úvahy

Odraz scény se vykreslí, když se samotná scéna transformuje a odráží ve vztahu k „zrcadlové“ rovině, což vyžaduje více průchodů vykreslení a použití vyrovnávací paměti šablony k omezení oblastí, kde funguje aktuální průchod vykreslení:

  1. Nakreslete scénu bez zrcadlových oblastí - pro každé zrcadlo zamkněte Z-buffer a barevný buffer
    1. Vykreslete viditelnou část zrcadla
    2. Hloubkový test je nastaven tak, aby každý pixel projel zadáním maximální hodnoty a vždy vyhověl
  2. pro každé zrcadlo:
    1. Test hloubky je nastaven tak, aby vyhověl pouze v případě, že vzdálenost pixelu je menší než aktuální (výchozí chování)
    2. Transformace matice se změní tak, aby odrážela scénu vzhledem k rovině zrcadla
    3. Odemkněte Z-buffer a barevný buffer
    4. Nakreslete scénu, ale pouze její část, která leží mezi rovinou zrcadla a kamerou. Jinými slovy, rovina zrcadlení je také rovinou ořezávání
    5. Znovu uzamkne vyrovnávací paměť barev, hloubkový test je nastaven tak, aby vždy proběhl, reset vzorníku pro další zrcadlo.

Planární stíny

Při kreslení roviny stínů existují dva dominantní problémy: První se týká problému hlubokého boje v případě, že plochá geometrie není udělena na části pokryté stínem stínů a venku. Viz část, která se k tomu vztahuje. Další problém se týká rozsahu stínů mimo oblast, kde je letadlo.

Další problém, který se může, ale nemusí objevit, v závislosti na technice, návrh více polygonů v jedné části stínu, což má za následek tmavší a světlejší části stejného odstínu. Všechny tři problémy lze vyřešit geometricky, ale vzhledem k možnosti, že se přímo použije hardwarová akcelerace, je to mnohem elegantnější implementace pomocí vyrovnávací paměti šablony: 1. Povolit světla a světla 2. Nakreslit scénu bez polygonu, který by měl být promítané stíny 3. Nakreslete všechny polygony, které by měly být promítané stíny, ale bez světel. Přitom vyrovnávací paměť šablony, pixel každého polygonu, který má být přiřazen ke konkrétní hodnotě pro zemi, ke které patří. Vzdálenost mezi těmito hodnotami by měla být alespoň dvě, protože pro každou rovinu mají být použity dvě hodnoty pro dva stavy: ve stínech a světlé. 4. Zakažte jakékoli globální osvětlení (aby se zajistilo, že další kroky ovlivní pouze jednotlivé vybrané světlo) Pro každou rovinu: Pro každé světlo: 1. Upravte vyrovnávací paměť šablony a pouze pixely, které nesou konkrétní hodnotu pro vybranou úroveň. Zvyšte hodnotu všech pixelů, které jsou promítanými objekty, mezi datem dané úrovně a jasem. 2. Nechte pouze vybrané světlo, aby nakreslilo hladinu, při které se část její specifické hodnoty nezměnila.

Prostorové stíny

Implementace vyrovnávací paměti prostorových výkresových stínů je jakýkoli stín geometrického těla, jehož objem zahrnuje část scény, která je v něm. Pokud některá část scény patří do tohoto svazku, světlo není osvětleno, jinak je. Tento problém se zhoršuje zvýšením počtu světel, ale neřeší počet oblastí, na které dopadají stíny. Existuje několik řešení problému, ale řídili jsme se následujícím algoritmem: 1. Nakreslete scénu bez světla 2. Zamkněte Z-buffer a barevný buffer, aby dva nemohli provádět změny Pro každé světlo 1. Použití hloubky informace o scéně (Z-buffer) k vyplnění stencil bufferu pouze v těch částech scény, kde objemový stín neexistuje nebo není viditelný ze stávajících budov. 2. Odemkněte vyrovnávací paměť pro barvu a upravte funkci Z-vyrovnávací paměti tak, aby bylo možné provádět úpravy pouze tam, kde je hodnota hloubky rovna existující 3. Nakreslete scénu osvětlenou pouze tímto světlem, ale pouze pro část scény procházející testem šablony

Každá z těchto pasáží znamená, že lze použít čistou vyrovnávací paměť šablony.

Pokud jde o stíny, lze tuto techniku ​​použít k osvětlení částí vesmíru, které jsou pod silným světlem. Například bylo možné vidět jas reflektoru v tmavé místnosti s velkou přítomností prachu ve vzduchu osvětlující příslušný objem prostoru.

Další aplikace

Dalším příkladem je takzvaný měkký stín, ve kterém je přechod mezi osvětlenou a stínovanou částí scény rozostřený. Konkrétně jedním ze způsobů, jak dosáhnout tohoto efektu stencil bufferu, je znásobení objemu stínu, a to tak, že kopie jsou příslušně zmenšeny podle geometrické řady s malým zvětšením, např. 1,04. Střed měřítka může být těžištěm polygonu, který představuje nejvyšší objem. To samo o sobě poskytne řadu složených stínů, které dávají požadovaný efekt.

Další implementace zahrnuje pole vizualizace během modelování techniky těles Solid Constructive Solid Geometry (CSG), kde vyrovnávací paměť šablon může společně s Z-vyrovnávací pamětí úspěšně vyřešit problémy booleovských operací SOLiD.

OpenGL

glEnable(GL_STENCIL_TEST); // by default not enabled
glStencilMask(stencilMask); // allow writing to stencil buffer, by default (0xFF) no mask.
glClearStencil(clearStencilValue); // clear stencil value, by default = 0
glStencilFunc(func, ref, mask); // by default GL_ALWAYS, 0, 0xFF, always pass stencil test
glStencilOp(fail,zfail,zpass); // by default GL_KEEP, GL_KEEP, GL_KEEP, do not change stencil buffer
glClear(GL_STENCIL_BUFFER_BIT); // clear stencil buffer, fill with (clearStencilValue & stencilMask)

Test: (ref & mask) func (stencilValue & mask)

V závislosti na třech možných podmínkách funkce šablony / funkce hloubky.

1. Selže testovací funkce šablony:

   If say func is GL_NEVER, the stencil test will always fail. 
   Neither Color/Z-buffers are modified. The stencil buffer is modified as per glStencilOp fail.
   If say glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP) then GL_REPLACE takes place and 
   stencilValue = (ref & stencilMask) // will become ref

2. Testovací funkce šablony vyhovuje / funkce hloubkové zkoušky selže:

  If say func is GL_ALWAYS, the stencil test will always pass, but depth test may fail.
  Neither Color/Z-buffer are modified. The stencil buffer is modified as per glStencilOp zfail.
  If say glStencilOp(GL_KEEP, GL_INCR, GL_KEEP) then GL_INCR takes place and
   stencilValue = (stencilValue+1) // will become 1

3. Předání funkce vzorníku / předání funkce hloubky:

  If say func is GL_ALWAYS, the stencil test will always pass. If the depth test also passes.
  Both Color/Z-buffer are modified. The stencil buffer is modified as per glStencilOp zpass.
  If say, glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) then Stencil values are not changed, only Color and Z-buffers are modified.

Typicky je vyrovnávací paměť šablony inicializována nastavením masky vyrovnávací paměti Z a barevné vyrovnávací paměti na hodnotu false. a poté nastavením příslušné hodnoty ref na vzorkovací vyrovnávací paměť selháním testu vzorníku pokaždé.

  // disable color and Z-buffers
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glDepthMask(GL_FALSE);

  glStencilFunc(GL_NEVER, 1, 0xFF); // never pass stencil test
  glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);  // replace stencil buffer values to ref=1
  glStencilMask(0xFF); // stencil buffer free to write
  glClear(GL_STENCIL_BUFFER_BIT);  // first clear stencil buffer by writing default stencil value (0) to all of stencil buffer.
  draw_stencil_shape(); // at stencil shape pixel locations in stencil buffer replace stencil buffer values to ref = 1

Nyní použijte inicializovanou vyrovnávací paměť šablony a test šablony k zápisu pouze v místech, kde je hodnota šablony 1:

  // enable color and Z-buffers.
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  glDepthMask(GL_TRUE);

  // no more modifying of stencil buffer on stencil and depth pass.
  glStencilMask(0x00);
  // can also be achieved by glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

  // stencil test: only pass stencil test at stencilValue == 1 (Assuming depth test would pass.) 
  // and write actual content to depth and color buffer only at stencil shape locations.
  glStencilFunc(GL_EQUAL, 1, 0xFF);
 
  draw_actual_content();

Viz také

Reference