Jak přidat glow a 2D světla do staré 2D hry v Unity URP
Jak v Unity URP dát staré 2D hře selektivní glow přes Bloom a HDR, dynamická 2D světla a ostré UI pro dnešní displeje. Postup na příkladu hry Dreamica.

Stará 2D hra v Unity na vestavěném render pipeline vypadá na dnešním telefonu ploše: světlo chybí, glow buď není, nebo rozzáří celý obraz i s UI, a sprity rozhraní jsou rozmazané. V Unity URP to vyřešíte třemi věcmi: Bloomem s prahem 1 a HDR barvou jen na objektech, které mají zářit, 2D světly z 2D rendereru a UI s většími sprity, které respektuje bezpečnou oblast displeje.
Postup ukazujeme na naší hře Dreamica (App Store, Google Play). Je to pádová adventura, ve které prstem kreslíte čáry a jimi vedete bublinu se spícím dítětem přes čtyři světy. Původně vznikla v Unity 5.3, UI bylo v pluginu NGUI, glow obstarával plugin MK Glow a grafika byla připravená pro iPhone 7 s displejem 1334 × 750 pixelů. Hratelnost zůstala stejná, změnila se jen grafika.
Starou hru často otevřete kvůli obchodu, ne kvůli grafice. Google Play od srpna 2019 vyžaduje 64bitové verze a hra, která má jen 32bitový build, z něj vypadne. Přesně tak dopadla i Dreamica. Když už projekt převádíte do Unity 6, grafika je poměrně levný bonus.
Proč nestačí starý celoobrazovkový glow
Starší glow pluginy fungují jako celoobrazovkový efekt. Rozzáří všechno světlé včetně ikonek tlačítek v menu. V Dreamice ikonky pod MK Glow v Unity 6 skoro zmizely. Oficiální balík Post Processing Stack v2 je náhrada jen pro vestavěný pipeline, v URP se už neaplikuje. Pokud chcete glow, který řídíte po materiálech, a k tomu dynamická 2D světla, přejděte na URP a použijte Bloom, který je v něm zabudovaný.
Krok 1: Přepněte projekt na URP
Po přepnutí na URP narazíte ve staré 2D hře téměř jistě na dvě pasti. Obě se projevují tak, že obraz vypadá špatně nebo přesně jako předtím, přestože shadery jsou v pořádku.
Šedá obrazovka: nastavte zásobník kamer
Pokud herní okno v Editoru ukazuje jen šedou plochu, ale scéna v editoru i jednorázový render kamery vypadají správně, chyba není v shaderech, ale ve skládání kamer. Staré hry mívají dvě kamery, jednu na svět a jednu na UI, a UI kamera maže jen hloubku. Tak se vrství kamery ve vestavěném pipeline a URP to nepodporuje. Potřebuje explicitní zásobník kamer (camera stack): jedna kamera je základní (Base), ostatní jsou překryv (Overlay) zařazený do jejího zásobníku. Nastavte ho v každé scéně, kde se kamery vrství.
Sprity ignorují světlo: přepněte na 2D renderer
Sprity s osvětleným shaderem nereagují na žádné světlo, pokud běží běžný URP renderer. Ten 2D světla vůbec nepočítá. Přepněte na 2D renderer. Ani ten ale osvětlení nekreslí, dokud ve scéně není alespoň jedno 2D světlo. Když něco po změně vypadá přesně jako předtím, nejdřív zkontrolujte, který renderer běží.
Částice a staré pluginy
Částice na starých shaderech se pod 2D rendererem kreslí černě nebo vůbec. Dejte jim nový jednoduchý shader.
Pozor i na Asset Store. Při obnovení assetů umí Editor sám aplikovat „aktualizaci“ starého pluginu, která přidá metadata a přejmenuje shadery. Materiály hledají shader podle jména, takže se potichu rozbijí. Po každém větším obnovení assetů ve starém projektu si ve verzovacím systému projděte všechny změněné soubory, i ty, na kterých zrovna nepracujete.
Krok 2: Selektivní glow přes HDR barvu a Bloom s prahem 1
Cílem je, aby zářily vybrané objekty, v Dreamice nakreslená čára, lasery, jiskry, světlušky a runy, ale ne pozadí a UI. Bloom v URP rozmaže a přičte všechno, co je jasnější než jeho práh. Nastavte práh na 1 a materiálům, které mají zářit, vytlačte barvu nad 1.
shader čáry:
barva = textura × barva vrcholu × odstín × intenzita (intenzita = 6)
Bloom:
práh = 1, síla = 0,3
září jen to, co má po výpočtu jas nad 1
Pozadí a tlačítka mají barvy od 0 do 1, přes práh neprojdou a zůstanou ostrá. Tím zmizí i problém s vybělenými ikonkami. Podmínkou je kamera s HDR. Bez něj se barva ořízne na 1 a nezáří nic. 2D renderer přepínač HDR v inspektoru kamery neukazuje, proto ho zapněte skriptem.


Když je glow takto pod kontrolou, nemusí být volitelný. V Dreamice jsme přepínač glow z nastavení zrušili, glow je součást vzhledu.
Emisní mapa: září jen část spritu
Pokud má zářit jen část spritu, přidejte mu emisní mapu (emission map): druhou, černobílou texturu, která říká, která část spritu září. Jen ta část dostane barvu nad 1, takže u runy svítí jádro, ne celý obrys.

Pulzování v expozičních stupních
Pokud má záření pulzovat, nenásobte barvu lineárně. HDR materiál může mít jas kolem 2 na osmou a lineární násobení od 0 do 10 na něm není vidět vůbec. Pulz počítejte v expozičních stupních (EV), stejně jako posuvník intenzity ve výběru HDR barvy v Unity:
barva = odstín × 2 ^ ev, ev kmitá mezi minimem a maximem
Krok 3: Dynamické 2D světlo kolem hráče
K hráči dejte bodové 2D světlo a kolem něj měkkou záři. V Dreamice jedna sinusovka řídí zároveň jas záře, poloměr světla i jeho intenzitu, takže pulzují spolu. Barvu světla může určovat prostředí: v lese je bílá, v bažině oranžová, v zimě fialová, v pekle žlutá. Pozadí a překážky přepněte na osvětlené shadery, jinak na světlo nereagují.
Krátká světla oživí události. Když vystřelí veverka s dělem, rozsvítí se jantarové světlo s intenzitou 3, které za 0,3 sekundy zhasne, a jiskry z hlavně září. Zářit nemusí všechno: prach při zmizení žaludu je záměrně hnědý a nezáří.
Stejný shader na navazujících plochách
Pokud na sebe navazují dvě pozadí, zdrojové obrázky mají stejný jas, a přesto je mezi nimi vidět šev, zkontrolujte shadery. V Dreamice mělo úvodní pozadí a nekonečné pozadí lesa každé jiný shader. Jeden odstín materiálu 0,733 ignoroval, druhý ho použil a ztmavil les na 73 %. Řešením je stejný shader na obou plochách.


Záblesk: přechod na vrchol místo přičtení
Při přechodu do dalšího světa světlo a záře vzplanou: náběh 0,6 sekundy, krátké podržení, doznění 1,4 sekundy a záře se přitom jednou otočí. Pokud záblesk jen přičtete k pulzu, vrchol závisí na tom, v jaké fázi je sinusovka zrovna v tu chvíli, a každý záblesk je jinak silný. Plynule přejděte z pulzu na pevný vrchol:
váha = křivka záblesku (0 až 1)
hodnota = pulz + (vrchol - pulz) × váha


Krok 4: Ostré UI pro dnešní displeje
UI kreslené pro iPhone 7 má malé sprity. Tlačítko v menu Dreamicy mělo sprite 128 × 64 pixelů a na telefonu s trojnásobnou hustotou bodů se roztahovalo na několikanásobek. Překreslete sprity ve větším rozlišení: nové tlačítko má 800 × 434, ukazatele postupu narostly z 200 × 26 na 800 × 104.


Pokud UI stojí na NGUI, zvažte přepis. Kotvy v NGUI se dopočítávají po částech během několika snímků, dlouhé řetězy kotev se občas ustálí špatně a měřítko se liší mezi Editorem, telefonem a iPadem. V Dreamice to opravy spolehlivě nevyřešily, proto jsme UI přepsali na uGUI a TextMeshPro. Postupujte obrazovku po obrazovce a starou verzi mějte zapnutou vedle jako předlohu. UI škálujte podle výšky vůči referenčnímu rozlišení (u nás 434 × 941 bodů) a respektujte bezpečnou oblast displeje, tedy výřez a zaoblené rohy. Po přepisu NGUI z projektu úplně odstraňte, ať v něm nezůstanou dva systémy UI.
Limity: nekomprimované textury
Tento postup mění jen grafiku. Textury jsme v Dreamice záměrně nekomprimovali, protože jsme chtěli plnou ostrost. Cenou je velikost: už původní hra měla v Editoru 313 MB textur v paměti a v App Store má 299 MB. Komprese by podle našeho odhadu zmenšila textury přibližně na 40 MB. Pokud vám na velikosti hry záleží, je to první místo, kde ušetřit.
Jiný příklad Unity hry od prvního řádku kódu po vydání najdete v článku o hře Space Impact Watch, výkonu v Unity se věnuje článek o navigaci hordy v Unity DOTS. Pokud je hra ještě v Unity 4, neotevírejte ji přímo v Unity 6; bezpečný postup popisuje návod jak převést projekt z Unity 4 do Unity 6. Pokud máte starou Unity hru, která vypadla z obchodů, a chcete ji vrátit zpět, ozvěte se nám.


