Bilineární filtrování - Bilinear filtering

Zvětšovat malá část z bitmapy , pomocí nejbližšího souseda filtrování (vlevo) , bilineární filtrování (centra) , a bikubickou filtraci (vpravo) .

Bilineární filtrování je metoda filtrování textur používaná k vyhlazení textur, když jsou zobrazeny větší nebo menší, než ve skutečnosti jsou.

Většinu času se při kreslení texturovaného tvaru na obrazovku textura nezobrazí přesně tak, jak je uložena, bez jakéhokoli zkreslení. Z tohoto důvodu většina pixelů nakonec potřebuje použít bod na textuře, který je „mezi“ texely - za předpokladu, že jsou texely body (na rozdíl od řekněme čtverců) - uprostřed (nebo v levém horním rohu, nebo kdekoli jinde; na tom nezáleží, pokud je to konzistentní) jejich příslušných „buněk“. Bilineární filtrování používá tyto body k provádění bilineární interpolace mezi čtyřmi texely nejblíže bodu, který pixel představuje (obvykle uprostřed nebo vlevo nahoře).

Vzorec

V matematickém kontextu je bilineární interpolace problémem hledání funkce f (x, y) tvaru

uspokojující

Obvyklý a obvykle výpočetně nejméně nákladný způsob výpočtu je lineární interpolace použitá dvakrát, například k výpočtu dvou funkcí a splnění

a poté spojit tyto funkce (které jsou lineární ) do jedné funkce vyhovující

V počítačové grafice se bilineární filtrování obvykle provádí na textury během mapování textury nebo na bitmapě během změny velikosti. V obou případech lze na zdrojová data (bitmapu nebo texturu) pohlížet jako na dvojrozměrné pole hodnot nebo na několik (obvykle tři) z nich v případě plnobarevných dat. Datové body použité při bilineárním filtrování jsou body 2x2 obklopující místo, pro které má být barva interpolována.

Navíc nemusíte počítat skutečné koeficienty funkce ; výpočet hodnoty je dostatečný.

Bude voláno největší celé číslo ne větší než x a zlomková část bude . Pak , a . Máme , , , . Datové body používané pro interpolaci jsou převzaty z textury / bitmapy a přiřazeny , , a .

, jsou dva datové body pro odečtení prvního od druhého výnosu

Protože je lineární, jeho derivace je konstantní a rovná se

Protože ,

a podobně,

Protože jsme vypočítali koncové body a potřebné pro druhý krok interpolace.

Druhým krokem je výpočet , kterého lze dosáhnout samotným vzorcem, který jsme použili pro výpočet mezilehlých hodnot:

V případě změny měřítka zůstane y konstantní ve stejné linii obrazu se změněnou stupnicí a uložení mezivýsledků a jejich opětovné použití pro výpočet dalšího pixelu může vést k významným úsporám. Podobné úspory lze dosáhnout u všech „bi“ druhů filtrování, tj. U těch, které lze vyjádřit jako dva průchody jednorozměrného filtrování.

V případě mapování textury je konstantní x nebo y zřídka, pokud se někdy setkáte, a protože dnešní (2000+) grafický hardware je vysoce paralelní, stejně by nedošlo k žádné časové úspoře.

Další způsob psaní bilineárního interpolačního vzorce je

Ukázkový kód

Tento kód předpokládá, že textura je čtvercová (extrémně běžný výskyt), že se nepoužívá žádné mipmapování a že existuje pouze jeden kanál dat (To je neobvyklé. Téměř všechny textury jsou barevné, proto mají červenou, zelenou a modré kanály a mnoho z nich má kanál průhlednosti alfa, takže musíme provést tři nebo čtyři výpočty y, jeden pro každý kanál). Umístění UV souřadnic je ve středu texelu. Například {(0,25,0,25), (0,75,0,25), (0,25,0,75), (0,75,0,75)} jsou hodnoty pro texturu 2x2.

 double getBilinearFilteredPixelColor(Texture tex, double u, double v) {
   u = u * tex.size - 0.5;
   v = v * tex.size - 0.5;
   int x = floor(u);
   int y = floor(v);
   double u_ratio = u - x;
   double v_ratio = v - y;
   double u_opposite = 1 - u_ratio;
   double v_opposite = 1 - v_ratio;
   double result = (tex[x][y]   * u_opposite  + tex[x+1][y]   * u_ratio) * v_opposite + 
                   (tex[x][y+1] * u_opposite  + tex[x+1][y+1] * u_ratio) * v_ratio;
   return result;
 }

Omezení

Bilineární filtrování je poměrně přesné, dokud se měřítko textury nedostane pod polovinu nebo nad dvojnásobek původní velikosti textury - to znamená, že pokud byla textura 256 pixelů v každém směru, její zvětšení pod 128 nebo nad 512 pixelů způsobí, že textura bude vypadají špatně kvůli chybějícím pixelům nebo příliš velké hladkosti. V herních nebo jiných aplikacích pro 3D vykreslování se často používá mipmapping k poskytnutí zmenšené verze textury pro lepší výkon; přechod mezi dvěma různě velkými mipmapami na textury v perspektivě pomocí bilineárního filtrování však může být velmi náhlý. Trilineární filtrování , i když poněkud složitější, může tento přechod v celém procesu zjemnit. Ve světě změny velikosti 2-D obrazu je obvykle preferována bikubická interpolace pro iluzi ostrosti, kterou vytváří, a pro své vynikající vlastnosti vyhlazování; většina bikubiků toho však dosahuje kombinací rozmazání a vyzvánění artefaktů. Hermitův filtr, který je jediný kubický, který nepřidává ani rozmazání ani vyzvánění, nevyhladí alias lépe než lineární interpolace, ale stále je o něco ostřejší.

Pro rychlou ukázku toho, jak může textel ve filtrované struktuře chybět, je zde seznam čísel představujících středy krabic z textilie široké 8 texelů (v červené a černé barvě) smíchané s čísly ze středů krabiček z 3 texel-široký-down-vzorkované textury (v modré barvě). Červená čísla představují texely, které by se při výpočtu textury 3 texel vůbec nepoužily.

0,0625, 0,1667 , 0,1875, 0,3125 , 0,4375, 0,5000 , 0,5625, 0,6875 , 0,8125, 0,8333 , 0,9375

Speciální případy

Textury obecně nejsou nekonečné a někdy jeden končí souřadnicí pixelu, která leží mimo mřížku souřadnic texelu. Existuje několik způsobů, jak to vyřešit:

  • Zabalte texturu tak, aby poslední texel v řadě také přišel těsně před prvním a poslední texel ve sloupci také nad prvním. To funguje nejlépe, když se textura obkládá.
  • Vytvořte oblast mimo texturu jednou barvou. To může být užitečné pro texturu navrženou tak, aby byla položena na pevné pozadí nebo aby byla průhledná.
  • Opakujte okrajové texty do nekonečna. To funguje nejlépe, pokud textura není navržena tak, aby se opakovala.

Viz také