18 Dec 2020

Sonic - optimalizácia a kompresia

Final Fantasy 6 pre SNES je kolosálna hra s famóznou pixel art grafikou a audiom. Priemerná doba prvého prejdenia hry je niekde okolo 35-40 hodín a celé sa to vôjde na 3 megový kartridž. Ešte technicky lepší Chronotrigger si vystačí so 4 megami. Tales of Phantasia mala 6 megabajtov /a intro so samplovanými hlasmi a 16 kanálové audio/ a nakoniec Star Ocean to úplne zarezal s dodatočným čipom S-DD1 pre dekompresiu a hra mala po rozbalení 12 mega. To je ekvivalent 100 gigovej hry dnes. Všetky tie SNES JRPG gamesy som krvopotne svojho času pretlačil cez SNES emuláciu, ktorá vtedy bola ešte v pokakaných plienkach. Vidíte teraz koľko vzácneho kartridžového priestoru dobrá hra zaberie a aké vychytané softvérové, optimalizačné postupy asi museli japončíci vymyslieť, aby to tam natlačili. Opúšťam teraz nintendo a preskakujem na megadrive, kde mi miestny borec Sonic hovorí, že len jeho vlastná animácia má cca 220 kilobajtov. Celá FF6 pre SNES má pritom 3 mega !! 

 
Sonic 3D Blast je posledná, vydaná sonic hra pre megadrive. Používa "izometrické" zobrazenie a hlavný hrdina nemá ručne urobenú pixel grafiku ale vyrenderovanú v 3D štúdiu s peknými odleskami. Hýbe sa do 16 smerov a v každom má 12 frejmov animácie. Vyzerá to v pohybe krásne ako CG panduľák z Toy Story. Celá táto paráda ale bez úprav zaberá 220 kilo. Takže toto číslo musíme zraziť dole zapojením mozgu a bez pomoci drahého čipu pre HW dekompresiu. Prvý redukčný krok je využitie faktu, že postavička v niektorých smeroch behá zrkadlovým otočením animácie. Nemusíme teda tieto dáta uložiť ale stačí ich v HW v smere osi otočiť. Už teda nepotrebujeme animáciu v 16tich ale iba v 9tich smeroch. Objem dát spadol na 121 kilo. Skoro na polovicu.

A ideme ďalej. Hlavný sprajt sonica je umiestnený na mriežke 6 x 6 znakov /znak je vlastne atribút veľkosti 8x8 pixel/. Neukladáme dáta všetkých 36 znakov ale iba 22, v ktorých sa pixely sonica reálne nachádzajú. Dokonca keď telo sonica úmyselne posunieme o pár pixelov v gride doprava, tak zistíme, že dosiahneme nižšie pokrytie plochy a úsporu 3 celých znakov a tých 19, ktoré v tomto momente potrebujeme už zaberajú len 64 kilobajtov. Sme opäť takmer o polovicu dole. A posledný krok. Pozrieme sa aj "dovnútra" jednotlivého 8x8 pixel znaku. Zistíme, že ani tam samozrejme nie je 100% pokrytie, takže použijeme triviálnu RLE kompresiu, ktorú zvládne aj 8 bit. V tomto bode bude mať celá animácia sonica vo všetkých smeroch na kartridži iba 53 kilobajtov, teda 25% pôvodnej veľkosti. Zázrak.

 
Sonic 3D Blast - intro

Zázrak do troch dní, nemožné na počkanie. Sonic 3D Blast totiž má aj plne renderované FMV intro /full motion video/. Základná matematika - 320x224 pixel krát 30 frejmov za sekundu krát 12.5 sekúnd dĺžky intra = 27 megabajtov na kartridži o kapacite 4 megabajtov !!  Takže optimalizujeme. Veľkosť frejmu stiahneme na 320x200 pixelov, rýchlosť videa na 15 snímkov za sekundu a použije sa farebná paleta o sile iba 16 farieb. Voilá a intro video už má iba 6 megabajtov. Do akcie nabehne RNC kompresia /Rob Northen compression/ v sofvérovom režime a v tom prípade by to mohla zabaliť až s efektivitou 3:1. Problém, je že naše CPU to nezvládne rozbaľovať v reálnom čase dostatočne rýchlo /iba cirka na úrovni 5 fps/.

Prepočet ukazuje, že dekodovaný obraz nemôže mať väčšiu veľkosť ako 256x80 pixelov. Ako však vidíte vo YT videu vyššie, tak intro pokrýva "celú" plochu obrazovku, nie len maličký výsek v strede. Na roztiahnutie obrazu na celú plochu /primitívny upscale/ využijeme schopnosť GPU /VDP - Video Display Processor/ megadrajvu, že DMA pri blokových presunoch dát dokáže generovať prerušenie /kontrolovaný horizontálny interupt/ na každom horizontálnom riadku a takto vlastne riadok zduplikujeme dvakrát po sebe a dosiahneme lepšie pokrytie plochy. Pokračujeme vertikálnym ditheringom a interlace alterovaním snímkovania s dosiahnutím lepšieho rozlíšenia videa /doslova ako šachovnicový checkerboard rendering či interlace upscale na PS4ke, heh/. Finálna veľkosť FMV intra po všetkých týchto krokoch je 660 kilobajtov namiesto pôvodných 27 megabajtov /v nekompromisne najvyššej kvalite/. Asi je vám jasné a sonic to potvrdzuje, že Call of Duty dev tím zjavne nerobí všetko preto, aby sme pri ďalšom diely ságy nemuseli sťahovať 350 gigabajtov dát. Stále platí, že tvrdé limity, ktoré sa snažíte nejako obísť, podporujú tvorivosť, inovácie. Hojnosť je pochabosť.