# Kända solsystem `solar-systems.json` innehåller solsystemen som ersätter proceduriell generering i sina tilldelade gridceller. `sol` ligger i `(0,0,0)`. Övriga celler fortsätter genereras från universums seed. ## Planet-id:n | Id | Namn | | --- | --- | | `mercury` | Merkurius | | `venus` | Venus | | `earth` | Jorden | | `mars` | Mars | | `jupiter` | Jupiter | | `saturn` | Saturnus | | `uranus` | Uranus | | `neptune` | Neptunus | `sun` är Solen. `moon` definieras som en satellit under Jordens `moons` och räknas inte som en av de åtta planeterna. Id:n är stabila och unika inom respektive solsystem, oberoende av ordningen i JSON-listan. ## Startkamera Projektets `../config.json` väljer startmålet: ```json "startup": { "systemId": "sol", "planetId": "earth", "planetHotkeys": ["mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", "neptune"], "distanceInRadii": 3.0, "longitudeDegrees": 20, "latitudeDegrees": 20, "speedMetersPerSecond": 200000, "fieldOfViewDegrees": 67.65 } ``` Byt `planetId` för att starta framför en annan planet. `planetHotkeys` mappar tangenterna **1–9** i ordning till planet-id:n; exempelvis går **1** till Merkurius och **6** till Saturnus. Listan får innehålla högst nio id:n som finns i det valda startsystemet. Latitud och longitud avser planetens egna texturkoordinater. `distanceInRadii` är avståndet från planetens centrum. **F2** ordnar en solbelyst ytnära vy, **F3** visar närmaste stjärna och **F4** flyger till närmaste ringsystem. Tryck **Q** för att flyga mjukt till den närmaste planeten från kamerans nuvarande position. Ändringar i JSON och kartor läses vid appstart. Kör `dotnet run --configuration Release --project src/Universe.App/Universe.App.csproj` från projektroten efter ändringar; byggsteget kopierar konfiguration och kartor till körmappen. Vid direktstart av exe-filen läses filerna bredvid exe-filen. De följer även med `dotnet publish`. ## Parametrar - `systems`: lägg till fler system med eget `id`, `name`, `sector`, `centerOffsetMeters`, `stars` och `planets`. Två kända system får inte ligga i samma cell. - `stars`: `id`, `name`, `positionMeters`, `radiusMeters`, `luminositySolar`, linjär RGB-`color` och valfri `seed`. En eller två stjärnor stöds. - `planets`: `id`, `name`, `description`, `hostStarId`, `radiusMeters`, `seed`, `axialTiltDegrees`, `rotationDegrees`, `orbit`, `surfaceType`, `surfaceColor`, valfri `surfaceTexture`, `terrain`, `atmosphere`, valfria `clouds`, `ocean`, `rings` och `moons`. - `orbit`: `semiMajorAxisAu`, `eccentricity`, `meanAnomalyDegrees`, `inclinationDegrees`, `ascendingNodeDegrees`, `periapsisDegrees`, valfri `periodDays`. Banorna beräknas analytiskt från systemets `epochUtc`. En satellits bana är relativ till den rörliga moderplanetens centrum. Äldre `phaseDegrees` stöds som sann anomali vid epoken om `meanAnomalyDegrees` saknas. - `surfaceType`: `rocky`, `terrestrial`, `cloudCovered`, `gasGiant` eller `iceGiant`. Gas- och isjättarna har molnband, inte berg. `cloudBandFrequency` och `stormStrength` styr bandtäthet och en större storm. - `atmosphere`: `heightMeters`, `density`, RGB-`color`, `composition`. Sammansättningen är beskrivande metadata; `density`, höjd och färg styr grafiken. - `rings`: `innerRadiusMeters`, `outerRadiusMeters`, RGB-`color`, `opacity` samt valfria `gapInnerRadiusMeters` och `gapOuterRadiusMeters`. Ringarnas plan följer planetens axellutning och skuggar planeten. Alla längder anges i **meter**, utom banornas halvstoraxel som anges i **AU**. Färger har tre komponenter i intervallet 0–1. `seed` är ett heltal; utelämnad seed härleds stabilt från id. Felaktiga id:n, saknade kartor, orimliga värden och objekt utanför sin gridcell ger ett tydligt startfel. ## Tid, banor och rotation Varje system har `epochUtc` (standard `2000-01-01T12:00:00Z`). Banfaser och rotationsfaser är relativa till denna tidpunkt. `simulation.startUtc` och `simulation.timeScale` i projektets `config.json` väljer startdatum och tidsfaktor; standard är 1× verklig tid. Menyn **P → DEBUG ON** har ett tidsreglage 0–100×. Menyn och benchmarkrutterna pausar världstiden, och 0× pausar bara simulationen, så att kameran fortfarande kan användas. | JSON-fält | Betydelse | | --- | --- | | Stjärnans `massKg` | Massa i kg; används för beräkning av omloppstid om perioden saknas. Standard en solmassa. | | Planetens `massKg` | Massa i kg; används för tvåkroppsperiod och satellitbanor. Standard en jordmassa. | | `orbit.semiMajorAxisAu` | Ellipsens halvstoraxel i AU. | | `orbit.eccentricity` | Excentricitet från 0 till mindre än 1. | | `orbit.periodDays` | Siderisk omloppstid i dygn om 86400 sekunder; om utelämnad används `2π √(a³ / G(M+m))`. | | `orbit.meanAnomalyDegrees` | Medelanomali vid epoken. Har företräde framför äldre `phaseDegrees` (sann anomali). | | `orbit.inclinationDegrees` | Banplanets lutning mot systemets XZ-plan. | | `orbit.ascendingNodeDegrees` | Uppstigande nodens longitud. | | `orbit.periapsisDegrees` | Periapsisargument relativt noden, inte periheliets absoluta longitud. | | `rotationPeriodHours` | Siderisk axelrotation i timmar. Standard 24. Måste vara ändlig och skild från noll. | | `axialTiltDegrees` | Axellutning mot systemets +Y-riktning, 0–180 grader. Värden över 90 ger retrograd rotation med positiv rotationsperiod. | | `rotationDegrees` | Meridianens rotationsfas vid epoken. | | `poleLongitudeDegrees` | Vridning av den lutade axelns riktning runt systemets Y-axel; standard 0. | `rotationPeriodHours` anges som positivt belopp i vårt solsystem. Venus (177,4°) och Uranus (97,8°) har redan omvänd rotationsriktning genom axellutningen; en negativ period skulle vända dem en gång till. Negativa perioder stöds för andra konfigurationer som vill vända spinnen kring den angivna axeln. Jorden använder en siderisk dag på cirka 23 h 56 min, medan dess soldygn blir ungefär 24 timmar genom kombinationen av rotation och omlopp. Solsystemets åtta planeter använder [JPL:s banelement vid J2000](https://ssd.jpl.nasa.gov/planets/approx_pos.html) och [sideriska perioder och massor](https://ssd.jpl.nasa.gov/planets/phys_par.html). Månen följer jorden med ungefär 27,32 dygns omlopps- och rotationstid. Proceduriella planeter får deterministiska rotationstider och omloppstider beräknade från avstånd och värdkroppens massa. Deras stjärnor har fasta lägen; dubbelstjärnornas inbördes banor integreras inte. Modellen är en spelbar tvåkroppsapproximation med fasta banelement, inte JPL Horizons eller en fullständig N-kroppssimulering. Sekulära störningar, precession/nutation, tidvattenkrafter, relativitet och ljusets gångtid ingår inte. Jordbanan använder jord–måne-barycentrums element som approximation. UTC används direkt för epoken utan TT/TDB-korrigering. Axelfaser och polernas longituder är visuellt konfigurerade och inte IAU-kalibrerade; atmosfärens vind kan dessutom röra molnen relativt ytan. Detta gör att perioder och omloppshastigheter är astronomiskt grundade utan att ange exakta observerade lägen för ett datum. Meshdata, terräng-LOD och material behåller planetens lokala koordinater. Rendering och kollision använder samma aktuella rotation utan att generera om terräng för varje rotationssteg. En markbunden spelare följer både omlopp och rotation, medan tangentbordsstyrning och hopp använder vanlig, oskalad bildrutetid. Fokusanimeringar följer rörliga planeter. `--simulation-report` genererar bilder av jordrotation, markvy och debugreglage i appens `graphics-report/`. ## Jordens heightmap och noise Jordens inställningar kombinerar kartan med finare terräng: ```json "terrain": { "heightmap": "Textures/earth-height.jpg", "heightmapMinMeters": 0, "heightmapMaxMeters": 8848, "heightmapGamma": 1.0, "proceduralNoiseAmplitudeMeters": 120, "proceduralNoiseFrequency": 24, "noiseMask": "heightmapLand", "landThreshold": 0.02, "landBlend": 0.04 } ``` Höjden beräknas som: `radie + kartans höjd + proceduriell noise × amplitud × landmask` Svart på kartan motsvarar `heightmapMinMeters`, vitt motsvarar `heightmapMaxMeters`. `heightmapGamma` formar fördelningen mellan dem. Noisens frekvens styr detaljstorleken; amplituden styr höjdskillnaderna. `heightmapLand` tonar in noise över svarta havsområden enligt tröskel och övergångsbredd. `everywhere` applicerar noise överallt. - Bara heightmap: sätt `proceduralNoiseAmplitudeMeters` till `0`. - Bara noise: utelämna `heightmap` och använd `noiseMask: "everywhere"`. - Båda: behåll båda inställningarna som i exemplet ovan. Meshgenerering, kamera-kollision, marknormaler och bergsskuggor samplar samma kombinerade höjdfunktion. GPU-kontrollen `--validate-graphics` jämför också Jordens heightmap + noise med CPU-funktionen. ## Hav och vatten Jordens `ocean`-block aktiverar ett eget vattenpass på planetens havsnivå. Tryck **F6** för en mjuk flygning till en solbelyst havsvy ungefär sex meter över vattnet. Kameran kan flyga under ytan och stannar vid havsbotten. | Fält i `ocean` | Effekt | | --- | --- | | `enabled` | Aktivera havet; utelämnat block ger inget vatten | | `maskFromSurfaceTexture` | Använd färgkartans blå vattenområden som kustmask; vita isområden och land förblir torra. `false` fyller terräng under havsnivån utan färgmask | | `seaLevelMeters`, `depthMeters` | Havsnivå relativt planetradien och bottennivå i maskerade hav | | `waveAmplitudeMeters`, `waveLengthMeters` | Den största vågens amplitud och våglängd; ytterligare elva komponenter ger finare vågor | | `windDirectionDegrees`, `waveSpeed`, `choppiness` | Vågriktning, animationshastighet och hur spetsiga vågkammarna är | | `roughness`, `reflectionStrength`, `refractionStrength` | Solglittrets bredd, reflektionernas styrka och brytningens skärmförskjutning | | `deepColor`, `shallowColor`, `absorption` | Linjära RGB-färger för djup/grunt vatten och absorption per meter för rött, grönt och blått ljus | | `foamStrength` | Skum på vågkammar och vid grunda stränder | Vågspektrumet består av Gerstner-komponenter som filtreras efter pixelstorleken. Ytan söks med strålar i ett lokalt koordinatsystem förankrat i dubbelprecision, så samma hav fungerar från rymden till våghöjd. Refraktionen använder scenens färg och djup från ett separat framebuffer. Havet simulerar ingen fluiddynamik, fartygskölvatten eller bestående skumtransport. ### Skärmrymdsreflektioner på vatten `ocean.screenSpaceReflections` styr en separat reflektionspassering efter atmosfär och moln. Den söker synlig geometri med perspektivkorrekt interpolation mot det logaritmiska djupet och förfinar träffen i sju binära steg. Där en stråle fortsätter ut mot himlen används den färdiga scenens himmel, inklusive molnkartan och stjärnorna. Havets vågnormaler och Fresnelvikt styr reflektionen; skum minskar den. Färg-mipmaps filtrerar reflektionen efter vattnets `roughness`. | Fält | Standard | Betydelse | | --- | --- | --- | | `enabled` | `true` | Slår på den extra skärmreflektionen. Grundläggande himmel/molnreflektion finns även avstängd. | | `reflectSky` | `true` | Använd bildens färdiga himmel och avlägsna objekt som reflektionskälla. | | `strength` | `1` | Inblandning av skärmreflektionen, 0–1. `reflectionStrength` på havet styr hela reflektionsmaterialet. | | `resolutionScale` | `0.5` | Upplösning 0,25–1. Halv upplösning med djup- och normalstyrd uppskalning är standard. | | `maxSteps` | `48` | Högst 8–128 djupsöksteg per reflektionspixel. | | `stridePixels` | `2` | Minsta skärmsteg i fullupplösta bildpunkter; större steg kan missa små objekt. | | `maxDistanceMeters` | `3000` | Geometrisökningens längd, 10–50000 m. | | `maxSurfaceDistanceMeters` | `4000` | Största kamera–vatten-avstånd där SSR används, 10–20000 m. Effekten tonas ut innan gränsen. | | `thicknessMeters` | `1.5` | Tillåten djupmarginal vid träff, 0,01–50 m. | | `normalBiasMeters` | `0.12` | Startförskjutning från vattenytan för att undvika självträffar, 0,01–5 m. | | `edgeFade` | `0.07` | Tonar ut träffar nära skärmkanten; värdet är en andel av bildens bredd/höjd. | Upplösning, raymarch, kantutfasning och uppskalning mäts tillsammans som **WATER REFLECTIONS** i debugpanelen. Från rymden används den billigare grundreflektionen. Reflektioner läggs endast på vatten och befintlig molntransmission dämpar dem när moln skymmer ytan. Vid flera hav används det närmaste havets SSR-inställningar för den lokala vyn. SSR kan bara träffa geometri som finns i kamerans färg- och djupbild. Dolda objekt och objekt utanför bilden får därför en analytisk himmel/molnreserv, och övergången tonas ut. Det är inte RTX-strålspårning eller en fullständig reflektionskarta av omgivningen. Metoden bygger på perspektivkorrekt skärmsökning enligt [McGuire och Mara, Efficient GPU Screen-Space Ray Tracing](https://jcgt.org/published/0003/04/04/). `--ocean-report` kör ett kontrollerat väggtest (även att mark inte ändras), sparar dag-/nattbilder med reflektionen av/på samt undervattens- och omloppsvyer. Jämförelser och GPU-tid skrivs till konsolen; bilder hamnar i appens `graphics-report/`. Tekniken är inspirerad av principerna i [Crests beskrivning](https://github.com/JJarvis89/crest-oceanrender#the-tech), med en egen implementation för OpenGL 3.3. Unity-paketet ingår inte som ett beroende. Skapa bilder och kontrollera animation, giltiga GPU-pixlar samt undervattensvyn med: ```powershell dotnet run -c Release --project src/Universe.App -- --ocean-report --validate-graphics ``` ## Volymetriska 3D-moln Jordens `clouds`-block definierar ett sfäriskt molnlager mellan 2 100 och 6 400 meter. Molnen går att flyga genom och syns även från rymden. **F7** ger en vy strax ovanför molntopparna; **F6** visar dem underifrån över havet. Space/Ctrl flyttar kameran genom lagret. ```json "clouds": { "enabled": true, "densityTexturePath": "Clouds/earth-clouds.png", "densityTextureStrength": 1.0, "baseAltitudeMeters": 2100, "thicknessMeters": 4300, "coverage": 0.40, "density": 0.85, "shapeScaleMeters": 18000, "detailScaleMeters": 2400, "windSpeedMetersPerSecond": 18, "windDirectionDegrees": 25, "sunsetStrength": 1.4, "viewSteps": 48, "lightSteps": 4, "resolutionScale": 0.4 } ``` | Fält i `clouds` | Effekt | | --- | --- | | `enabled`, valfri `seed` | Aktivering och valfri separat väderseed; annars används planetens seed | | `baseAltitudeMeters`, `thicknessMeters` | Molnbas över planetradien och lagrets tjocklek; hela lagret ska ligga inom atmosfären | | `coverage`, `density` | Täckning och optisk täthet; båda kan sättas till `0` för en klar himmel | | `densityTexturePath`, `densityTextureStrength` | Valfri equirektangulär gråskalekarta relativ till `Content/`; svart tar bort moln, vitt behåller full täckning och grått ger mjukare kanter. Styr hur starkt kartan formar det proceduriella molnfältet | | `shapeScaleMeters`, `detailScaleMeters`, `erosion` | Större molnform, finare kanter och hur mycket mindre noise bryter upp kanterna | | `cloudType` | Profil från låga skiktmoln (`0`) till höga stackmoln (`1`) | | `windSpeedMetersPerSecond`, `windDirectionDegrees` | Vind i planetens koordinatsystem; fältet är stabilt när kameran rör sig | | `extinctionPerMeter`, `scatteringAlbedo` | Ljusdämpning och hur stor andel av ljuset som sprids i molnet | | `anisotropy`, `silverLiningStrength` | Framåtspridning och ljusa molnkanter mot solen | | `ambientStrength`, `sunlightStrength` | Indirekt himmelsljus och direkt solljus | | `sunsetStrength` | Atmosfärens färgfiltrering: blått ljus dämpas mer på den långa vägen vid låg sol | | `shadowStrength` | Molnskuggornas styrka på mark och hav | | `viewSteps`, `lightSteps` | 16–192 steg genom molnet och 2–16 mot varje sol | | `resolutionScale` | Molnpassets upplösning relativt fönstret, 0,25–1; `0.5` ger halv bredd/höjd med djupstyrd uppskalning | | `maxViewDistanceMeters` | Maximal sträcka genom varje molnsegment; även omloppsvyer stöds | Utelämnat `clouds`-block ger seedat molnväder som anpassas till `atmosphere.heightMeters` och `atmosphere.density`. Tunn eller obefintlig atmosfär ger inga moln, medan tätare atmosfärer i genomsnitt ger större täckning och täthet. Samma seed ger samma molninställningar. För att uttryckligen stänga av moln, använd `"clouds": { "enabled": false }`. Fasta planeter använder detta lager; gasjättars molnband hör till deras `gas`-volym. Rendering och skuggor använder samma 3D-fält och valfria 2D-molntäthetskarta. Jordens karta `Content/Clouds/earth-clouds.png` styr molnens geografiska täckning även på avstånd; den procedurella volymen ger molnen höjd, form och detaljer. Ljuset samplas genom molnvolymen mot varje sol, och en atmosfärsmodell dämpar blått ljus mer än rött vid horisonten. Solglöden dämpas av molnens transmittans. Havet har en billigare spegling av samma molnfält. Väder och multipel ljusspridning är visuella realtidsmodeller. Principerna för strålmarschering och ett separat molnpass är inspirerade av [RealtimeVolumetricCloudRenderer](https://github.com/OfenPower/RealtimeVolumetricCloudRenderer), med egen GLSL-kod för den sfäriska världen. ```powershell dotnet run -c Release --project src/Universe.App -- --cloud-report --validate-graphics ``` Rapporten sparar bilder under, över och inne i molnen samt från omloppsbana. Den kontrollerar giltig transmittans, vindrörelse och att molnens renderade ljus blir varmare när solen sänks till horisonten. ## Kartfiler Appen använder `Textures/earth-color.jpg` (**6880 × 3440**) och `Textures/earth-height.jpg` (**1280 × 640**). De bifogade PNG-förhandsbilderna är bara **168 × 159** pixlar. Höjdkartans Himalaya toppar vid ungefär 239/255, vilket blir cirka **8 300 m** med maxhöjden 8 848 m. I den lilla PNG-förhandsbilden når samma område bara ungefär 94/255, alltså cirka **3 300 m**. Det var därför bergen såg låga ut: JSON pekade på förhandsbilden i stället för den detaljerade höjdkartan. Den högupplösta kartan ger också betydligt bättre relief och färgdetaljer nära marken. Byt gärna till andra kartor och ändra sökvägarna i JSON. Kartorna tolkas som equirektangulära: norr upptill, söder nedtill, longitud −180° till +180° från vänster till höger. Planetens längdkoordinat spegelvänds vid mappningen så att kontinenterna visas rättvända i den här kamerans koordinatsystem; både färg och höjd använder samma projektion. Albedo och heightmap kan ha olika pixelupplösning men måste använda samma geografiska projektion. Höjdkartor läses som 8-bitars gråvärden ur bildens röda kanal; texturer färghanteras som sRGB. Alla kartsökvägar är relativa till denna mapp och måste stanna inom den. Inga absoluta sökvägar till urklippsfiler behövs vid körning. ## Datakällor och modell Radier, ungefärliga banavstånd och axellutningar utgår från [NASA Planetary Fact Sheet](https://nssdc.gsfc.nasa.gov/planetary/factsheet/) och [NASA Planet Compare](https://solarsystem.nasa.gov/planet-compare/). Solens radie följer [NASA Sun Fact Sheet](https://nssdc.gsfc.nasa.gov/planetary/factsheet/sunfact.html). De viktigaste ringradierna och Cassinidelningen följer [NASA Saturnian Rings Fact Sheet](https://nssdc.gsfc.nasa.gov/planetary/factsheet/satringfact.html). Stenplaneterna är sfäriska approximationer; gasplaneterna är tillplattade volymer. Banornas illustrativa faser är inte aktuella efemerider. Moln, atmosfärsfärger och ringarnas optiska egenskaper är visuella modeller; klimat, växthuseffekt, vindar och magnetfält simuleras inte fysikaliskt. Endast Jorden har geografiska kartor i denna första katalog; övriga ytor är proceduriella material. ## Gasplaneter som volym `surfaceType: "gasGiant"` och `"iceGiant"` använder **ingen planetmesh eller fast kollisionsyta**. Shadern integrerar färgad gas längs varje kamerastråle och skuggar gasen med ljusstrålar mot varje sol. Kameran kan flyga in i och genom gasen. Inuti tätnar dimman och skymmer omgivningen. Solens riktning, ringskuggor och andra planeters förmörkelser påverkar volymen. `cloudCovered` är fortfarande en fast planet med molntäcke, exempelvis Venus. Saturnus har ett komplett `gas`-block i JSON. Övriga gasplaneter kan använda samma parametrar och egna färger. Utelämnade värden får standardvärden från `GasVolumeSettings`. | Fält i `gas` | Effekt | | --- | --- | | `outerRadiusScale`, `polarRadiusScale` | Volymens yttre radie och tillplattning vid polerna, relativt `radiusMeters` | | `density`, `scaleHeight` | Optisk täthet och hur snabbt den ökar inåt; skalhöjden anges som andel av radien | | `viewSteps`, `lightSteps` | Integrationssteg för kamera respektive solljus, 16–192 och 2–16 | | `sampleDistribution`, `stopTransmittance` | Koncentration av prover nära volymens framkant och gräns för tidigt avslut | | `scatteringAlbedo`, `lightExtinction`, `anisotropy` | Andel spritt ljus, effektiv utsläckning mot solen och spridningens riktning | | `sunlightStrength`, `ambientStrength` | Direktljus och svagt omgivningsljus | | `bandColor`, `polarColor`, `hazeColor` | RGB-färger för molnband, polarområden och dis; basfärgen är planetens `surfaceColor` | | `bandContrast`, `fineBandFrequency`, `fineBandContrast` | Variation i de breda och fina latitudbanden | | `cloudTurbulence`, `detailStrength`, `noiseScale`, `windSpeed` | Bandens turbulens, finstruktur, noisefrekvens och animation | Planetens `cloudBandFrequency` och `stormStrength` styr fortsatt de stora banden och stormen. Gasplaneter måste ha `proceduralNoiseAmplitudeMeters: 0` och sakna heightmap. `gas` ersätter deras vanliga atmosfärspass; `atmosphere` beskriver fortfarande sammansättning och ger en reservfärg för dis. Volymen använder Beer–Lambert-transmittans och enkel spridning med en effektiv kompensation genom `lightExtinction`. Det är en realtidsmodell, inte en fullständig simulering av multipel spridning eller gasdynamik. Principerna beskrivs i [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques). ## Detaljerade ringar och lokala stenar Saturnus `rings` innehåller samtliga inställningar. En deterministisk radiell profil används gemensamt av ringarnas färg, optiska täthet, ringskuggorna och stenarnas fördelning. Profilen filtreras med mipmaps på avstånd för att undvika flimrande tunna linjer. Den nedskalas om grafikkortets maximala texturbredd är lägre än `profileResolution`. | Fält i `rings` | Effekt | | --- | --- | | `seed` | Seed för ringstruktur och stenarnas stabila positioner | | `innerRadiusMeters`, `outerRadiusMeters`, `thicknessMeters` | Ringarnas radier från planetcentrum och stenlagrets tjocklek | | `color`, `opacity` | Grundfärg och övergripande täthet | | `gapInnerRadiusMeters`, `gapOuterRadiusMeters` | Den stora Cassinidelningen | | `bands` | Lista med `innerRadiusMeters`, `outerRadiusMeters`, `density`, `color`; Saturnus har C-, B- och A-band | | `gaps` | Fler intervall med radier och `densityMultiplier`; `0` ger en tom lucka utan stenar | `appearance` styr ringmaterialet: | Fält | Effekt | | --- | --- | | `profileResolution`, `fineBandCount`, `microBandCount`, `bandContrast` | Profilens upplösning och mängden oregelbundna fina ringband | | `opticalDepth`, `outerColor` | Gemensam optisk täthet och yttre reservfärg när inga explicita band anges | | `sunlightStrength`, `ambientStrength` | Belysning av ringmaterialet | | `forwardScattering`, `backlitStrength` | Spridning och genomlysning när solen ligger bakom ringarna | | `shadowSoftnessMeters` | Mjukhet på planetens skugga och ringskuggor | | `dustOpacity` | Den andel dis som återstår där lokala stenar ersätter det sammanhängande ringmaterialet | `rocks` styr närbildens geometri: | Fält | Effekt | | --- | --- | | `enabled` | Aktivera lokala stenar; `false` behåller ringmaterialet på alla avstånd | | `cellSizeMeters`, `particlesPerCell`, `densityScale` | Cellstorlek, antal kandidater och täthetsfaktor; tomma luckor förblir tomma | | `streamRadiusMeters`, `maximumInstances` | Lokal räckvidd och hård gräns för antal instanser; avlägsna celler rensas | | `minRadiusMeters`, `maxRadiusMeters`, `sizeExponent` | Storleksintervall; större exponent ger fler små stenar | | `meshDistanceMeters`, `meshLodPixels`, `lodTransitionMeters` | Avstånd, projicerad storlek och övergång mellan ljussatta punktpartiklar och 3D-stenar | | `fadeStartMeters` | Avstånd där stenarna börjar tonas ut mot räckviddens slut | | `shapeIrregularity`, `roughness`, `iceStrength` | Oregelbunden form, materialets strävhet och isreflexer | | `sunlightStrength`, `ambientStrength`, `minColor`, `maxColor` | Ljus och färgvariation mellan stenarna | Instanserna förankras nära kameran i dubbelprecision före omvandling till GPU-koordinater, så meterstora stenar behåller precisionen vid astronomiska avstånd. De är visuella partiklar med stabila seedade positioner. Individuella stenbanor, gravitation och kollisioner med stenarna simuleras inte. `maximumInstances` begränsar närbildens belastning; för hög täthet kan fylla budgeten innan hela räckvidden täcks. ## Prova Saturnus Tryck **F4** från startvyn vid Jorden för en mjuk flygning till närmaste ringsystem. Kameran lämnar först den närliggande stenplaneten, anländer vid ringarna och sänker hastigheten. Tangenten som är mappad till `saturn` (standard **6**) ger sedan en översikt ovanför Saturnus ringplan. **F1** frigör musen; startflaggan `--free-mouse` gör det direkt vid start. `rings.preview` gör båda vyerna konfigurerbara: | Fält | Effekt | | --- | --- | | `radiusFraction`, `azimuthDegrees`, `heightMeters` | Närbildens radiella läge mellan ringarnas kanter, vinkel i ringplanet och höjd över planet | | `yawOffsetDegrees`, `pitchDegrees`, `rollDegrees` | Riktning från planetcentrum, blickens lutning och kamerans roll | | `fieldOfViewDegrees`, `flightSeconds`, `speedMetersPerSecond` | Närbildens synfält, flygtid och efterföljande hastighet | | `overviewDistanceInOuterRadii`, `overviewElevationDegrees`, `overviewSunAngleDegrees` | Översiktens avstånd, höjdvinkel och riktning i förhållande till solen | Ringarna är bara tiotals meter tjocka men tiotals miljoner meter breda. En vy nära stenarna visar därför nästan vågräta ringar, medan översikten visar hela bandstrukturen. Ändra `heightMeters`, kameravinklar eller höjden med Space/Ctrl för andra perspektiv. ## Asteroiddetaljer nära kameran `rings.rocks.asteroid` styr närbilden. Stenarna använder delade icosfärmeshar med jämnt fördelade trianglar och seedad, individuellt deformerad form. Detailjnivån ökar med projicerad diameter på skärmen. Standardnivåerna innehåller 80, 320, 1 280, 5 120, 20 480 respektive 81 920 trianglar. Det ger tät geometri när en sten fyller bilden, medan bakgrundens partiklar fortsätter använda billigare representationer. Formen kombinerar domain-warped gradientnoise i flera oktaver, oregelbundna proportioner, ryggar och ett cellulärt kraterfält med skålformade sänkor och kanter. Stora kratrar påverkar geometrin; mindre kratrar och korn påverkar ytans normaler. Detaljerna följer stenens lokala koordinater och rotation, så de sitter kvar när kameran flyttas. Samma heltalshash används i vertex- och fragmentshadern för stabila kraterpositioner. | Fält i `asteroid` | Effekt | | --- | --- | | `baseSubdivision`, `maxSubdivision` | Lägsta och högsta icosfärnivå; maximalt `6` | | `lodStartPixels`, `lodPixelMultiplier` | Skärmdiameter där nästa nivå börjar och faktor mellan nivåernas trösklar | | `highDetailDistanceMeters`, `maxHighDetailInstances` | Räckvidd och hård instansbudget för nivåer över `3`; störst på skärmen prioriteras | | `elongation` | Variation i stenarnas proportioner | | `noiseFrequency`, `noiseOctaves`, `noisePersistence` | Grundformens gradientnoise och fördelningen av detalj mellan oktaver | | `ridgeStrength` | Relief från ryggar och bergknallar | | `craterFrequency`, `craterStrength`, `craterDensity`, `craterRimHeight` | Kratrarnas storlek, djup, förekomst och kanthöjd | | `surfaceDetailStrength`, `surfaceDetailFrequency`, `normalStrength` | Finare ytstruktur och hur kraftigt den påverkar skuggningen | Den befintliga `rocks.shapeIrregularity` styr fortfarande grundformens amplitud. LOD byts med hysteres för att undvika upprepade byten vid en tröskel. Högsta geometrin kan skapas första gången en sten blir tillräckligt stor på skärmen. Alla instanser återanvänder samma basmeshar; noisen och kratrarna skiljer dem åt. ## Solstrålar och linsglöd Varje stjärna har ett `glow`-block. Det gäller även proceduriella solar, som får samma standardinställningar. Solen i katalogen visar alla värden explicit. | Fält i `glow` | Effekt | | --- | --- | | `enabled`, `intensity` | Aktivering och styrka | | `referenceDistanceAu`, `distanceFalloff` | Avståndsskala i AU och hur snabbt glöden avtar | | `apparentRadiusMultiplier` | Visuell skivstorlek; växlar mjukt till förstoring när kameran är långt från stjärnan, utan att ändra dess fysiska storlek eller ljusberäkningen | | `minimumCorePixels` | Minsta storlek på den lysande kärnan, så solen syns även vid yttre planeter | | `haloRadiusDegrees`, `haloStrength` | Glödens vinkelstorlek och styrka | | `rayCount`, `rayLengthDegrees`, `raySharpness`, `rayStrength` | Antal riktade strålar, längd, skärpa och styrka | | `ghostStrength`, `ghostSpacing`, `chromaticAberration` | Linsreflexer längs axeln genom bildcentrum och deras färgseparation | Styrkan beräknas som `intensity × sqrt(luminositySolar) / (1 + (distanceAu / referenceDistanceAu)^distanceFalloff)`. Den avtar kontinuerligt utan att klippas bort vid ett bestämt avstånd. Detta är en visuell kameramodell, där dämpningen kan göras långsammare än fysisk invers kvadrat för att solen fortfarande ska synas vid exempelvis 30 AU. Strålar och reflexer beräknas separat för varje sol och läggs till i HDR före bloom och tonmappning. Djupbufferten samplas över solskivan: objekt framför solen dämpar eller släcker glöden. Reflexerna flyttas med solens läge på skärmen och är tydligast när solen ligger vid sidan av bildcentrum. ## Automatiska grafikrapporter Rapporterna använder appens riktiga OpenGL-shaders i ett dolt fönster och avslutas automatiskt utan att fånga musen: ```powershell dotnet run -c Release --project src/Universe.App -- --graphics-report --validate-graphics dotnet run -c Release --project src/Universe.App -- --scene-report ``` `graphics-report/` bredvid den byggda appen får PNG-bilder. Det första kommandot kontrollerar den tätaste asteroidmeshen, giltiga shaderresultat, två solars glöd vid 1 respektive 30 AU samt att framförliggande djup släcker glöden. Det andra renderar den riktiga Saturnusscenen, en närliggande ringsten och Solen från 30 AU genom hela renderingskedjan.