Přesné a číselné výřezy v grafech efektu
Aplikace, které vykreslují efekty pomocí Direct2D, se musí postarat o dosažení požadované úrovně kvality a předvídatelnosti s ohledem na číselnou přesnost. Toto téma popisuje osvědčené postupy a relevantní nastavení v Direct2D, které jsou užitečné v těchto případech:
- Graf efektů spoléhá na vysokou číselnou přesnost nebo barvy mimo rozsah [0, 1] a chcete zajistit, aby byly vždy dostupné.
- Nebo graf efektů spoléhá na implementaci vykreslování k upnutí mezilehlých barev do rozsahu [0, 1] a chcete zajistit, aby k tomuto upnutí vždy došlo.
Direct2D často rozdělí graf efektu na oddíly a vykreslí jednotlivé oddíly v samostatném kroku. Výstup některých kroků může být uložen v přechodných texturách Direct3D, které mají ve výchozím nastavení omezený číselný rozsah a přesnost. Direct2D neposkytuje žádné záruky ohledně toho, jestli nebo kde se tyto přechodné textury používají. Toto chování se může lišit v závislosti na možnostech GPU i mezi verzemi Windows.
Ve Windows 10 direct2D kvůli použití propojení shaderu používá méně přechodných textur. Direct2D proto může vést k různým výsledkům s výchozím nastavením než v předchozích verzích Windows. To má primárně vliv na scénáře, kdy je možné propojení shaderu v grafu efektu a tento graf obsahuje také efekty, které vytvářejí výstupní barvy rozšířeného rozsahu.
Přehled renderování efektů a mezistupňů
Pokud chcete vykreslit graf efektu, Direct2D nejprve najde podkladový graf transformací, kde transformace je uzel grafu použitý v rámci efektu. Existují různé typy transformací, včetně těch, které poskytují shadery Direct3D pro použití s Direct2D.
Například Direct2D může vykreslit graf efektu takto:
Direct2D hledá příležitosti ke snížení počtu přechodných textur použitých k vykreslení grafu efektu; tato logika je neprůhlená pro aplikace. Například následující graf může Direct2D vykreslit pomocí jednoho volání kreslení Direct3D a bez přechodných textur:
Před Windows 10 by Direct2D vždy používal přechodné textury, pokud se v grafu daného efektu použilo více pixelových shaderů. Většina předdefinovaných efektů, které jednoduše upravují hodnoty barev (například Jas nebo Sytost), to dělají pomocí shaderů pixelů.
Ve Windows 10 teď Direct2D nemusí v takových případech používat přechodné textury. Dělá to interním propojením sousedních pixelových shaderů. Například:
Všimněte si, že ne všechny sousední pixelové shadery v grafu mohou být propojené dohromady, a proto pouze některé grafy vytvoří jiný výstup ve Windows 10. Úplné podrobnosti naleznete v části Propojení shaderu efektu. Primární omezení jsou:
- Efekt nebude propojen s efekty, které spotřebovávají jeho výstup, pokud je první efekt připojen jako vstup k více efektům.
- Efekt nebude propojen s efektem nastaveným jako vstupem, pokud první efekt vzorkuje svůj vstup na jinou logickou pozici než jeho výstup. Například efekt Matice barev může být propojen s jeho vstupem, ale konvoluční efekt nebude.
Předdefinované chování efektu
Mnoho předdefinovaných efektů může generovat barvy mimo rozsah [0, 1] v nepremultiplikačním barevném prostoru, i když jsou jejich vstupní barvy v tomto rozsahu. V takovém případě mohou být tyto barvy předmětem číselného výřezu. Všimněte si, že je důležité vzít v úvahu rozsah barev v nepřerušeném prostoru, i když předdefinované efekty obvykle vytvářejí barvy v předvyplněném prostoru. Tím zajistíte, že barvy zůstanou v rozsahu, i když je následně ostatní efekty odpremultiplikují.
Některé z efektů, které mohou generovat barvy mimo rozsah, nabízejí vlastnost "ClampOutput". Patří mezi ně:
Nastavení vlastnosti ClampOutput na hodnotu TRUE u těchto efektů zajistí konzistentní výsledek bez ohledu na faktory, jako je propojení shaderu. Všimněte si, že uchycení probíhá v nepružné ploše.
Jiné předdefinované efekty mohou také vytvářet výstupní barvy mimo rozsah [0, 1] v nepředmultiplikačním prostoru, i když jsou jejich barevné pixely (a vlastnosti "Barva", pokud existují) v daném rozsahu. Patří mezi ně:
- efekty transformace a škálování (pokud je vlastnost Režim interpolace krychlový nebo vysoce kvalitní krychlový)
- efekty osvětlení
- detekce hran (pokud je vlastnost překrytí hran PRAVDA)
- expozice
- Složené (Pokud je vlastnost Mode Plus)
- teplota a barevný nádech
- sépie
- sytost
Vynucení číselného výřezu v grafu efektu
Při použití efektů uvedených výše, které nemají vlastnost ClampOutput, by aplikace měly zvážit vynucení numerického omezení. To lze provést vložením dalšího efektu do grafu, který upne jeho pixely. Je možné použít efekt Color Matrix s vlastností "ClampOutput" nastavenou na TRUE a ponechat vlastnost 'ColorMatrix' jako výchozí (průchozí) hodnotu.
Druhou možností, jak dosáhnout konzistentních výsledků, je požadovat, aby Direct2D používal přechodné textury, které mají větší přesnost. Toto je popsáno níže.
Řízení přesnosti mezilehlých textur
Direct2D nabízí několik způsobů řízení přesnosti grafu. Před použitím vysoce přesných formátů v Direct2D musí aplikace zajistit, aby byly dostatečně podporovány GPU. Chcete-li to zkontrolovat, použijte ID2D1DeviceContext::IsBufferPrecisionSupported.
Aplikace mohou vytvořit zařízení Direct3D pomocí WARP (softwarové emulace), aby se zajistilo, že všechny přesnosti vyrovnávací paměti jsou podporovány nezávisle na skutečném hardwaru GPU na zařízení. To se doporučuje ve scénářích, jako je použití efektů na fotku při ukládání na disk. I když Direct2D podporuje formáty vyrovnávací paměti s vysokou přesností na GPU, doporučuje se použití WARP v tomto scénáři na úrovni funkcí 9.X u GPU kvůli omezené přesnosti aritmetiky shaderu a vzorkování na některých grafických procesorech s nízkým výkonem.
Ve všech níže uvedených případech je požadovaná přesnost ve skutečnosti minimální přesností, kterou Direct2D použije. Vyšší přesnost lze použít, pokud nejsou vyžadovány zprostředkující. Direct2D může také sdílet přechodné textury pro různé části stejného grafu nebo různé grafy zcela. V tomto případě Direct2D používá maximální přesnost požadovanou pro všechny zúčastněné operace.
Výběr přesnosti z ID2D1DeviceContext::SetRenderingControls
Nejjednodušší způsob, jak řídit přesnost zprostředkujících textur Direct2D, je použít ID2D1DeviceContext::SetRenderingControls. To řídí přesnost všech mezilehlých textur, pokud přesnost není také ručně nastavena u efektů nebo transformací přímo.
if (Device->IsBufferPrecisionSupported(D2D1_BUFFER_PRECISION_32BPC_FLOAT))
{
// Get the current rendering controls
D2D1_RENDERING_CONTROLS renderingControls = {};
Context->GetRenderingControls(&renderingControls);
// Switch the precision within the rendering controls and set it
renderingControls.bufferPrecision = D2D1_BUFFER_PRECISION_32BPC_FLOAT;
Context->SetRenderingControls(&renderingControls);
}
Přesný výběr ze vstupů a cílů rendrování
Aplikace se také můžou spoléhat na přesnost vstupů do grafu efektu, aby bylo možné řídit přesnost mezilehlých textur. To platí, pokud není zadána přesnost vyrovnávací paměti pomocí ID2D1DeviceContext::SetRenderingControlsa není nastavena ručně přímo na efektech a transformacích.
Přesnost vstupů vůči efektům je šířena prostřednictvím grafu, aby se vybrala přesnost následných mezistupňů. Kde se v grafu efektu shodují různé větve, použije se největší přesnost každého vstupu.
Přesnost vybranou na základě rastrového obrázku Direct2D určuje jeho formát pixelů. Přesnost vybraná pro ID2D1ImageSource je určena z formátu PIXEL WIC podkladového IWICBitmapSource použitého k vytvoření ID2D1ImageSource. Všimněte si, že Direct2D neumožňuje vytváření zdrojů obrázků z WIC zdrojů s přesnostmi, které nejsou podporovány Direct2D a GPU.
Je možné, že Direct2D nemůže přiřadit efektu přesnost na základě svých vstupů. K tomu dochází v případě, že efekt nemá žádné vstupy nebo když se použijeID2D1CommandList, který nemá žádnou specifickou přesnost. V tomto případě je přesnost mezilehlých textur určena ze sady bitmap, která je nastavena jako aktuální cíl vykreslování kontextu.
Přesný výběr přímo na efekty a transformace
Minimální přesnost pro přechodné textury může být také nastavena na explicitních místech v grafu efektu. To se doporučuje jenom pro pokročilé scénáře.
Minimální přesnost může být nastavena pomocí vlastnosti efektu následujícím způsobem:
if (Device->IsBufferPrecisionSupported(D2D1_BUFFER_PRECISION_32BPC_FLOAT))
{
hr = Effect->SetValue(D2D1_PROPERTY_PRECISION, D2D1_BUFFER_PRECISION_32BPC_FLOAT);
}
V rámci implementace efektu lze minimální přesnost nastavit pomocí ID2D1RenderInfo::SetOutputPrecision následujícím způsobem:
if (EffectContext->IsBufferPrecisionSupported(D2D1_BUFFER_PRECISION_32BPC_FLOAT))
{
hr = RenderInfo->SetOutputBuffer(
D2D1_BUFFER_PRECISION_32BPC_FLOAT,
D2D1_CHANNEL_DEPTH_4);
}
Všimněte si, že přesnost nastavená na efekt se rozšíří na podřízené efekty ve stejném grafu efektu, pokud u těchto podřízených efektů není nastavena jiná přesnost. Přesnost nastavená na transformaci v rámci efektu nemá vliv na přesnost podřízených transformačních uzlů.
Níže je úplný rekurzivní algoritmus určující minimální přesnost pro mezipaměť, která ukládá výstup daného uzlu transformace.