Faza 3: Runtime Streaming
Ovaj dokument opisuje kako se uvezeni/upakirani sadržaj (Faza 2) stvarno prikazuje i učitava tijekom igranja — koje komponente postoje, koji su im parametri u Inspectoru i po kojem principu rade. Projekt sadrži tri usporedna runtime streaming sustava, razvijana u različitim fazama projekta, svaki sa svojim pristupom i svojim setom komponenti:
| Sustav | Glavna komponenta | Podaci koje čita | Princip |
|---|---|---|---|
| Klasični (scene-based) | TerrainStreamingController (+ BasemapController) |
Direktne reference na Unity Terrain/prefab objekte unutar CityDataset asseta (Fazu 2, Dataset Import Manager) |
Jednostavan radius-based load/unload oko kamere; ili "SetActive" (samo toggle vidljivosti već postavljenih objekata), ili "Runtime" instanciranje iz TerrainData/prefaba |
| Realtime (bundle-based) | RealtimeStreamingController |
AssetBundle-ovi + StreamingDatasetManifest iz StreamingAssets/ZGConnect/ (Faza 2, RealTime Asset Importer) |
Radius-based load/unload, ali sadržaj se učitava iz bundleova (Addressables-free), prikladno za build bez source assets-a |
| Spatial (HLOD ring-based) | SpatialStreamingController |
spatial_manifest.json iz zasebnog bake pipelinea (SpatialBakePipeline, opisano niže) |
Napredniji sustav — koncentrični LOD prstenovi oko kamere, hijerarhijski HLOD2/HLOD4 supertileovi, budžetirano opterećenje po frameu |
Ovaj dokument prolazi kroz sva tri sustava redom, počevši od najjednostavnijeg
(TerrainStreamingController) prema najsloženijem (SpatialStreamingController), objašnjavajući
svaku Inspector opciju, njeno zadano ponašanje i princip rada u kodu.
Napomena o opsegu: postoji i četvrti folder,
PhotogrammetryStreaming/(Google 3D Tiles/Cesium-style streaming), ali je on označen kao napušten/deprecated unutar projekta (Google photogrammetry integracija nije više cilj projekta) i namjerno je izostavljen iz ove dokumentacije.
Dio 1: TerrainStreamingController (klasični, scene-based streaming)
Skripta: Assets/ZGConnect/Runtime/TerrainStreamingController.cs (79 654 bajtova), custom
inspector: Assets/ZGConnect/Editor/ZGConnectStreamingControllerEditor.cs.
Princip rada
Komponenta puni/prazni terrain pločice oko kamere na temelju udaljenosti, automatski birajući jedan od dva režima po pločici:
- SetActive režim — pločica već ima unaprijed postavljen scene objekt
(
CityTileRecord.sceneObject != null, npr. jer je uvoz radio s uključenom opcijom "Create Scene Objects" u Dataset Import Manageru, ili je pokrenut gumb "Instantiate All Terrains"). Streaming tada samo uključuje/isključuje (SetActive) postojeći GameObject — nema instanciranja ni uništavanja. - Runtime režim — pločica nema scene objekt. GameObject se instancira iz
CityTileRecord.terrainData(ili preko Addressables reference,terrainDataRef) kada pločica uđe u radijus učitavanja, i uništava kad izađe iz radijusa isključivanja. Ne zahtijeva prethodni scene setup.
Oba režima mogu koegzistirati unutar istog dataseta — inspector prikazuje status ("SetActive
mode" / "Runtime mode" / "Mixed mode") na temelju toga koliko pločica ima sceneObject postavljen.
Inspector — Dataset
| Polje | Tip | Opis |
|---|---|---|
| Dataset | CityDataset |
Asset koji vozi cijeli streaming — sadrži popis svih CityTileRecord pločica (referenca na terrain podatke, zgrade, vegetacijske maske) |
| Camera Transform | Transform |
Kamera oko koje se računaju udaljenosti. Ako je prazno, automatski se koristi Camera.main pri pokretanju |
Inspector — Terrain Rendering
| Polje | Opis |
|---|---|
| Terrain Material | URP Terrain/Lit (ili kompatibilan) materijal primijenjen na runtime-instancirane pločice. Obavezan za ispravan render u buildu, pogotovo kad je uključen Draw Instanced |
Inspector — Radii (meters)
| Polje | Zadano | Opis |
|---|---|---|
| Load Radius | 3000 m | Pločice čiji je najbliži rub unutar ove udaljenosti od kamere se učitavaju |
| Unload Radius | 5000 m | Pločice čiji je najbliži rub izvan ove udaljenosti se rasterećuju. Mora biti veći od Load Radius radi histereze (sprječava treperenje load/unload na granici jednog radijusa) |
Inspector — Performance
| Polje | Zadano | Opis |
|---|---|---|
| Check Interval | 0.5 s | Razmak između evaluacijskih prolaza streaminga (koliko često se provjerava koje pločice treba učitati/rasteretiti) |
| Quality Preset | Medium | Low / Medium / High / Custom — grupni preset koji odjednom postavlja hrpu donjih LOD/kvaliteta polja (vidi tablicu ispod). Custom ostavlja sva polja ručno kontrolirana |
| Max Loaded Tiles | 9 (default u kodu; ignorira se osim za Custom preset) |
Maksimalan broj istovremeno učitanih pločica (aktivnih + na čekanju). Svaka pločica troši ~15–80 MB VRAM-a ovisno o tipu i rezoluciji basemapa |
Quality Preset — stvarne vrijednosti koje se primjenjuju (ApplyQualityPreset()):
| Parametar | Low | Medium | High |
|---|---|---|---|
| Max Loaded Tiles | 16 | 48 | 128 |
| Basemap Distance | 800 | 2000 | 4000 |
| Pixel Error Near/Mid/Far | 8 / 12 / 18 | 3 / 6 / 10 | 1.5 / 3 / 6 |
| Pixel Error (fallback) | 12 | 6 | 3 |
| Terrain LOD Near/Mid Distance | 500 / 2000 m | 800 / 3000 m | 1200 / 5000 m |
| Terrain Texture Mip Far | 4 | 3 | 2 |
| Far Basemap Resolution N/M/F | 1024/512/256 | 2048/1024/512 | 2048/1024/512 |
| Streaming Mipmaps Budget | 512 MB | 1024 MB | 2048 MB |
| Streaming Mipmaps Max Reduction | 4 | 3 | 2 |
Napomena o dokumentaciji u kodu: XML komentar na
enum TerrainQualityPresetnavodi "Low = up to 4 tiles", "Medium = up to 9 tiles", "High = up to 16 tiles" — ovo su zastarjeli brojevi u komentaru; stvarne vrijednosti kojeApplyQualityPreset()postavlja su 16/48/128, kako je prikazano gore. Dokumentacija ovdje prati stvarno ponašanje koda, ne komentar.
Ako je terrainLodEnabled uključen, preset dodatno postavlja tri Unity QualitySettings globalne
vrijednosti: streamingMipmapsActive, streamingMipmapsMemoryBudget,
streamingMipmapsMaxLevelReduction.
Inspector — Runtime Terrain Root
| Polje | Opis |
|---|---|
| Terrain Root | Roditeljski transform za runtime-instancirane terrain pločice. Ako je prazan, automatski se stvara GameObject "ZG Connect Terrains (Runtime)" |
Inspector — Terrain Quality (Runtime Mode)
Ova polja se koriste samo za pločice instancirane u Runtime režimu (ne SetActive):
| Polje | Zadano | Opis |
|---|---|---|
| Draw Instanced | true | drawInstanced postavka primijenjena na runtime-instancirane terene |
| Basemap Distance | 2000 | Unity Terrain.basemapDistance — udaljenost na kojoj puni splat detalj prelazi u pečeni basemap. (Prebrisuje se dinamički ako je Dynamic Terrain Texture LOD uključen — vidi niže "Near Terrain Basemap Distance") |
| Dynamic Heightmap LOD | true | Kad je isključeno, Pixel Error Near/Mid/Far se ignoriraju i koristi se jedinstveni "Pixel Error" za sve udaljenosti |
| Pixel Error Near / Mid / Far | 2 / 5 / 10 | heightmapPixelError kad je kamera unutar/blizu pločice (Near), na srednjoj (Mid) ili velikoj (Far) udaljenosti |
| Pixel Error (fallback) | 5 | Koristi se za sve udaljenosti kad je Dynamic Heightmap LOD isključen |
Inspector — Terrain LOD
| Polje | Zadano | Opis |
|---|---|---|
| Terrain Lod Enabled | true | Glavni prekidač. Kad je isključen, ne radi runtime LOD — primjenjuju se samo Basemap Distance i Pixel Error iz gornje sekcije |
Inspector — Terrain LOD Distances
| Polje | Zadano | Opis |
|---|---|---|
| Terrain Lod Near Distance | 800 m | Maksimalna horizontalna udaljenost od granica pločice za Near tier (0 m kad se stoji na pločici) |
| Terrain Lod Mid Distance | 3000 m | Maksimalna udaljenost za Mid tier. Iznad ovoga koristi se Far tier |
Ove tri distance-tier vrijednosti (Near/Mid/Far) koriste se dosljedno kroz sve LOD sekcije ispod (teksture, far basemap rezolucija, basemap distance boost).
Inspector — Terrain Texture LOD (close-up quality)
Ovo kontrolira blizinsku kvalitetu terena — ono što se stvarno vidi izbliza (za razliku od
baseMapResolution, koji utječe samo na daleki render).
| Polje | Zadano | Opis |
|---|---|---|
| Dynamic Terrain Texture LOD | true | Prisiljava pune-rezolucije mipmape na terrain layer teksturama kad je kamera blizu |
| Enable Global Texture Streaming | true | Unity globalni texture streaming. Isključi za test je li mutan teren posljedica mip budžeta (troši više VRAM-a kad je isključeno) |
| Terrain Texture Mip Near / Mid / Far | 0 / 1 / 3 | requestedMipmapLevel na Near/Mid/Far udaljenosti (0 = najoštrije). Utječe samo na teksture importane sa Streaming Mipmaps |
| Near Terrain Basemap Distance | 20000 | Dok je kamera unutar Near pojasa, Terrain.basemapDistance se privremeno diže na ovu vrijednost, kako bi Unity zadržao splat/layer detalj umjesto da prijeđe na daleki basemap |
Inspector — Far Basemap LOD (VRAM only)
Utječe samo na render dalekih pločica (TerrainData.baseMapResolution), ne mijenja izbliza
kvalitetu splata.
| Polje | Zadano | Opis |
|---|---|---|
| Dynamic Far Basemap LOD | true | Uključuje dinamičko podešavanje baseMapResolution po udaljenosti |
| Far Basemap Resolution Near / Mid / Far | 2048 / 1024 / 512 | Rezolucija far-basemap teksture ovisno o tier-u |
Inspector — Buildings
| Polje | Zadano | Opis |
|---|---|---|
| Stream Buildings | true | Kad je uključeno, grupe zgrada se streamaju uz odgovarajuću terrain pločicu. Prefab-based zgrade (buildingsLod0Prefab postavljen) se Instantiate-aju pri učitavanju i Destroy-aju pri rasterećenju; starije scene-object zgrade (buildingsSceneObject) koriste SetActive kao fallback |
| Buildings Root | — | Roditeljski transform za instancirane grupe zgrada. Auto-kreira se kao "ZG Connect Buildings (Runtime)" ako nije postavljen |
| Building Destroy Delay | 30 s | Koliko sekundi rasterećena grupa zgrada ostaje u memoriji (neaktivna) prije uništenja — omogućuje trenutnu ponovnu aktivaciju ako se kamera vrati unutar ovog prozora |
| Max Inactive Building Groups | 10 | Maksimalan broj neaktivnih grupa zgrada držanih u memoriji tijekom grace perioda. Kad se limit dosegne, najstarija grupa se uništava odmah, bez obzira na delay |
| Stagger Building Activation | false | Kad je uključeno, grupa zgrada pločice se instancira sa svakom direktnom child zgradom deaktiviranom, zatim se otkriva X-sweep animacijom od zapadnog prema istočnom rubu pločice |
| Building Sweep Speed | 100 m/s | Brzina sweep animacije duž svjetske X osi (zapad→istok), dok je Stagger Building Activation uključen |
| Building Reveal Duration | 0.35 s | Trajanje lerp-a localScale.z svake zgrade od 0 do pune veličine kad je sweep aktivira |
| Apply Shared Building Materials | true | Zamjenjuje ugrađene GLB materijale zajedničkim project materijalima pri instanciranju pločice |
| Building Surface Settings | — | Facade/roof materijal profili (isti asset kao kod importa u Fazi 2) |
| Building Material Style | FacadeAndRoofVariants | Kako se materijali dodjeljuju — mora odgovarati načinu na koji su zgrade uvezene (vidi tablicu enum vrijednosti niže) |
| Roof Orthophoto Basemap Id | "ortho" | Basemap id na CityTileRecord-u za roof orthophoto režim |
| Roof Orthophoto Material Template | — | Opcionalni URP Lit predložak za per-tile runtime roof materijale. Ako je prazan, materijal se stvara iz Building Surface Settings |
Building Material Apply Style — vrijednosti:
| Vrijednost | Opis |
|---|---|
UniformFacade |
Jedan zajednički facade materijal iz Building Surface Settings (za sirove GLB-ove bez obrade površina) |
FacadeAndRoofVariants |
Facade + roof varijante materijala po visini/kategoriji zgrade (za obrađene površine — odgovara "Process Facade / Roof Surfaces" opciji iz Fazu 2 uvoza) |
RoofOrthophoto |
Zajednički facade + per-tile ortofoto materijal krova (odgovara "Roof Orthophoto UV" opciji iz uvoza) |
Inspector — Vegetation
| Polje | Zadano | Opis |
|---|---|---|
| Stream Vegetation | true | Kad je uključeno, vegetacijski chunkovi se generiraju i uništavaju uz terrain pločicu |
| Vegetation Rule Set | — | Globalni set pravila razmještaja dijeljen preko svih pločica (VegetationRuleSet — polje globalSeed + niz VegetationRule pravila) |
| Vegetation Prototypes | prazno (auto) | Opcionalni render registar. Kad je prazan, prototipovi se automatski skupljaju iz species setova unutar Vegetation Rule Seta. Kad je popunjen, djeluje kao allow-list za scenu — samo navedeni prototipovi mogu spawnati |
Svako VegetationRule unutar rule seta definira: koji RGBA kanal maske se čita (sourceMaskChannel
— npr. forest=R, park=G, grass=B), densityThreshold (min. vrijednost maske da bi se uopće
postavila vegetacija), density (množitelj za konačni density roll), spacingMeters/
jitterMeters (razmak i nasumično odstupanje pozicija), exclusionThreshold (vrijednost A kanala
iznad koje se pozicija isključuje — ceste, zgrade, voda), i speciesSet (koji prototipovi/mesh-evi
se koriste, s težinskom distribucijom po vrsti).
Inspector — Vegetation Spawn Animation
| Polje | Zadano | Opis |
|---|---|---|
| Vegetation Spawn Animation | ChunkPopIn | Kako se vegetacija pojavljuje kad pločica uđe u stream: None (puna veličina odmah), ChunkPopIn, PerTree |
| Vegetation Chunk Pop In Duration | 0.35 s | Trajanje scale-in animacije cijele pločice odjednom, kad je mod = Chunk Pop In (jeftino — jedan faktor po pločici) |
| Vegetation Per Tree Grow Duration | 1.2 s | Trajanje rasta pojedine instance nakon stagger-a, kad je mod = Per Tree |
| Vegetation Per Tree Max Stagger | 0.8 s | Maksimalno nasumično kašnjenje prije nego što svako stablo počne rasti (Per Tree mod; skuplje — matrice instanci se ponovno grade svaki frame dok animacija traje) |
Inspector — Vegetation Draw Distance
| Polje | Zadano | Opis |
|---|---|---|
| Vegetation Max Draw Distance | 1500 m | Vegetacija se ne crta izvan ove udaljenosti. Postavi na 0 za isključivanje ograničenja |
| Vegetation Density Falloff Start | 800 m | Puna gustoća do ove horizontalne udaljenosti od kamere po instanci; iznad toga gustoća linearno pada do Max Draw Distance |
| Vegetation Frustum Cull Chunks | true | Preskače crtanje vegetacijskih pločica čije granice su izvan kamerinog frustuma |
| Vegetation Frustum Cull Instances | true | Preskače pojedina stabla izvan frustuma (unutar vidljivih pločica) |
Inspector — Start Position
| Polje | Zadano | Opis |
|---|---|---|
| Teleport Camera On Start | false | Kad je uključeno, kamera se pri pokretanju (Start) teleportira u centar dataseta — korisno kad scena kamera inače starta daleko od tile grida |
| Teleport Height Offset | 300 m | Visina kamere iznad maksimalne visine terena u datasetu, nakon teleportacije |
Inspector — HUD
| Polje | Zadano | Opis |
|---|---|---|
| Show HUD | true | Prikazuje on-screen debug HUD (broj učitanih pločica, vidljivih zgrada, itd. — OnGUI overlay) tijekom Play moda |
Custom inspector — dodatne akcije i validacija
Iznad polja Inspector automatski nudi i sljedeće (izvan standardnih serijaliziranih polja):
- Auto Setup Scene References — ako
Camera Transform,Terrain RootiliBuildings Rootnisu postavljeni, prikazuje upozorenje i gumb koji automatski dodjeljujeCamera.maini stvara "Terrain Root" / "Buildings Root" GameObjecte kao djecu ovog controllera - Status dataseta — prikazuje je li dataset u SetActive / Runtime / Mixed modu, broj pločica s TerrainData, i niz kontekstnih upozorenja (npr. "Apply Shared Building Materials je uključeno, ali Building Surface Settings nije postavljen", "Stream Buildings je uključeno, ali nijedna pločica nema building prefab", "Stream Vegetation je uključeno, ali nijedna pločica nema VegetationMask")
- Instantiate All Terrains (SetActive mode) — poziva
ZGConnectImporter.InstantiateAllTerrains, stvarno postavlja sve terene u scenu odjednom (priprema za SetActive režim) - Instantiate All Buildings — isto za zgrade, s prikazom napretka (koliko je već u sceni od ukupnog broja s prefabom)
- Bake All Vegetation / Regenerate All Vegetation (force) — poziva
controller.EditorBakeAllVegetation()da unaprijed generira vegetacijske instance na svim terenima koji su već u sceni (radi samo u Edit modu, ne u Play modu) — deaktivirano dok Vegetation Rule Set ili prototipovi nisu dostupni - Camera Positioning (Camera Positioning foldout) — prikazuje izračunati centar dataseta i nudi
gumb za teleportaciju kamere (ili Scene View pivota, ako
Camera.mainne postoji) u taj centar, dostupno i u Edit i u Play modu - Streaming Control (samo Play mode) — status ("● Active" / "○ Stopped"), broj učitanih pločica,
broj vidljivih zgrada, te gumbi Start/Stop koji pozivaju
StartStreaming()/StopStreaming()ručno (inače streaming kreće automatski pri ulasku u Play mod)
Princip rada u kodu (sažetak)
Svakih Check Interval sekundi (EvaluateTiles()), kontroler prolazi kroz sve pločice u datasetu,
računa udaljenost kamere od granica svake pločice (TileBoundaryDistance) i:
- ako je pločica unutar Load Radius i nije još učitana →
LoadTile()(Runtime: instanciranje izTerrainData, uz asinkroni Addressables handle ako je pločica migrirana; SetActive: samoSetActive(true)), zatimLoadBuildingGroup()iGenerateVegetation()ako su ti streamovi uključeni - ako je pločica izvan Unload Radius i učitana →
UnloadTile()/UnloadBuildingGroup()/DestroyVegetation()
Nakon učitavanja terena (OnTerrainDataLoaded/CreateTerrainGameObject), primjenjuje se statična
kvaliteta (ApplyStaticTerrainQuality) i zatim, svaki frame dok je pločica aktivna,
UpdateActiveTerrainLod() dinamički podešava pixel error, texture mip i basemap distance/
resolution na temelju trenutne udaljenosti kamere prema Near/Mid/Far pragovima opisanim gore.
Susjedne pločice se povezuju (RewireNeighbors()) radi besprijekornog stitchanja rubova terena
(sjene, normale).
Dio 2: BasemapController (prebacivanje podloge)
Skripta: Assets/ZGConnect/Runtime/BasemapController.cs (7597 bajtova), custom inspector:
Assets/ZGConnect/Editor/ZGConnectBasemapControllerEditor.cs. Ovo je mala pomoćna komponenta
koja radi neovisno o TerrainStreamingController-u, ali surađuje s njim: kad
TerrainStreamingController aktivira pločicu, poziv basemapController.ApplyToTile(record)
osigurava da nova pločica odmah pokupi trenutno aktivnu podlogu umjesto uvozno zadane.
Princip rada
Svaka terrain pločica ima onoliko Unity terrain layera koliko je basemap izvora uvezeno u Fazi 2
(npr. i ortofoto i tiled/splatmap varijanta zajedno). BasemapController ne mijenja geometriju —
samo piše alphamape (SetAlphamaps) tako da jedan odabrani layer bude 100% vidljiv (ili
cross-fade između dva layera tijekom prijelaza), na svim aktivnim pločicama odjednom.
Inspector — polja
| Polje | Opis |
|---|---|
| Dataset | CityDataset asset — isti kao na TerrainStreamingController-u |
| Default Basemap Id | Basemap id koji se aktivira pri pokretanju (Start()). Prazno = zadrži uvozno zadani layer (layer 0) |
Inspector — Basemap Switching (custom, samo u Play modu)
Prikazuje trenutno aktivan basemap (Active), polje za trajanje prijelaza u sekundama, i jedan
gumb po dostupnom basemapu iz dataset.availableBasemaps (label = displayName ili
basemapId). Klik na gumb basemapa koji već nije aktivan:
- ako je Transition (s) > 0 → poziva
TransitionTo(basemapId, duration)(glatki crossfade) - ako je Transition (s) = 0 → poziva
SwitchTo(basemapId)(trenutni rez)
Trenutno aktivan gumb je vizualno istaknut (zelena pozadina) i onemogućen za ponovni klik. Ova sekcija je dostupna samo u Play modu — u Edit modu prikazuje se samo informativna poruka.
Javni API (za pozivanje iz drugih skripti)
| Metoda | Opis |
|---|---|
SwitchTo(basemapId) |
Trenutni rez — postavlja alphamap svih aktivnih pločica tako da odabrani layer bude 100% |
TransitionTo(basemapId, duration) |
Coroutine koja svaki frame linearno interpolira alphamape od trenutnog prema ciljnom layeru kroz duration sekundi, zatim piše čisto uniformno stanje na kraju (bez floating-point ostataka) |
ApplyToTile(record) |
Primjenjuje trenutno aktivan basemap na jednu, pojedinačnu pločicu — poziva se iz TerrainStreamingController pri aktivaciji nove pločice |
Dio 3: RealtimeStreamingController (bundle-based streaming s HLOD ringovima)
Skripta: Assets/ZGConnect/RealtimeStreaming/Runtime/RealtimeStreamingController.cs (218 369
bajtova — najveća pojedinačna skripta u projektu), custom inspector:
Assets/ZGConnect/RealtimeStreaming/Editor/RealtimeStreamingControllerEditor.cs.
Princip rada
Za razliku od TerrainStreamingController-a, ovaj kontroler ne čita CityDataset Unity asset
nego StreamingDatasetManifest — JSON manifest upisan u StreamingAssets/ZGConnect/...
tijekom pack koraka (RealTime Asset Importer, Faza 2). Sav sadržaj (teren, zgrade, ortofoto/tiled
basemapovi, vegetacija) dolazi iz AssetBundle-ova, ne iz projektnih assets-a — zato ovaj
sustav radi i u gotovom buildu bez izvornog dataseta u projektu.
Ključna razlika naspram klasičnog sustava je HLOD (Hierarchical Level of Detail) prstenasti sustav: umjesto da se svaka 1×1 km pločica uvijek streama pojedinačno, sustav bira, ovisno o udaljenosti kamere, hoće li se prikazati:
- 1×1 — pojedinačna pločica, puni detalj (najbliži prsten)
- 2×2 — supertile koji spaja 4 susjedne 1×1 pločice u jednu, jeftiniju geometriju/teksturu (srednji prsten)
- 4×4 — supertile koji spaja 16 pločica (4×4 mreža 1×1) u jednu, još jeftiniju cjelinu (najdalji prsten)
Kako se kamera približava, grublji supertile se zamjenjuje finijim (4×4 → 2×2 → 1×1); kako se udaljava, obrnuto. Ovo je isti koncept kao klasični video-igra "LOD ring" sustav, primijenjen na geografske tileove umjesto na pojedinačne modele.
Inspector — Load Region (custom sekcija, na vrhu)
| Polje | Opis |
|---|---|
| Limit Load Region | Kad je uključeno, samo pločice unutar zadanog EPSG:3765 pravokutnika su podobne za streaming (teren, zgrade, vegetacija). Radius i HLOD pravila se i dalje primjenjuju prvo; pločice izvan regije se filtriraju zadnje (tvrdo ograničenje, neovisno o sadržaju manifesta) |
| Min E / Max E / Min N / Max N | Granice EPSG:3765 pravokutnika. Uređuju se ručno ili preko gumba "Open Tile Map" (isti vizualni birač karte kao u importerima) |
Inspector — Dataset
| Polje | Zadano | Opis |
|---|---|---|
| Manifest Relative Path | zadana putanja (RuntimeStreamingPaths.DefaultManifestRelativePath) |
Relativna putanja do StreamingDatasetManifest unutar StreamingAssets/ |
| Camera Transform | — | Kamera prema kojoj se računaju udaljenosti |
| Auto Focus Camera On Dataset | true | Pri pokretanju (Start), kamera se automatski kadrira na granice dataseta ako je daleko od terena |
| Auto Focus Distance Scale | 0.65 | Udaljenost kamere kao razlomak raspona dataseta (max od širine/dubine) |
| Auto Focus Max Camera Height Y | 0 (bez limita) | Tvrdi gornji limit na Y kameru pri auto-fokusu (Unity world space, m). Ne utječe na slobodni let kamere nakon toga |
| Auto Focus Elevation Degrees | 38° | Nagib iznad horizonta pri auto-fokusu (0 = horizontalno, 90 = odozgo) |
| Show Runtime Hud | true | Prikazuje broj učitanih pločica i poziciju kamere u gotovom buildu (ne samo u editoru) |
Inspector — Radii (meters) i HLOD prstenovi
| Polje | Zadano | Opis |
|---|---|---|
| Load Radius | 15000 m | Opći radijus učitavanja (gornja granica za sve tierove) |
| Unload Radius | 16000 m | Opći radijus rasterećivanja |
| Hlod 1x1 Load/Unload Distance | 1500 / 2000 m | Udaljenost granice pločice unutar koje se koristi puni detalj (1×1) |
| Hlod 2x2 Load/Unload Distance | 5000 / 6000 m | Udaljenost za srednji prsten (2×2 supertile) |
| Hlod 4x4 Load/Unload Distance | 15000 / 16000 m | Udaljenost za najdalji prsten (4×4 supertile) |
| Enable Hlod 2x2 | true | Kad je isključeno, ćelije koje bi koristile 2×2 se umjesto toga popunjavaju s 1×1 pločicama (skuplje, ali detaljnije) |
| Enable Hlod 4x4 | true | Kad je isključeno, 4×4 ćelije koriste 2×2 umjesto toga — ili 1×1 ako je i 2×2 isključen (kaskadni fallback) |
| Check Interval | 0.5 s | Razmak između evaluacijskih prolaza |
| Max Loaded Tiles | 32 | Gornja granica broja istovremeno učitanih pločica/supertileova |
Use Rectangular Hlod Distances (zadano: true) — koristi kvadratne (L∞/Čebiševljeve) prstenove za odabir HLOD faktora, tako da se supertileovi slažu uredno na mreži; kružni prstenovi bi ostavili udaljene periferne pločice zaglavljene na 1×1 detaljnu. Use Grid Aligned Hlod Zones (zadano: true) — po-ćelijski HLOD: računa idealni LOD po svakoj 1×1 ćeliji, zatim pokriva teren redoslijedom 4×4 → 2×2 → 1×1 od grubljeg prema finijem.
Inspector — Load Region i pozadinsko procesiranje
| Polje | Zadano | Opis |
|---|---|---|
| Max Concurrent Background Prepares | 2 | Maksimalan broj pločica koje se istovremeno pripremaju na pozadinskim threadovima (disk I/O + dekodiranje heightmapa) |
| Max Concurrent Tile Finalizes | 1 | Maksimalan broj pločica koje se istovremeno finaliziraju na glavnom threadu (stvaranje Terrain/Texture objekata) |
| Use Background Tile Prepare | true | Kad je isključeno, sav rad ide sinkrono na glavnom threadu (stariji/legacy put, korisno za debug) |
| Prefer Terrain Bundles | true | Učitava unaprijed pečene TerrainData AssetBundle-ove iz pack-a (manifest v3) kad su dostupni |
| Terrain Bundle Only Mode | false | Teren isključivo iz bundleova — bez RAW heightmap pripreme/fallbacka. Zahtijeva da bundleovi postoje na disku za svaku streamanu pločicu i aktivni basemap |
| Prefer Building Bundles | true | Učitava unaprijed pečene building tile prefab bundleove iz pack-a (manifest v5) kad su dostupni |
| Prefer Baked Vegetation | true | Učitava unaprijed pečene vegetacijske instance bundleove iz pack-a kad su dostupni |
Inspector — Terrain
| Polje | Zadano | Opis |
|---|---|---|
| Terrain Material | — | Materijal primijenjen na instancirane terene |
| Flip Heightmap Vertically | true | GDAL RAW redovi idu odozgo prema dolje; Unity terrain očekuje odozdo prema gore (isto ponašanje kao import u Dataset Manageru) |
| Draw Instanced | false | drawInstanced postavka za instancirane terene (zadano isključeno ovdje, za razliku od klasičnog sustava gdje je zadano uključeno) |
| Basemap Distance | 2000 | Unity Terrain.basemapDistance |
| Terrain Root | — | Roditelj za instancirane pločice terena |
Inspector — Heightmap LOD (Pixel Error)
Identična logika kao kod TerrainStreamingController-a: Dynamic Heightmap Lod (zadano true),
Pixel Error Near/Mid/Far (2/5/10), Pixel Error fallback (5), Terrain Lod Near/Mid Distance
(800/3000 m).
Inspector — Streaming toggles
| Polje | Zadano | Opis |
|---|---|---|
| Stream Terrain | true | Uključuje/isključuje streaming terena u cijelosti |
| Stream Buildings | true | Uključuje/isključuje streaming zgrada |
| Stream Vegetation | true | Uključuje/isključuje streaming vegetacije |
| Sequential Initial Load Order | false | Kad je uključeno, prvi prolaz učitava redom: prvo sav teren u dosegu, zatim sve zgrade, pa tek onda vegetaciju i dinamički streaming — umjesto da sve ide istovremeno |
| Stream Ortho Basemaps | true | Uključuje ortofoto basemapove u streaming |
| Stream Tiled Basemaps | true | Uključuje tiled/splatmap basemapove u streaming |
Inspector — Basemap
| Polje | Zadano | Opis |
|---|---|---|
| Active Basemap Id | "ortho" | Koji basemap je trenutno aktivan (padajući izbornik u custom inspectoru, popunjen izravno iz manifesta) |
| Tint Basemaps By Hlod | false | Množi boju terrain materijala HLOD faktorom, za vizualizaciju kojeg prstena (1×1/2×2/4×4) koristi svaka pločica — debug alat |
| Hlod 1x1 / 2x2 / 4x4 Basemap Tint | bijela / plavkasta / crvenkasta | Boje za gornju vizualizaciju |
| Debug Basemap Borders | false | Crta obojeni rub oko ortofoto basemap teksture radi prikaza granica pločica |
| Debug Basemap Border Color / Pixels | magenta / 6 px | Boja i debljina debug ruba |
Inspector — Buildings
| Polje | Zadano | Opis |
|---|---|---|
| Building Style | Facade | RealtimeBuildingStyle.Facade ili .OrthoRoof — facade ili ortho-roof building bundleovi iz upakiranog dataseta. Mesh combine i collideri su već zapečeni u vrijeme pack-a (bake-at-pack, Faza 2) |
| Building Surface Settings | — | Dodjeljuje facade/roof materijale na CombinedRender meshevima u runtimeu (prepoznaje ih po imenu objekta, npr. Combined_building_facade_grid) |
| Roof Orthophoto Material Template | — | Opcionalni URP Lit predložak za per-tile ortho roof materijale, kad je Building Style = Ortho Roof |
| Building Cull Distance Meters | 400 m | Udaljenost isključivanja renderiranja zgrada |
| Building Collider Load Distance Meters | 0 (odmah) | Kad je > 0, building bundleovi prvo učitavaju samo vizualni CombinedRender, a fizički (collider) prefab streamaju tek unutar ove granične udaljenosti. 0 = collider se učitava odmah zajedno s vizualnim tileom |
| Building Lod0 Screen / Lod1 Screen | 0.25 / 0.08 | Pragovi veličine na ekranu (screen-space) za prijelaz između LOD0 i LOD1 building geometrije |
| Building Destroy Delay | 30 s | Isto značenje kao kod klasičnog sustava — grace period prije uništavanja neaktivne grupe zgrada |
| Max Inactive Building Groups | 10 | Isto — gornja granica broja neaktivnih grupa u memoriji |
| Building Check Interval | 0.25 s | Koliko često se ponovno evaluira vidljivost building pločica |
| Max Concurrent Building Prepares | 2 | Maksimalan broj building pločica koje istovremeno čitaju GLB/JSON na pozadinskim threadovima |
| Max Concurrent Building Loads | 1 | Maksimalan broj istovremenih GLB instanciranja zgrada na glavnom threadu |
Inspector — Building interaction
| Polje | Zadano | Opis |
|---|---|---|
| Enable Building Interaction | true | Uključuje interakciju sa zgradama (hover/klik) |
| Building Highlight Material | — | Materijal primijenjen na svaki submesh kopije zgrade dok je "hovered" (highlight efekt) |
| Building Selection Material | — | Materijal za odabranu (selected) zgradu |
| Building Info Popup Prefab | — | Prefab popup UI-a koji se prikazuje s informacijama o zgradi |
Inspector — Diagnostics
| Polje | Zadano | Opis |
|---|---|---|
| Log Streaming Diagnostics | true | Ispisuje greške u konzolu kad pločice unutar dosega nemaju terrain podatke ili kad učitavanje terena ne uspije |
Inspector — Frame-budget spreading
Skup polja koji raspoređuje skupe operacije kroz više frameova umjesto da sve rade odjednom (kako bi se izbjegli "spike"-ovi u frame rateu):
| Polje | Zadano | Opis |
|---|---|---|
| Glb Post Process Buildings Per Frame | 12 | Koliko building metadata komponenti se dodaje po frameu nakon legacy GLB instanciranja |
| Glb Post Process Ms Budget | 4 ms | Maksimalno ms po frameu potrošeno na legacy GLB post-instantiate setup (0 = koristi se samo broj zgrada) |
| Vegetation Rules Per Frame | 1 | Koliko pravila razmještaja vegetacije se procesira po frameu kad pločica generira vegetaciju |
| Vegetation Spread Ms Budget | 4 ms | Maksimalno ms po frameu potrošeno na generiranje vegetacije za jednu pločicu (0 = koristi se samo broj pravila) |
| Use Background Building Prepare | true | Kad je isključeno, čitanje building datoteka ide na glavnom threadu tijekom učitavanja |
| Building Metadata Source Mode | PreferBinary | PreferBinary (koristi .bytes kad postoji, fallback na JSON uz upozorenje), BinaryOnly (zahtijeva buildings_{tileId}.bytes, bez JSON fallbacka), JsonOnly (uvijek parsira JSON — legacy/debug) |
| Buildings Root | — | Roditelj za instancirane building grupe |
Inspector — Vegetation
| Polje | Zadano | Opis |
|---|---|---|
| Vegetation Rule Set | — | Isto kao kod klasičnog sustava |
| Vegetation Prototypes | prazno (auto) | Isto kao kod klasičnog sustava |
| Stream Vegetation On 2x2 Supertiles | true | Kad je uključeno, vegetacija se generira i na streamanim 2×2 HLOD terrain pločicama, kombinirajući vegetacijske maske djece 1×1 pločica. Kad je isključeno, vegetacija raste samo na 1×1 pločicama — na srednjem 2×2 dosegu teren će biti vidljiv bez stabala dok se kamera ne približi unutar Hlod 1x1 Load Distance (custom inspector na ovo eksplicitno upozorava) |
Inspector — Vegetation Spawn Animation / Draw Distance
Identična polja i zadane vrijednosti kao kod TerrainStreamingController-a (Vegetation Spawn
Animation Mode, Chunk Pop In/Per Tree trajanja, Max Draw Distance, Density Falloff Start, Frustum
Cull Chunks/Instances) — vidi Dio 1 za detalje, jer se ovdje ponašaju identično.
Custom inspector — dodatne akcije
- Basemap Id popup —
Active Basemap Idse ne uređuje kao slobodan tekst nego kao padajući izbornik popunjen direktno iz manifesta (StreamingManifestEditorUtility.DrawBasemapIdPopup) - Upozorenje za Terrain Bundle Only Mode — kad je uključeno, prikazuje info okvir da se teren učitava isključivo iz bundleova i da svaka streamana pločica treba bundle za aktivni basemap
- Upozorenje za vegetaciju — ako je Stream Vegetation uključen, a Vegetation Rule Set nije postavljen, ili ako je Stream Vegetation On 2×2 Supertiles isključen, prikazuju se odgovarajuća upozorenja/info okviri opisani gore
- Runtime status (Play mode) — broj učitanih pločica (
LoadedTileCount), broj pločica u manifestu; napomena da se tijekom Play moda mogu mijenjati Active Basemap Id, Building Style i HLOD tint, ali da materijali/mesh-combine/collideri zgrada dolaze isključivo iz pack-baked bundleova (ne mogu se promijeniti bez ponovnog pack-a) - Editor Populate (samo izvan Play moda) — "Populate Scene" trenutno postavlja teren i
building pločice u scenu bez ulaska u Play mod: teren uzima sve 1×1 "leaves" unutar Load Region
(ignorira HLOD 2×2/4×4 i udaljenost kamere), zgrade uzima sve stilizirane leaves unutar regije;
collideri se stvaraju na
TileBuildings_*_Physicsdjeci. Zahtijeva postavljen Building Surface Settings za CombinedRender materijale. "Clear Populated" uklanja tako postavljen sadržaj - Restart Streaming (samo Play mode) — ručno ponovno pokreće
StartStreaming()
Princip rada u kodu (sažetak)
Za razliku od jednostavnog radius-checka u klasičnom sustavu, evaluacija ovdje najprije za svaku
1×1 ćeliju grida određuje idealni HLOD faktor na temelju udaljenosti kamere od granice ćelije
i pragova hlod1x1/2x2/4x4LoadDistance (kvadratni L∞ prstenovi ako je useRectangularHlodDistances
uključen), zatim popunjava pokrivenost redoslijedom grublje-prema-finijem (4×4 → 2×2 → 1×1) tako
da svaka točka na terenu bude pokrivena točno jednom razinom detalja. Rezultat se učitava/
rasterećuje asinkrono: pripreme (disk I/O, dekodiranje) idu na pozadinskim threadovima ograničene
istovremenim brojem (maxConcurrentBackgroundPrepares), a finalizacija (stvaranje Unity objekata,
koja mora ići na glavnom threadu) je odvojeno budžetirana (maxConcurrentTileFinalizes), kako bi
se izbjeglo zamrzavanje glavnog threada pri masovnom streamanju velikih regija. Zgrade i
vegetacija prate isti HLOD raspored kao njihova roditeljska terrain pločica/supertile, uz vlastite
odvojene budžete za pozadinsku pripremu i frame-raspoređeno procesiranje (Frame-budget spreading
sekcija gore).
Dio 4: SpatialStreamingController (HLOD ring-based streaming)
Skripta: Assets/ZGConnect/SpatialStreaming/Runtime/SpatialStreamingController.cs (92 872 bajta).
Ovo je treći, najnapredniji runtime streaming sustav u projektu. Za razliku od prethodna dva,
ovdje nema custom Inspector skripte — Unity prikazuje sva polja kroz standardni, automatski
generirani inspector (nema dodatnih gumba/validacijskih poruka kao kod
TerrainStreamingController-a ili RealtimeStreamingController-a). Priprema sadržaja za ovaj
sustav radi zaseban bake pipeline (SpatialBakePipeline + Editor prozor SpatialStreamingWindow,
68 KB odnosno 38 KB koda) koji čita isti tip izvornog dataseta kao RealTime Asset Importer, ali
pече ga u drugačiju manifest strukturu (spatial_manifest.json) prilagođenu ovom sustavu. Bake
strana nije pokrivena ovim dokumentom (fokus je runtime streaming) — može se dokumentirati zasebno
ako zatrebaš.
Princip rada
Sustav radi u koncentričnim prstenovima oko kamere, s pet hijerarhijskih razina detalja koje
se kaskadno smanjuju s udaljenošću (opisano i u internoj arhitekturnoj bilješci
Documentation/SpatialStreaming_HLOD_Optimization.md):
Detail (250 m sub-ćelije) → Sub-cell proxy (1 km) → Tile proxy (1 km) → HLOD2 (2×2 km) → HLOD4 (4×4 km)
Svaka razina ima vlastiti broj "prstenova" (rings) koji određuje koliko daleko od kamere ta razina
detalja seže, prije nego što preda štafetu grubljoj razini. Bake pipeline unaprijed priprema
spatial_manifest.json s 1 km tileovima, opcionalnim sub-ćelijama, proxy geometrijom za
tile/sub-cell, i HLOD2/HLOD4 supertileovima. U runtimeu, SpatialDatasetRuntimeIndex gradi O(1)
indekse (grid ključevi, supertile blokovi, sub-cell mape) iz tog manifesta pri učitavanju, kako bi
evaluacija po prstenovima ostala jeftina i pri 800+ tileova (umjesto linearnog prolaska kroz cijeli
dataset — detaljno opisano u internoj bilješci o optimizaciji).
Inspector — Dataset
| Polje | Opis |
|---|---|
| Manifest Relative Path | Relativna putanja do spatial_manifest.json unutar StreamingAssets/ (zadano iz SpatialStreamingPaths.SpatialManifestRelativePath) |
| Content Root | Roditeljski transform za sav streamani sadržaj |
| Target Camera | Kamera prema kojoj se računaju prstenovi/udaljenosti |
Inspector — HLOD
| Polje | Zadano | Opis |
|---|---|---|
| Enable Hlod | true | Glavni prekidač za cijeli HLOD kaskadni sustav |
Inspector — LOD tile rings
Ovo je centralna konfiguracija cijelog sustava — pet polja, svako definira doseg jedne razine detalja, izraženo u broju prstenova ćelija te razine (ne u metrima izravno):
| Polje | Zadano | Opis |
|---|---|---|
| Detail Rings | 2 | Kvadrat 250 m sub-ćelija s punim detaljem oko kamere. 1 = samo sub-ćelija kamere, 2 = 3×3 sub-ćelije oko kamere. 0 = preskoči ovu razinu potpuno |
| Subcell Proxy Rings | 2 | Kumulativni prstenovi 1 km tileova izvan detail pojasa, za sub-cell proxy geometriju (jeftinija zamjena za puni detalj). 0 = preskoči |
| Tile Proxy Rings | 2 | Kumulativni prstenovi 1 km tileova izvan sub-cell pojasa, za proxy geometriju cijelog tile-a. 0 = preskoči |
| Hlod 2x2 Rings | 3 | Kumulativni prstenovi 2×2 km blokova izvan finijih pojaseva, za HLOD2 supertileove. 0 = preskoči |
| Hlod 4x4 Rings | 5 | Kumulativni prstenovi 4×4 km blokova — bazni HLOD sloj koji popunjava ostatak vidnog polja. 0 = preskoči |
Svaka razina je "kumulativna" u odnosu na prethodnu — sustav ne broji apsolutnu udaljenost od kamere za svaku razinu zasebno, nego dodaje prstenove izvan onoga što je već pokriveno finijom razinom. Postavljanjem bilo koje vrijednosti na 0 ta se razina detalja u potpunosti preskače (npr. postavljanje Subcell Proxy Rings i Tile Proxy Rings na 0 bi značilo da nakon Detail razine odmah slijedi HLOD2, bez međukoraka).
Inspector — Streaming
| Polje | Zadano | Opis |
|---|---|---|
| Check Interval | 0.35 s | Koliko često se ponovno evaluira HLOD want/unload na temelju udaljenosti kamere. Ne throttlea samo učitavanje ili instanciranje — to je odvojeno budžetirano (vidi niže) |
| Load Budget | SpatialStreamingLoadBudget.Default |
Struktura koja definira per-frame budžet učitavanja/instanciranja blokova (broj coroutina, ms budžet po frameu) za ovu kaskadu. Napredna postavka — zadane vrijednosti su prikladne za većinu slučajeva, mijenja se samo pri finom performance tuningu |
Inspector — Rendering
| Polje | Opis |
|---|---|
| Gpu Settings | SpatialGpuResidentRenderingSettings asset — projektne postavke za Unity GPU Resident Drawer (vidi tablicu ispod) |
| Building Surface Settings | Isti tip asseta kao kod druga dva sustava — facade/roof materijal profili |
| Apply Materials On Load | Kad je uključeno (zadano), remapira materijale kombiniranog mesha na svakoj detail sub-ćeliji nakon učitavanja |
Sadržaj SpatialGpuResidentRenderingSettings asseta:
| Polje | Zadano | Opis |
|---|---|---|
| Apply To Spawned Tile Roots | true | Kad je uključeno, spawnani tile root-ovi dobivaju GPU Resident Drawer kompatibilnost fixeve |
| Apply Recursively | true | Prolazi kroz cijelu hijerarhiju ispod svakog streamanog tile root-a |
| Warn When Drawer Disabled | true | Ispisuje upozorenje pri pokretanju ako aktivni URP asset nema uključen GPU Resident Drawer |
| Log Renderer Counts | false | Ispisuje broj renderera nakon primjene GPU-friendly postavki na tile root-ove |
| Max Renderers For Gpu Opt In | 32 | Maksimalan broj mesh renderera po spawnanom root-u koji se uključuju u GPU-driven crtanje. 0 = bez limita; kad je postavljeno, prvih N renderera po redoslijedu u hijerarhiji se uključuje |
(Unity GPU Resident Drawer je render-engine funkcija za jeftinije crtanje velikog broja statičnih mesheva — relevantno ovdje jer Spatial Streaming cilja scene s vrlo velikim brojem istovremeno vidljivih blokova/zgrada.)
Inspector — Debug
| Polje | Zadano | Opis |
|---|---|---|
| Show Debug Hud | true | Prikazuje on-screen HUD s statistikom streaminga |
| Log Streaming | false | Ispisuje detaljan log streaming odluka u konzolu |
| Debug Footprint Want | false | Loga praznine u supstituciji (susjed je "želi se" ali nedostaje iz manifesta/grafa/bundlea). Dodaje i liniju s HLOD2 blokom kamere u HUD |
| Debug Lod Tint | false | Oboji svaki streamani blok prema razini detalja: detail = zeleno, sub-cell proxy = cijan, tile proxy = žuto, HLOD2 = narančasto, HLOD4 = crveno — vizualni debug alat za provjeru koji prsten je stvarno aktivan gdje |
| Debug Draw Tile Km Grid | false | Crta 1×1 km mrežu tileova iz manifesta (magenta) u Scene view i tijekom Play moda |
| Debug Hud Scale | 1.0 (raspon 0.25–2.5) | Jedinstvena skala runtime debug HUD panela |
Inspector — Performance profiling
| Polje | Zadano | Opis |
|---|---|---|
| Enable Performance Profiling | true | Uključuje interno mjerenje performansi streaminga (SpatialStreamingPerformanceTracker) |
| Spike Frame Ms Threshold | 33.33 ms (~30 FPS) | Prag iznad kojeg se frame smatra "spike"-om tijekom aktivnog streaminga i loga se |
| Log Spikes To Csv | true | Zapisuje redak u CSV datoteku za svaki spike frame (za naknadnu analizu izvan Unityja) |
| Log Spikes To Console | false | Dodatno ispisuje spike frameove i direktno u Unity konzolu |
Inspector — Residency budget (optional)
| Polje | Zadano | Opis |
|---|---|---|
| Max Resident Blocks | 0 (bez limita) | Kad je premašeno, najudaljeniji blokovi koji trenutno nisu "wanted" se stavljaju u red za rasterećenje — LRU-stil ograničenje ukupne memorije, neovisno o prstenovima. Opcionalna napredna zaštita za scene s ekstremno velikim brojem tileova |
Princip rada u kodu (sažetak)
Ovo je sustav opisan detaljno u internoj arhitekturnoj bilješci
(SpatialStreaming_HLOD_Optimization.md), koja dokumentira i povijest optimizacije. Sažeto:
ShouldRunStreamingEvaluate()odlučuje treba li uopće pokrenuti puni evaluate ovaj Check Interval — pokreće se pri promjeni grid-ćelije kamere ili značajnom pomaku; dok kamera miruje unutar iste ćelije, puni evaluate se preskače (cleanup/unload se i dalje izvode svaki frame)SpatialStreamingHlodEvaluatorprolazi samo kroz tileove/supertileove unutar trenutnog prstena (ring-window), ne kroz cijeli manifest — cijena evaluacije skalira s O(ring²), ne s ukupnim brojem tileova u datasetu- Rezultat ide u red za učitavanje (
ProcessPendingLoads, budžetirane coroutine), a registracija uSpatialStreamingLoadedStateIndex(bitmaske po sub-ćeliji, HLOD2/HLOD4 mape blokova) omogućuje da su naknadne provjere supstitucije/pokrivenosti O(1) ili O(broj sub-ćelija po tileu), umjesto ponovnog prolaska kroz sve učitane blokove SpatialStreamingCoverageRefCountsprati hijerarhijsku pokrivenost (je li HLOD2 blok u potpunosti pokriven sa 4 djeteta 1 km sloja, itd.) inkrementalno, tako da grublji HLOD sloj ostaje vidljiv sve dok finiji sloj ne prijavi da je spreman — čime se izbjegavaju vizualne praznine (nema praznog "detail-only" prstena, nema preklapanja HLOD/detail/proxy nakon što se budžeti smire)
Nikakav SetActive/Destroy se ne izvodi sinkrono unutar evaluacije — rasterećenja idu kroz
ProcessPendingUnloads, budžetirano po frameu, isto kao i učitavanja.
Dio 5: Spatial Streaming — Bake Pipeline
Priprema sadržaja za SpatialStreamingController (Dio 4) radi zaseban alat, neovisan o Dataset
Import Manageru i RealTime Asset Importeru iz Faze 2: Editor prozor
Assets/ZGConnect/SpatialStreaming/Editor/SpatialStreamingWindow.cs (meni ZG Connect → Spatial
Streaming, 37 861 bajt) koji pokreće SpatialBakePipeline.cs (68 039 bajtova — bake logika)
preko SpatialBakeProfile ScriptableObject asseta (konfiguracija bakea).
Prozor sam eksplicitno navodi u UI-u: "Independent workflow from RealtimeStreaming. Sources:
StreamingAssets/ZGConnect/*. Bake output: StreamingAssets/ZGConnect/bundles_spatial/." — dakle
čita isti izvorni dataset (building GLB-ovi iz _dataset/StreamingAssets strukture, isto kao i
RealTime Asset Importer), ali piše u svoju vlastitu izlaznu mapu (bundles_spatial/) i svoj
vlastiti manifest (spatial_manifest.json), potpuno odvojene od RealtimeStreaming pack izlaza.
SpatialBakeProfile (ScriptableObject — konfiguracija bakea)
Asset koji se dodjeljuje u prozoru i sadrži svu konfiguraciju bakea (stvara se preko ZG Connect →
Spatial Streaming prozora, gumb "Create Default Bake Profile", ili ručno kroz Create → ZG Connect
→ Spatial Streaming → Bake Profile"):
Subcell split:
| Polje | Zadano | Opis |
|---|---|---|
| Subcell Size Meters | 250 | Duljina brida sub-ćelije u metrima (npr. 250 → mreža 4×4 sub-ćelije po 1 km pločici) |
| Min Buildings For Subcell Split | 80 | Kad pločica ima manje zgrada od ovog broja, peče se jedan grubi bundle za cijelu pločicu umjesto da se dijeli na sub-ćelije (nema smisla usitnjavati rijetko izgrađena područja) |
| Max Subcells Per Edge | 8 | Sigurnosni gornji limit broja sub-ćelija po bridu pločice |
Mesh combine:
| Polje | Zadano | Opis |
|---|---|---|
| Combine Meshes Per Material | true | Kombinira meshove po materijalu (manje draw callova) |
| Combine Material Override | — | Kad je postavljen, svi rendereri sub-ćelije koriste ovaj materijal prije kombiniranja (najbolji mogući broj draw callova, po cijenu gubitka detalja materijala) |
| Deduplicate Materials By Shader | true | Spaja instance glTF materijala koje dijele isti shader prije kombiniranja. Isključiti samo ako je stvarno potreban materijal po pojedinoj zgradi |
Materials:
| Polje | Opis |
|---|---|
| Building Surface Settings | Kad je postavljen, materijali zgrada se remapiraju iz ovog asseta (po imenu GLB materijala) prije kombiniranja — isti tip asseta kao i kod druga dva streaming sustava |
Footprint proxy / HLOD:
| Polje | Zadano | Opis |
|---|---|---|
| Bake Footprint Proxies | true | Peče floor-aligned ekstruzije 1×1 km proxy geometrije za svaku pločicu (uključujući pločice sa sub-ćelijama) — ovo je grublja zamjenska geometrija za tile-proxy razinu detalja opisanu u Dijelu 4 |
| Bake Subcell Footprint Proxies | true | Kad se koriste sub-ćelije, peče jedan proxy bundle po sub-ćeliji (preporučeno) |
| Bake Hlod Supertiles | true | Spaja tile proxyje u 2×2 i 4×4 supertile bundleove (HLOD2/HLOD4 razine iz Dijela 4) |
| Skip Existing Outputs | false | Kad je uključeno, ponovno koristi već stažirane prefabove/mesh-detail assete i kopirane bundles_spatial izlaze — staging se čuva između pokretanja, regeneriraju se samo nedostajući artefakti (inkrementalni bake) |
| Proxy Material Override | — | Opcionalni bezteksturni placeholder materijal za spremanje proxy prefaba (zadano built-in Default-Material). Ne smije se dodijeliti facade atlas ovdje |
Asset bundles:
| Polje | Zadano | Opis |
|---|---|---|
| Uncompressed Bundles | false | Nekomprimirani bundleovi — brže arhiviranje, veće datoteke |
| Detail Bundle Mode | MeshAssets | MeshAssets peče samo SpatialMeshDetailAsset (bez duplikata prefaba — jeftinije po disku); Prefab peče puni prefab payload za detail sub-ćeliju |
Bake scope:
| Polje | Opis |
|---|---|
| Selected Tile Ids | Kad je prazno, peku se sve pločice koje imaju izvorne GLB-ove prema roditeljskom manifestu (manifest.json) |
Debug:
| Polje | Zadano | Opis |
|---|---|---|
| Verbose Bake Logging | true | Loga korake bakea po pločici u konzolu (upozorenja se uvijek ispisuju detaljno, neovisno o ovoj postavci) |
Inspector prozora — GPU Resident Drawer
Prva sekcija prozora ne tiče se same geometrije nego globalne project-level postavke Unity
renderera, budući da Spatial Streaming cilja scene s vrlo velikim brojem istovremeno vidljivih
blokova (vidi i SpatialGpuResidentRenderingSettings iz Dijela 4):
| Polje | Zadano | Opis |
|---|---|---|
| Instanced Drawing (GPU Resident Drawer) | true | Uključuje Unity GPU Resident Drawer za projekt |
| GPU occlusion culling in cameras | true | Uključuje GPU-based occlusion culling (dostupno samo dok je Drawer uključen) |
| Small mesh screen % cull | 0 (raspon 0–20) | Isključuje crtanje mesheva ispod ovog postotka veličine ekrana — jeftin način odbacivanja sitnih detalja izdaleka |
| Apply to \<PC pipeline asset path> | true | Kad je uključeno, postavke se primjenjuju na namjenski PC URP pipeline asset; kad je isključeno, primjenjuju se na trenutno aktivni URP asset |
Gumbi: "Apply Project Settings" (upisuje gornje postavke u odabrani URP asset i osigurava BRG
shader stripping "Keep All"), "Reinitialize Drawer" (ponovno inicijalizira GPU Resident Drawer
i ispisuje status), "List all incompatible URP renderers in project" / "Upgrade renderers to
Forward+/Deferred+" — pronalazi i, na zahtjev, nadograđuje Universal Renderer Data assete koji
nisu kompatibilni s GPU Resident Drawerom (radi samo s Forward+ ili Deferred+ rendererima). Prozor
uživo prikazuje status (aktivni URP asset, trenutni drawer mode, je li occlusion culling
uključen) preko SpatialGpuResidentDrawerStatus.Query().
Inspector prozora — Spatial bake → bundles_spatial/
Glavna sekcija: dodjela Bake Profile asseta (s gumbom "Create Default Bake Profile" ako nije
postavljen), zatim pregled njegovih ključnih polja (Source folder, Subcell size, Split threshold),
polje za Building Surface Settings, te dva toggle-a (Verbose bake logging, Skip existing
outputs) koja se odmah upisuju natrag u profil.
Bake scope — bira se između:
- All — peku se sve pločice s izvornim GLB-ovima iz roditeljskog manifesta
- Region — EPSG:3765 pravokutnik (Min/Max E, Min/Max N), koji se automatski poravnava na 4×4 tile grid (isto kao Realtime pack, radi usklađenosti s HLOD supertileovima). Otvara se preko gumba "Open area selection map" (isti vizualni birač karte kao svugdje drugdje u projektu) ili ručnog unosa. Uživo prikazuje broj pločica s izvornim GLB-ovima unutar regije i njihove ID-jeve (ako ih je ≤12, ispisuju se poimence). Bake regije spaja rezultat u postojeći manifest — ostale, prethodno pečene pločice se ne diraju
Gumb za pokretanje mijenja label ovisno o scope-u ("Bake All Tiles" / "Bake Selected Region (N tiles)") i onemogućen je dok scope nije valjan. Tijekom bakea prikazuje se progress bar po fazama (vidi niže) te gumb "Cancel Bake".
Staging recovery — ako postoje stažirani prefabovi u _spatial_bake_staging/ koji još nisu
pretvoreni u bundleove (npr. bake je prekinut nakon geometrijske faze, prije faze Asset Bundles),
prozor to prepoznaje i nudi "Build bundles from staging" — nastavlja pipeline od stažiranih
prefaba nadalje, bez ponovnog pečenja GLB-ova, uz opciju "Rebuild spatial_manifest.json".
Manifest recovery — ako spatial_manifest.json referencira pločice čiji bundleovi više ne
postoje na disku (npr. ručno obrisani), prozor nudi "Sync manifest to bundles on disk" — obreže
manifest da odgovara stvarnom sadržaju bundles_spatial/ mape (ne ponovno peče bundleove, samo
čisti manifest).
Inspector prozora — Source dataset
Read-only pregled stanja izvora i izlaza: putanja root dataseta, postoji li roditeljski
manifest.json, postoji li spatial_manifest.json, broj facade GLB-ova, broj ortho-roof GLB-ova,
broj datoteka u bundles_spatial/, broj stažiranih prefaba, plus lista upozorenja (npr. upravo
onih koja pokreću Staging/Manifest recovery sekcije gore). Gumb "Rescan dataset" osvježava sve
brojke.
Inspector prozora — Scene setup
Dva gumba: "Add Spatial Streaming Rig to Scene" (SpatialSceneSetupUtility.
EnsureStreamingRigInOpenScenes) — dodaje SpatialStreamingController u otvorenu scenu i odmah mu
dodjeljuje zadani SpatialGpuResidentRenderingSettings i BuildingSurfaceSettings asset ako
postoje; "Create GPU Resident Settings Asset" — stvara SpatialGpuResidentRenderingSettings
asset na zadanoj putanji ako još ne postoji.
Faze bakea (interni pipeline)
SpatialBakePipeline.BakeCoroutine prolazi kroz šest faza (prikazane kao zaseban progress bar u
prozoru, SpatialBakeStage enum):
| Faza | Udio ukupnog napretka (s HLOD uključenim) | Opis |
|---|---|---|
| Prepare | 0–2% | Priprema: skeniranje izvornog dataseta, određivanje popisa pločica za pečenje (sve ili regija) |
| Tiles | 2–72% | Najveći dio posla: za svaku pločicu — dijeljenje na sub-ćelije (ako je pločica dovoljno gusto izgrađena), remap materijala prema Building Surface Settings, kombiniranje mesheva po materijalu, pečenje footprint proxy geometrije po pločici/sub-ćeliji |
| HLOD supertiles | 72–78% (preskače se ako Bake Hlod Supertiles isključen) | Spajanje tile proxyja u 2×2 i 4×4 supertile blokove |
| Asset bundles | 78–98% (76–98% bez HLOD faze) | Pakiranje svih pečenih prefaba/mesh-detail asseta u AssetBundle-ove unutar bundles_spatial/ |
| Manifest | 98–100% | Upisivanje/ažuriranje spatial_manifest.json sa svim pečenim pločicama, sub-ćelijama i supertileovima |
| Collect staging | (samo kod "Build bundles from staging" toka) | Skuplja već stažirane prefabove/mesh-detail assete iz _spatial_bake_staging/ kao polaznu točku, preskačući fazu Tiles u potpunosti |
Kao što se vidi iz raspodjele postotaka, faza Tiles dominira ukupnim trajanjem bakea (70-ak postotnih bodova od 100) — logično, jer uključuje čitanje svakog izvornog GLB-a, dijeljenje na sub-ćelije, remap materijala i pečenje proxy geometrije za svaku pločicu pojedinačno.
Odnos između tri sustava
Ovim su sva tri runtime streaming sustava dokumentirana na razini Inspector opcija i principa
rada: TerrainStreamingController (klasični, scene-based), RealtimeStreamingController
(bundle-based s HLOD 1×1/2×2/4×4 prstenovima) i SpatialStreamingController (najnapredniji,
petostupanjska HLOD kaskada s ring-window evaluacijom).
Sva tri su jednakopravno produkcijska — cijeli ZG Connect paket funkcionira kao skup alata za pripremu i streaming sadržaja, a koji se sustav koristi ovisi o potrebama konkretnog projekta koji paket koristi (npr. jednostavna scena manjeg opsega može ostati na klasičnom sustavu; scena koja treba build bez source assets-a i srednji doseg gradi na Realtime pack-u; scena s vrlo velikim brojem tileova i potrebom za finom HLOD kontrolom poseže za Spatial Streamingom). Nijedan od njih ne zamjenjuje ili nadilazi drugi u samom projektu — izbor je na krajnjem korisniku alata.
Bake pipeline za Spatial Streaming (Dio 5 gore) sada je dokumentiran na isti način kao što je Faza 2 pokrila Dataset Import Manager i RealTime Asset Importer — sva tri runtime sustava sada imaju i svoju pripremnu (bake/import) i svoju runtime dokumentaciju.
ZG Connect