Postup zpracování aplikace v Unreal Engine
Unreal Engine je ideálním nástrojem pro tvorbu produktů založených na potřebě real-time renderingu. V minulosti šlo především o hry, dnes se hojně využívá k simulacím, virtuální realitě, tréninkovým programům, architektonickým vizualizacím, tvorbě filmů, videí, živých vysílání i prezentaci digitálních produktů v řadě odvětví. Jak se tyto věci tvoří? Názorný postup prací a klíčové atributy každého kroku přiblíží tento článek.
Jednotlivé kroky se mohou ve větší či menší míře v závislosti na konkrétní aplikací měnit. Níže popsaný postup je relevantní k jedné z aktuálně nejrozšířenějších a znalostně nejjednodušších aplikací - architektonickým vizualizacím. Článek je součástí seriálu o Vývoji VR aplikací v herním enginu Unreal.
1) Založení projektu
Při repetitivních projektech, kdy se tvoří řada podobných aplikací, je optimální startovat ze šablony, která již obsahuje veškerá potřebná nastavení a knihovny assetů (materiály, modely, audio, scripty, komponenty...) pro konkrétní zaměření projektu. V takovém případě se v rámci tvorby již řeší pouze samotný obsah projektu.
Začátek ze šablony prakticky znamená pouze zkopírovat si složku se starter projektem určeným pro konkrétní užití a přejmenovat ji na název konkrétního projektu. Poté otevřít a následovat ke kroku 2 - Práce s levely v Unreal Engine.
2) Práce s Levely (a assety)
Kapitolou prací s levely lehce předbíhám, přesto, je to z dobrého důvodu. Pro efektivní práci v Unreal Engine je nezbytné znát principy fungování modelů a dalších assetů v Unreal Engine, jež je velmi snadné vysvětlit právě na příkladu levelů.
Jak Unreal Engine pracuje s assety?
Assetem je chápán jakkýkoli soubor (3D model, textura, materiál, hudba, script...) vložený do Unreal Engine, respektive kdekoli v rámci jeho složky "Content" a jejích podsložek. V některých případech při vkládání dochází k převodu vkládaného souboru do Unreal formátu, jindy se pracuje s výchozím, což může obnášet potřebu převodu souboru do vhodného formátu ještě před importem do Unreal Engine. Naštěstí je na webu řada užitečných konvertorů. (Převod audia, převod cubemaps...)
Assety se v Unreal Engine po importu / modifikaci ukládají separátně od samotného levelu (= mapy / scény, v němž jsou např. vloženy). Zatímco level a k němu přidružené nastavení uložíte tlačitkem "Save Current" v toolbaru Unrealu, Assety je nezbytné ukládat tlačítkem "Save all" v okně "Content Browser". Je to z toho důvodu, že Levely na assety pouze odkazují, případně přepisují jejich vlastnosti, hned si to vysvětlíme.
Pokud jde o 3D modely, v Unrealu známe jako StaticMesh, veškeré výchozí nastavení modelu (materiál, LODs, Kolize, Lightmapy atd.) je svázané se samotným objektem (StaticMesh). Pokud takovýto objekt vložíme přetažením do levelu (scény aplikace), v levelu se objeví jako obsah objektu "StaticMeshActor".
StaticMeshActor lze chápat jako prvek s definovanou lokací (sořadnice XYZ + rotace + měřítko) v rámci levelu, jež se vizuálně prezentuje jako k němu přiřazená StaticMesh. StaticMeshActor se tedy odkazuje pouze na určitý 3D model, a tedy kdykoli uděláme jakoukoli modifikaci na daném 3D modelu, tato změna se automaticky projeví ve všech StaticMeshActorech, jež na něj odkazují. To se týká vždy samotné sítě (tvaru modelu), pokud jde však o k němu přiřazené materiály, fyziku, kolize či jemnost mapy nasvětlení (lightmass), StaticMeshActor umožňuje přepis defaultních vlastností StaticMesh v rámci použití v onom konkrétním StaticMeshActoru. Ihned vysvětlím na příkladu - máte model restaurace s 6 identickými lustry. Potřebujete mít některé rozsvícené, jiné zhasnuté. 4 s černou objímkou, 2 s bílou. Tvar lustru zůstává identický.
Box "Transform" definuje polohu prvku StaticMeshActor v prostoru. Box "Static Mesh" informuje o přiřazeném 3D modelu (Static Mesh). Na základě přiřazeného 3D objektu (box Static Mesh) je v "StaticMeshActoru" vyplněn i box "Materials" a řada dalších, vždy dostupných v rámci totožného okna "Details".
Tato provázanost umožňuje následující. Vysvětlení provedu na materiálu, ovšem platí pro veškeré vlastnosti 3D modelu.
- Změníme-li materiál v boxu "Materials" StaticMeshActoru, daná změna se projeví pouze na daném konkrétním StaticMeshActoru, v našem případě označeném lustru.
- Pokud však změnu provedeme v 3D objektu (Static mesh - otevřeme jej dvojklikem na náhled v boxu "Static Mesh") namísto "StaticMeshActoru", tato změna se projeví na všech ve všech "StaticMeshActorech" odkazujících se na daný model, jež nemají přiřazený přepis (viz odrážka výše)
Zpátky k příkladu. Pokud ze šesti lustrů mají být 4 černé, jednoduše jako defaultní materiál v "Static Mesh" prohlížeči přiřadíme černou a tu v případě dvojice bílých lustrů přepíšeme pomocí nastavení "StaticMeshActoru". Obdobně pro světlo - rozsvícením přiřadíme emisivní materiál, zhasnutým standardní. Výsledkem je, že v případě potřeby modifikace sítě lustru, lightmap, nebo kolizí se veškeré změny projeví na všech lustrech, zatímco si jednotlivé lustry stále zachovávají své tížené vlastnosti.
Jak Unreal Engine pracuje s levely?
Nyní si konečně můžeme vysvětlit funkci levelů. Level je scéna - definuje to, co vidíme. Obsahuje tedy veškeré "StaticMeshActory" definující 3D modely ve scéně + řadu dalších komponent pro nasvícení, ozvučení, efekty, funkcionalitu a další prvky scény. Jakékoli modifikace "StaticMeshActoru" a všech dalších prvků mapy / scény jsou uloženy pouze v rámci daného levelu.
Levely v Unreal Engine nemusí pracovat samostatně - lze je vzájemně slučovat do jedné mapy / scény složené z několika levelů. Správa levelů ve scéně je dostupná skrze okno "Levels" (Window / levels).
Jednotlivé komponenty lze mezi levely jednoduše přesouvat. Levely lze používat ve 2 streamingových metodách - Blueprint a Always Loaded (načte do scény vše okamžitě).
Jaké možnosti práce s více levely v rámci jedné mapy přináší?
Řekněme, že si chcete v rámci jednoho modelu vyzkoušet více možností např. nasvícení (den / noc..). Zkrátka, sdílet určité prvky napříč více levely. V případě, že by jste pracovali vždy pouze s jedním levelem, jakákoli změna v levelu není replikována do ostatních. Pokud by jste například chtěli do modelu přidat další objekt, nebo jen upravit lokaci jednoho modelu, je třeba danou změnu provést ručně ve všech levelech. Naproti tomu, pokud aplikujete rozdělení prvků aplikace do jednotlivých levelů načtených v rámci jedné mapy, veškeré modely máte pouze v jednom levelu, jež poté načtete do levelu, jež je unikátním (nasvícení 1, nasvícení 2). V takovém případě veškeré změny v levelu "model" se automaticky projeví v levelu "nasvícení 1" i "nasvícení 2".
Vyjma nasvícení se do samotných levelů separují např. FX efekty, hudba a další. Pravidel moc neexistuje, rozvrh levelů / použití je vždy na tvůrci.
Naneštěstí, na jednu věc je nutné myslet, zejména při používání levelu obsahující static meshes. V jejich případě dochází při buildu k zapékání (baking) světelnosti, odrazů a dalších. Zapečení se přitom ukládá do souboru svázaného s daným levelem. Při potřebě měnit levely v rámci aplikace je tedy nutné minimálně před konečným buildem doposud sdílený level se static meshes zduplikovat do více a správě rozřadit, aby nedocházelo ke konfliktům v zapečených datech napříč mapami aplikace.
3) Import 3D modelů do Unreal Engine
Unreal Engine umožňuje import 3D modelů 2ma způsoby:
- Klasický import přes zelené tlačítko "Add/Import" okna "Content Browser"
- Import přes DataSmith, ikona v toolbaru Unreal (nutno mít aktivní plugin DataSmith - Edit → Plugins). Datasmith při importu model vkládá i přímo do levelu - pozor na to. Ideálně mít při importu otevřen nový prázdný level.
V případě obou způsobů je při importu možnost úpravy řady možností. Výběr je odvislý od typu importovaného souboru - datasmith umí importovat pouze .udatasmith (a .3dm) soubory. naproti tomu však neimportuje jednoduché kolizní modely.
V rámci importu lze předchozí modely přepisovat novými. V takovém případě je starý model nahrazen novým ve všech místech aplikace odkazujících na "předchozí" model.
4) Zpracování naimportovaných modelů
Naimportované modely reflektují nastavení jim přiřazené v softwaru, v němž byly vytvořeny. V případě importu skrze Datasmith jsou zpravidla dobře naimportovány i materiály, u běžného importu to tak veselé není - je vyžadováno redefinování materiálů (v podstatě znovu je "vytvořit"), případně hromadně nahradit jiným.
Dále by vás při pohledu na model v rámci výkonové náročnosti měl zajímat počet jeho objektů a počet jejich polygonů. Rovněž rozlišení textur přiřazených k materiálům. Obojí naleznete v okně statistik, jež je možné otevřít přes nabídku Window/Statistics. V případě potřeby je možné redukci rozlišení textur i polygonů provést v okne "StaticMesh" jednotlivých objektů, stejně jako hromadně pomocí možnosti "bulk edit" (označení mesh actorů, např vybráním ve scéně a stisknutím ctrl+b a poté pravé tlačítko myši → Asset Actions → Bulk Edit → Maximum Texture Size (texture size volte vždy v násobcích řady 64,128,256,512,1024,2048,4096. Počty polygonů lze hromadně měnit jen v rámci LOD, avšak doporučováno je redukci provádět u problémových komponent (= s vysokým počtem polygonů) jednotlivě v okně static mesh tak, aby vždy bylo dosahováno optimálního poměru počtu polygonů a vzhledu. V případě potřeby sloučení objektů lze používat nástroj pro mergování, v případě naopak přidávání nových dílů nástroj pro geometrické modelování. Technický přístup k obsahu a tvorbě je podrobně rozebrán v článku zaměřeném na technický design aplikací.
Chybné normály lze opravovat pomocí nástroje "mesh editing" dostupného v editaci static mesh. Komplexnější úpravy je nutné provádět v externích modelovacích softwarech.
5) Vložení požadovaných funkcionalit
Mechanismus pohybu, ovládacích prvků a jiné je v projektu nativně aktivován a nastaven již v rámci šablony (GameInstance + GameMode) a není je třeba řešit. Jediné, čím se tedy tvůrce zabývá, jsou funkční prvky úplatné konkrétním objektům v levelu. Jejich funkčnost lze napsat, případně pouze přiřadit, pokud již existuje - například opět v rámci oné šablony.
S funkcionalitou úzce souvisí kolizní modely. Náhled na kolizní objekty v mapě snadno získáte v rámci módu zobrazení (view mode) "Player Collision". Možnost naleznete rozklikem tlačítka "Lit" označující výchozí Lit mód zobrazení. Kolizní modely lze přidat buď v nastavení StaticMesh (zobrazení přes tlačítko "Collisions") v Toolbaru. Přidání jednoduchého kolizního modelu je možné přes možnost "Collision → Add ...", případně lze aktivovat použití komplexního kolizního modelu jako jednoduchého v možnosti "Collision Complexity" boxu "Collision". Pokud by žádná z možností nevyhovovala, požadovaný kolizní model lze do Unrealu i naimportovat. Samotné neviditelné zábrany lze nicméně vložit do scény i samostatně, a to prostřednictvím objektu "Blocking Volume" dostupného v okně "Place Actors" (Window/Place Actors). V základním "Collision Presets = InvisibleWall" nastavení brání v pohybu hráče, při nastavení "InvisibleWallDynamic" i veškeré dynamické objekty v mapě. To je velmi užitečné například při práci s Physics Constraint, které neumí offset a tedy přesné vymezení pohybu pouze prostřednictvím jeho limitů nemusí být vždy rychle a jednoduše proveditelným.
6) Nasvětlení mapy (scény)
Správné nasvětlení scény je klíčovým aspektem jakéhokoli vnějšího či vnitřního prostoru. Rozhoduje nejen o světlosti a stínech, ale rovněž vzhledu jednotlivých materiálů. S vhodně nastaveným post-processingem a odrazy světla udává vizuální atmosféru celé aplikace. Pod pojmem nasvětlení nelze přitom pouze chápat vložení různých typů světel a nastavení intenzity a vlastností jejich svitu, ale rovněž případné nastavení a opravu lightmap.
Nasvětlení scény je optimální startovat od nuly - tzn, s deaktivovanými veškerými zdroji světla v mapě. Po stisknutí tlačítka Build v toolbaru Unrealu (rychlejší je zvolit pouze Build Lightning, a ještě lepší nastavit před tím volbu lighting quality na Preview), měli by jste získat zcela tmavou scénu. Pokud je vaše scéna stále světlá, může to být z důvodu aktivního "Auto Exposure" dostupného v "Project settings". S Exposure lze rovnež manipulovat i přímo ve scéně, jeho hodnota se nachází ve spodní části okna s "View modes" možnostmi (tlačítko "Lit" ve Viewportu).
Prvním vloženým / aktivovaným světlem v mapě bývá obvykle "Directional Light". Jedná se o imitaci svitu slunce / měsíce. Následují další zdroje světel dle potřeby mapy.
Hlavní parametry světelných zdrojů jsou následující:
- Poloha a úhel natočení
- Mobilita = s jakými tělesy interagují při tvoření stínů
- Intenzita svitu, případně dosah, velikost kužele svitu, teplota svitu a podobně.
- Affect World = zda zdroj světla ovlivňuje jakékoliv objekty mapě (= aktivace / deaktivace světla)
- Cast Shadow = zda dané světlo vrhá stíny
- Indirect Lighting intensity = jak se dané světlo odráží v prostředí a celkově jej prosvětluje. Funguje jen pro Static a Stationary mobility). Využití je zejména při nasvětlování interiérů a prostředí s mnoha zákoutími bez přímého dopadu svitu ze zdroje světla.
- Lighting channels = kanály, které daný zdroj zohledňuje při svém svitu (umožňuje vyloučit ovlivňování určitých objektů určitým zdrojem světla)
Lepší náhled na světelnost prostředí v závislosti na nastavení světelných zdrojů lze získat přepnutím view módu do možnosti "Lighting only" nebo "Detail Lighting", z hlediská výkonu rovněž "Light Complexity" v podnabídce "Optimization Viewmodes". Kromě výše zmíněných v možnostech View Módu najdete i možnost "Reflection". Přes ní lze nahlédnout blíže na odrazy způsobované vloženými Reflection actory.
Částečně již v "Lighting only" módu, ale zcela určitě bu Buildnutí nově nastavených světel (tlačítko Build lighting) můžete objevit řadu chyb týkajících se nasvětlení:
- Nedostatečně jemné přechody světla na povrchu - důvodem je nízké Light Map Resolution
- Objekt nereaguje / reaguje špatně na světelné zdroje - důvodem je jsou chybná UV. UV generuje Unreal automaticky při importu (pokud je aktivováno) modelů. V případě mnoha updatů (reimportů) modelu z externího softwaru však dochází ke generování UV map nových, přičemž ty staré nemusí být smazány. Unreal se přitom může odkazovat právě na ty staré. UV mapy k jakékoli Static Mesh si lze prohlédnout pro tlačítkem "UV" v Static Mesh prohlížeči. Chybné UV lze mazat, nové generovat pomocí tlačítek "Generate" a "Unwrap". Unrealu lze i přikázat, který UV kanál má pro lighting používat, a to prostřednictvím možnosti "Source Lightmap Index".
Nastavení Min Lightmap Resolution a ukázka Lighting UV map - Tmavost stropů v interiéru, rohů, míst, kam světlo nedosvítí - V případě otevřených map lze světelnost prostředí a rozptyl světla řídit použitím actorů Skylight a SkyAtmosphere. Často v kombinaci s možností "Indirect Lighting intensity" různých zdrojů světla. V případě map využívajících 360° fotek (HDRi cubemaps) pro prezentaci okolí se poté pracuje hlavně s Indirect Lighting intensity.
Obecné parametry pro světelnost prostředí lze nastavovat v boxu Lightmass okna "World settings". Rychlý přístup k světlém prostředí je prostřednictvím okna Window/Env. Light Mixer.
7) Post-processing
Post-processing umožňuje aplikaci různých metod zvyšujících kvalitu obrazu. Odhlédneme-li od jeho aplikace v rámci zvýrazňování objektů, hlavním posláním post processingu je jemná úprava finálního vzhledu k utvoření lepší atmosféry. PostProcessing se nastavuje prost5ednictv9m actoru "PostProcessVolume".
8) Packaging (vybuildování aplikace)
Buildování aplikace se v Unrealu nazývá packaging. Nastavení packagingu lze nalézt v "Edit/Project Settings/Packaging". Nejčastěji upravovaným parametrem zde je možnost "List of maps to include in a packaged build" dostupná v rozkliku boxu "Packaging". Ostatní údaje jsou předvyplněná v rámci šablony (viz odstavec 1). Co však dále v rumci packagingu je nutné vyplnit jsou údaje o projektu (minimálně Project name a version) v záložce "Description" okna Project Settings a poté v záložce "Maps & Modes" přiřadit defaultní mapu, která se má v rámci spuštěné aplikace načíst jako první (možnost "Game Default map"). Následně lze již okno Project Settings zavřít a pod záložkou File → Package Project spustit buildování pro konkrétní platformu.
Zpětný pohled na zpracování modelu restaurace
- Chybějící stěny a základní tvary vytvořeny v Unreal s pomocí geometrických nástrojů
- Mechanismus HS portálu, krb a další dekorační prvky z VRealMatic komponent
- Stavební úpravy podlahy a stěn pro vložení zanořených noframe oken v Blender
- Stoly, židle, prostírání od 3D designéra