Files
Universe/Content/Vegitations
..

Färgstyrd vegetation

vegetation.json är den gemensamma katalogen. Sökvägar till modeller utgår från denna mapp. Den äldre mappen Content/Vegetations/ med markmaterial finns kvar.

Tillgångar och offlineverktyg

De tio modellpaketen kommer från Poly Haven, med CC0-licens. sources.json innehåller ursprungliga nedladdningsadresser, filstorlekar och MD5-kontrollsummor. Startpaketet omfattar 1 697 MiB originaldata inklusive 2K-material för skogsmark, torrt gräs och snö. Nedladdaren hämtar bara filer som saknas eller har fel kontrollsumma och stoppar över 2 GB nedladdning.

Förberedda modeller, alphakort och avståndsbilder ingår i spelets innehåll. Originalen och mellansteget source/bake-source.glb behövs bara vid import, ignoreras av Git och kopieras inte till distributionen. Spelet behöver inte nätåtkomst, Node eller Python.

Återskapa resurser från projektroten med Python 3, Node och .NET 10:

python tools/vegetation/download.py
npm ci --prefix tools/vegetation
node --max-old-space-size=16384 tools/vegetation/prepare.mjs --source-only pine_tree_01 fir_tree_01 tree_small_02 fir_sapling_medium
dotnet build src/Universe.App -c Release
./src/Universe.App/bin/Release/net10.0/Universe.App.exe --prepare-vegetation --bake-foliage
node --max-old-space-size=16384 tools/vegetation/prepare.mjs
dotnet build src/Universe.App -c Release
./src/Universe.App/bin/Release/net10.0/Universe.App.exe --prepare-vegetation --force
dotnet build src/Universe.App -c Release

Importen använder glTF Transform och Meshoptimizer. Tungt barr-/lövverk bakas från full geometri till 24 rumsliga grupper med tre alphakort per grupp. Stammar och grenar behåller geometri. GLB-scenerna LOD0, LOD1, LOD2 delar material. Startpaketets träd använder cirka 12 000 / 2 000 / 350 trianglar per trädvariant, under planens övre budget på 60 000 / 12 000 / 2 000. preparation.json redovisar summerade antal över alla varianter. Slutligen bakas 16 riktningar och tre elevationsvinklar per variant till impostorer med färg och normaler. Gräsets torra variant heter dry.glb.

Färgregler

matchColorRgb anger kartfärgen för placering, inte modellens färg. Avståndet är 100 * length(sRGB - target) / (255 * sqrt(3)), med mjuk uttoning under toleransens yttersta 20 %. RGB-värden anges 0–255. Överlappande biomvikter normaliseras och används också av markshadern. Katalogens fyra biomer ligger i ordningen skog, torr mark, sand och snö.

Varje växt anger id, model, type (tree, shrub, grass, fern), matchColorRgb, colorTolerancePercent, spawnWeight, scaleRange, altitudeMeters, absoluteLatitudeDegrees, maxSlopeDegrees, minimumSpacingMeters, windStrength och valfri trunkCollision med radiusMeters och heightMeters. Material och växtfärger kommer från GLB-filen. Arter väljs viktat inom respektive skikts täthetsbudget; fler arter ökar inte automatiskt antalet växter.

Valfri lodMeters på en träddefinition ersätter planetens tre meshgränser. distanceMeters kan förkorta artens räckvidd. Planetens depthPrepass aktiverar ett extra djupsteg före terrängen. Det döljer dyr terrängskuggning bakom lövverk och låter endast de främsta löven få full ljusberäkning. Standard är av: mätningen på Jorden visade att steget kostade mer vegetationstid än det sparade i terrängen. Dess GPU-tid ingår i vegetationsbudgeten och redovisas också separat i debugpanelen när det aktiveras.

Vatten, snö och olämplig höjd/lutning filtreras bort. Höjdintervall räknas från planetens referensradie, i projektets höjddata. Jordens globala höjdkarta har höga värden även över många gröna områden, så startkatalogen tillåter träd upp till 6 000 m. Det är ingen exakt karta över jordens verkliga skogar.

Inställningar per planet

Ange exempelvis i planetens JSON:

"vegetation": {
  "enabled": true,
  "densityMultiplier": 1,
  "allowedPlants": ["pine_tree_01", "fir_tree_01", "fern_02"],
  "affectGroundMaterials": true,
  "treeDensityPerHectare": 600,
  "shrubDensityPerHectare": 350,
  "groundDensityPerHectare": 20000,
  "forestScaleMeters": 450,
  "treeLodMeters": [40, 150, 400],
  "treeDistanceMeters": 2000,
  "shrubDistanceMeters": 150,
  "grassDistanceMeters": 80,
  "uploadBudgetMilliseconds": 1,
  "maximumCachedTiles": 2048,
  "maximumInstances": 650000,
  "shadowResolution": 2048,
  "shadowDistancesMeters": [100, 400],
  "shadowSoftness": 1,
  "shadowCascadeBlend": 0.2,
  "shadowBiasMeters": 0.035,
  "collisionDistanceMeters": 64
}

Utelämnad allowedPlants tillåter hela katalogen. Valfri biomeTexture anger en separat kartbild relativt KnownSolarSystem/; annars används surfaceTexture. Utan färgkarta används seedad proceduriell biomfördelning. Jorden är uttryckligen aktiverad. Atmosfäriska planeter av typen terrestrial får standardprofilen; andra fasta planeter kan aktiveras explicit. Gasplaneter tillåts inte. Proceduriella jordliknande planeter får också en standardprofil.

Jordens startprofil använder densityMultiplier: 0.7, motsvarande nominellt 420 träd, 245 buskar och 14 000 markväxter per hektar före biom-, täthetsbrus- och terrängfiltrering. Sätt multiplikatorn till 1 för den tätare grundprofilen.

Placeringarna bestäms av planet-ID, seed och fasta kubsfärsrutor, oberoende av terrängens LOD och planetens rotation. Trädrutor är cirka 256 m, buskrutor 128 m och markväxtrutor 32 m för att slippa generera stora mängder gräs långt bort. En begränsad arbetspool delas med terrängen. Inaktuella jobb avbryts. Resurs- och avståndsinstansdata laddas upp stegvis med den angivna tidsbudgeten; ett enskilt drivrutinsanrop kan inte avbrytas mitt i en uppladdning.

Avståndsinstanser byggs i bakgrunden och använder två uppsättningar återanvända CPU-/GPU-buffertar. Terrängcachen behåller inaktiva rutor i upp till 60 sekunder, med en budget på 16 384 rutor per planet. De äldsta överflödiga rutorna frigörs stegvis, så korta utflykter till omloppsbana inte omedelbart tvingar fram samma terräng igen.

Vegetationscachen följer spelarens position och täcker alla riktningar. En huvudvridning byter därför inte ut rutor eller startar nya vegetationsjobb. Standardgränsen är 2 048 rutor och fortfarande högst 650 000 instanser; detta behåller mer vegetation i minnet än den tidigare gränsen på 640 rutor. Små kameravridningar återanvänder instansbuffertarna med en konservativ marginal i synfältet. Skuggornas instanslistor uppdateras vid förflyttning eller nytt innehåll. Terrängrutor delar sin indextopologi och skriver vertexdata direkt till färdiga arrayer för att minska tillfälliga allokeringar. Detaljmaterial för avlägsna himlakroppar laddas först inom materialets synliga avstånd, så månens marktexturer inte läses in när man tittar runt på Jorden.

Vind följer simulationstiden. Alphamippar bevarar täckningen. Träd växlar med dither mellan tre mesh-LOD och därefter flervyade impostorer. Två lokala skuggkaskader stöder upp till två solar. Vegetationen ritas före havet och kan därför speglas av befintlig SSR när den syns i scenbilden. FPS-spelaren sveps mot stamkapslar och glider längs dem; fri kamera, gräs, buskar och löv påverkas inte.

Vegetationen ritas även före terrängen. Dess färdiga djupbild används för att undvika full terrängskuggning bakom stammar och löv, utan ett extra geometristeg. Separat depthPrepass är ett ytterligare, valfritt steg för lövens egen överlappning.

Benchmark och felsökning

Vegetationsskuggor filtreras med bilinära djupjämförelser på GPU:n. Marken använder ett viktat 5×5-filter med nio texturhämtningar; löv använder ett 3×3-filter med fyra hämtningar. Ingen slumpmässig sampling används. shadowSoftness (0–1) blandar mellan en bilinjär djupjämförelse och det mjuka filtret; standard är 1. shadowCascadeBlend (0–0,4, standard 0,2) anger hur stor del av närskuggans räckvidd som blandas med fjärrskuggan. shadowBiasMeters (0,001–0,25, standard 0,035) är djupmarginalen i meter och är oberoende av kaskadens räckvidd. Kartorna centreras på spelarens position och snäpps till texlar i dubbelprecision; att vrida huvudet flyttar inte kartorna.

Universe.App.exe --shadow-report verifierar produktionsfiltret mot en separat CPU-referens, mjukare skuggkanter, löv, två solar och kontinuerliga kaskadövergångar. Testbilder sparas i graphics-report/shadows/.

P-menyn innehåller BENCHMARK FOREST: omloppsvy, mjuk landning till 1,8 m, promenad, skogsbryn och uppstigning. Därefter återställs Jordvyn. Resultat med FPS-graf samt CSV/JSON sparas i benchmark-results/forest-* bredvid appen. Debugpanelen visar vegetation, vegetationsskuggor, CPU-/uppladdningstid, inskickade instanser/trianglar, LOD och väntande rutor.

Universe.App.exe --lookaround-report står still i skogen på Jorden och mäter en stillastående vy följd av två hela kameravarv i 1440 × 900. Efter uppvärmningen sparas bildrutetider, vegetationsgenerering, cacheändringar, terränguppladdningar, minnesallokeringar och GC-räkningar i graphics-report/lookaround/. GPU:n synkroniseras per bildruta. Lägg till --profile-passes för att lokalisera långsamma pass; den extra synkroniseringen påverkar då tiderna.

Universe.App.exe --vegetation-report kör samma rutt i 2560 × 1440 utan VSync, med vegetation av/på och kall/varm vegetationscache. Initial modell-/texturinläsning samt uppvärmning av shaders och terräng sker före mätningen. Kall körning tömmer vegetationsrutorna och deras instansbuffertar; varm körning återanvänder dem från föregående resa. Rapporten synkroniserar GPU:n per bildruta och sparar bilder, FPS-grafer, bildrutetider, statistik och PASS/FAIL i graphics-report/vegetation/. --preview-only avslutar efter bildkontrollen. Gränserna är 60 FPS i medel, 55 FPS i 1 %-låg, högst 50 ms och vegetation inklusive skuggor högst 5 ms vid 99:e percentilen. Hela scenens kostnad ingår i FPS; rapporten visar missade gränser i stället för att dölja dem.

Senaste kontrollen på RTX 5080, 2560 × 1440 och Jordens starttäthet 0,7:

Vegetationscache Medel-FPS 1 %-låg FPS Max bildruta Vegetation + skuggor, GPU p99
Kall 102,7 56,5 19,03 ms 4,23 ms
Varm 99,2 48,1 23,11 ms 4,23 ms

Varm körning klarar ännu inte gränsen 55 FPS för 1 %-låg; hela prestandamatrisen rapporteras därför som FAIL. Medel-FPS, vegetationsbudgeten och gränsen 50 ms klaras. Mätvärden varierar med vy och belastning. Grafikrapporten kontrollerar också två solar, giltiga OpenGL-resultat och minst 99 % närliggande yttäckning i djupbilden under spelarens fötter efter en orbital resa; senaste kontrollen gav 100 % täckning.