Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Generazione procedurale di galassie
Studente/i
Taddei Christian
Relatore
Marino Alge
Correlatore
Tiziano leidi
Committente
SUPSI
Corso di laurea
Ingegneria informatica(Informatica TP)
Modulo
Progetto di diploma
Anno
2018
Data
11 settembre 2018
i
Indice
1 Introduzione 1
1.1 Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Obiettivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3 Tecnologie e contesto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1 Generazione procedurale . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.2 Cassiopeiae . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.3 Unity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Pianificazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.1 Generazione procedurale . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.2 Serializzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.3 Rappresentazione grafica . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Stato dell’arte 5
2.1 Prodotti concorrenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1 Procedural Galaxies . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.2 The Galaxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.3 Galaxy Space - Procedural Galaxy Generator . . . . . . . . . . . . . . 6
2.1.4 Martin Evans’s Procedural Generation for Dummies . . . . . . . . . . . 7
2.1.5 Conclusione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Generazione procedurale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1 Random noise generation . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.2 Unity generic asset generation . . . . . . . . . . . . . . . . . . . . . . 9
2.2.3 Unity simple procedural generation . . . . . . . . . . . . . . . . . . . . 9
2.3 Rappresentazione grafica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.1 Shader Manuali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.2 ShaderForge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.3 Human Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.4 Space Graphics Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.5 Assets Statici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.6 Conclusione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Generazione procedurale di galassie
ii INDICE
3 Nozioni astronomiche 15
3.0.1 Galassia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.0.2 Stelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.0.3 Sistemi planetari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.0.4 Orbite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.0.5 Pianeti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.0.5.1 Tipologie di pianeti . . . . . . . . . . . . . . . . . . . . . . . 18
3.0.5.2 Distribuzione orbitale . . . . . . . . . . . . . . . . . . . . . . 18
3.0.5.3 Fascia abitabile . . . . . . . . . . . . . . . . . . . . . . . . . 19
4 GalGen 21
4.1 Realismo e semplificazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 Funzionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.3 Struttura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.4 Componenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.1 GalaxyGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.1.1 CoreGenerator . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.1.2 DiscGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.1.3 HaloGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.4.2 StarGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.4.3 SolarSystemGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.4.4 PlanetGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.4.5 Nota sui satelliti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.5 Gerarchia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.6 Distribuzioni Statistiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.6.1 Distribuzione normale . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.6.2 Distribuzioni limitate . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.7 Distanze e misure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.8 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.8.1 JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.8.2 Linguaggio alternativo alla deserializzazione . . . . . . . . . . . . . . 29
5 GalVis 31
5.1 Funzionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1.1 Livelli di visualizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1.1.1 GalacticView . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.1.1.2 SystemView . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.1.1.3 PlanetView . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.1.2 Interpretazione dei dati . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.2 Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Generazione procedurale di galassie
iii
5.2.1 Problemi riscontrati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2.2 Planet Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.2.3 Star Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.3 Farland Skies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6 Conlusione 39
6.1 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
6.2 Sviluppi futuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Generazione procedurale di galassie
iv INDICE
Generazione procedurale di galassie
1
Capitolo 1
Introduzione
1.1 Abstract
Generare secondo una distribuzione astronomicamente accurata le stelle ed i pianeti conte-
nuti in una galassia dal numero di stelle arbitrario. Rappresentare graficamente la galassia
generata in modo da poterne visualizzare i contenuti con uno stile realistico.
1.2 Obiettivo
Come progetto di diploma mi è stato chiesto di realizzare un generatore procedurale di ga-
lassie che si adatti ai requisiti del progetto Cassiopeiae. Il generatore deve creare con una
procedura automatica scritta in Java un file JSON (che diventerà poi un database) conte-
nente la rappresentazione di una galassia vicina alla realtà, seppur con un numero molto
più limitato di stelle e che rispetti la distribuzione di stelle e pianeti nel modo più accurato
possibile. Ogni oggetto della galassia, ovvero stelle e pianeti, deve possedere delle caratte-
ristiche fisiche distinte (es. temperatura, raggio, livello dei mari, ...) ed essere rappresentato
graficamente in modo che queste caratteristiche siano il più possibile riconoscibili dall’uten-
te, ma al contempo rispecchino l’aspetto reale dell’oggetto.
La rappresentazione grafica deve essere gestita dal motore di gioco Unity, ed il codice gene-
rato deve prestarsi all’utilizzo ed all’integrazione con il progetto Cassiopeiae durante sviluppi
futuri. Inoltre la parte grafica è pensata per essere eseguita su clients mobile, ed è neces-
sario quindi ottenere un risultato con prestazioni di render in tempo reali su devices dalla
potenza di calcolo limitata.
Generazione procedurale di galassie
2 Introduzione
1.3 Tecnologie e contesto
1.3.1 Generazione procedurale
Per generazione procedurale si intende un approccio alla generazione di contenuti automa-
tica, contrapposta alla creazione manuale di un numero finito di elementi. Attraverso vari
algoritmi si intende abilitare la creazione di un grande numero di scenari differenti senza
bisogno di interventi manuali.
Nello specifico del progetto verranno generati una galassia e svariate stelle e pianeti se-
condo regole ben definite dettate sia dalle necessità di gameplay che dalle reali regole che
governano l’universo conosciuto. Per la galassia sarà necessario sviluppare delle procedure
che distribuiscano un numero determinato di stelle nello spazio in modo che il risultato cor-
risponda alla struttura di una galassia spirale. Per ogni stella sarà necessario determinare
i suoi tratti (come tipo di stella, colore e raggio) in modo che questi risultino coerenti con la
sua posizione nella galassia. Successivamente ogni stella verrà circondata da pianeti, il cui
tipo e numero dipenderà dal tipo di stella, e anche questi possiederanno delle caratteristiche
generate proceduralmente e consistenti con la loro posizione ed con la stella che orbitano.
1.3.2 Cassiopeiae
Cassiopeiae è un progetto interno all’ISIN 1 che si prefigge di sperimentare sulle infrastrut-
ture e teconologie per il digital gaming, quali grafica 3D, networking, tecnologie di cloud
computing ed impiego di dispositivi mobile. La simulazione ottenuta come risultato di que-
sto progetto è legata a tutti questi aspetti, in quanto deve essere generata su di un server
ma sarà invece rappresentata su devices mobiles, deve soddisfare constraints di regolarità
e struttura dettati da necessità di gameplay ed il suo stile grafico deve allinearsi con lo stile
adottato per realizzare le altre componenti grafiche del progetto.
Il progetto Cassiopeiae è stato iniziato da Alghe Marino e Tiziano Leidi con lo scopo didattico
di permettere agli studenti SUPSI di apprendere le suddette tecnologie. Secondariamente
il progetto si prefigge di ottenere una demo tecnica di quello che è possibile realizzare in
ambito SUPSI nell’ambiente del gaming.
1.3.3 Unity
Unity è il game engine più diffuso e utilizzato nell’industria del digital gaming. Si tratta di
un ambiente di sviluppo comprendente un editor atto alla creazione di videogiochi 2D e 3D.
L’editor permette anche ad un utente non specializzato di realizzare velocemente demo o
concept di videogiochi tramite un’intuitiva interfaccia drag-n-drop. Per un utenza più tecnica
(come nel nostro caso) è possibile creare scripts in C# per regolare i vari aspetti della simu-
lazione.1Istituto SUPSI - Information Systems and Networking
Generazione procedurale di galassie
3
Questo motore è supportato da una community numerosa che rende semplice cercare so-
luzioni o alternative ai problemi, ed uno store contenente numerosi assets, gratuitamente o
a pagamento, che permettono di ampliare velocemente le funzionalità, sopratutto gli aspetti
grafici, di un progetto con risorse esterne.
1.4 Pianificazione
Il progetto è stato diviso in alcune fasi atte a stabilire dapprima quali tecnologie e tecniche
utilizzare, ed un seguito a come adattarle agli scopi del progetto.
1.4.1 Generazione procedurale
Scorrendo il codice sorgente del generatore utilizzato come placeholder all’interno di Cas-
siopeiae è subito risultato chiaro che il prodotto forniva una buona soluzione ed è quindi
stato deciso di creare un programma dalla struttura e dal funzionamento simili. Prima di
iniziare a sviluppare sono state anche analizzate altre soluzioni (vedi 2.2) che nonostante
non siano state utilizzate hanno comunque fornito ispirazione e metodi per affrontare il pro-
blema.
In quanto il generatore di galassie temporaneo si limita a creare stelle, è stato necessario
studiare una soluzione differente per quello che riguarda i pianeti. L’assets utilizzato pre-
cedentemente a questo scopo non si è rivelato per nulla idoneo in quanto la qualità del
codice era molto bassa e non possedeva molte delle caratteristiche richieste. È stato quindi
ritenuto più produttivo estendere il generatore di galassie con una componente interamente
nuova costruita da zero e sviluppata ad-hoc.
1.4.2 Serializzazione
Essendo gli ambienti di sviluppo dettati dalla consegna, è subito apparso chiaro che sarà
necessario trasmettere i dati da un programma Java all’editor Unity attraverso un file JSON.
La prima scelta da effettuare è stata dunque in quale modo serializzare e deserializzare i
dati.
Sfortunatamente la prima scelta è stata quella di non deserializzare i dati, ma invece di
creare un linguaggio proprietario per parsare i dati a runtime attraverso una serie di formu-
le, anch’esse parsate a runtime. Il linguaggio avrebbe dovuto creare in modo dinamico lo
shader adatto all’oggetto da renderizzare. Il vantaggio doveva essere quello di non avere
un modello statico nel client, così che su un aggiornamento dei tipi di dato contenuti nel da-
tabase non avrebbe richiesto un aggiornamento del client ma solamente un aggiornamento
del file contenente le formule. Questa soluzione è stata scartata, ed i motivi sono spiegati
in dettaglio in un capitolo a se (vedi 4.8.2) .
Una volta scartato il linguaggio proprietario e rivalutata la soluzione più semplice si è trat-
Generazione procedurale di galassie
4 Introduzione
tato solo di decidere quali librerie utilizzare per serializzare e deserializzare i dati in JSON.
Per serializzare i dati ottenuti dalla generazione in Java è stata scelta la libreria di Goo-
gle, GSON, mentre su Unity è una scelta quasi obbligata quella di utilizzare la soluzione
Microsoft complementare a C#, JSON.net, fornita come asset all’interno dello Unity Store.
1.4.3 Rappresentazione grafica
Essendo forzatamente da realizzare all’interno di Unity, la scelta di come realizzare la parte
grafica è stata relativamente semplice: da una parte si sarebbe potuto sviluppare uno sha-
der per rappresentare stelle e pianeti come parte integrante del progetto, ma questo avrebbe
richiesto molto tempo, diventando la parte principale del progetto, mentre l’alternativa scelta
è stata quella di basarsi su uno o più degli assets disponibili sullo store ed occuparsi solo di
adattarli alle esigenze del progetto.
Generazione procedurale di galassie
5
Capitolo 2
Stato dell’arte
Una volta decise le tecnologie utilizzate nel progetto, ma prima di iniziare a sviluppare le fun-
zionalità, ho effettuato delle ricerche riguardo gli attuali strumenti utilizzati per raggiungere
risultati simili. Nello specifico ho analizzato alcuni generatori procedurali utilizzati nell’indu-
stria videoludica e gli assets disponibili (sia gratuitamente che a pagamento) per coprire i
bisogni di grafica 3D del progetto.
2.1 Prodotti concorrenti
2.1.1 Procedural Galaxies
Un semplice prodotto che genera un oggetto visivamente simile ad una galassia posizio-
nando vari sprites nelle corrette posizioni. Il programma sistema nello spazio delle immagini
partendo dai parametri di grandezza della galassia, seguendo uno schema preciso che per-
mette di avere tutte le componenti 3.0.1 di una galassia.
La soluzione è però totalmente inadatta a questo progetto in quanto la galassia deve essere
riempita di oggetti realistici con determinate proprietà anch’esse generate proceduralmen-
te, mentre qui viene solo creata un’immagine che ricorda una galassia. Questa soluzione
può tornare utile nel caso si voglia aggiungere un effetto simile alla rappresentazione della
galassia, ma non si presta agli scopi del progetto.
2.1.2 The Galaxy
The Galaxy simula una galassia con un numero estremamente elevato di stelle, 1012 e man-
tenendo le distanze tra di esse realistiche. Il tutto riesce ad essere renderizzato in tempo
reale. Per quanto questi risultati siano interessanti, si basano sul fatto che ogni stella è sem-
plicemente un punto luminoso, mentre questo progetto richiede che esse siano popolate di
un sistema planetario. Le distanze realistiche, ovvero il fatto che la galassia abbia un raggio
di 60’000 anni luce mentre le stelle distano tra loro solo 4 anni luce, sono descritte come
Generazione procedurale di galassie
6 Stato dell’arte
Figura 2.1: L’oggetto generato da Procedural Galaxies
"una sfida tecnica". Questo ha portato a considerare di semplificare le distanze nel progetto,
in quanto si dovrebbero avere distanze ancora più piccole, quelle tra pianeti, e si rivelerebbe
certamente molto complicato mantenere il tutto in scala in un sistema unico.
Figura 2.2: l’insieme di punti generato da The Galaxy
2.1.3 Galaxy Space - Procedural Galaxy Generator
Questo asset dello Unity Store genera una galassia tramite un generatore di particelle, che
vengono distribuite in modo da formare una galassia spirale. Condivide gli stessi problemi di
Generazione procedurale di galassie
7
Figura 2.3: Uno sguardo ravvicinato di un settore da The Galaxy
Procedural Galaxies 2.1.1, e cioè che si limita ad essere una rappresentazione grafica, non
ci sono i dettagli sufficienti per popolare ed utilizzare questa struttura agli scopi del progetto.
Inoltre la galassia non è particolarmente accurata in quanto comprende soltanto un disco
galattico, niente nucleo e niente corona.
2.1.4 Martin Evans’s Procedural Generation for Dummies
Un buon punto di partenza per capire in quale modo il mio stesso problema sia stato risolto
da terzi è stata la guida Martin Evans’s Procedural Generation for Dummies, che mette a
disposizione il codice sorgente di un semplice generatore procedurale di galassie (limitato
alle posizioni delle singole stelle), che ho in seguito scoperto essere stato utilizzato come
base per la generazione della galassia di Cassiopeiae antecedente a questo progetto.
Il suddetto generatore procedurale si compone di elementi specializzati nella creazione di
varie parti della galassia partendo da metodi atti a popolare vaste sezioni, ad esempio il
core, nucleo della galassia, che invocano successivamente metodi sempre più generici,
richiedendo ad esempio che vengano generate delle posizioni di stelle all’interno di una
sfera. Combinando gli elementi generici, per la maggior parte primitive geometriche nelle
quale vengono posizionate le stelle, secondo i criteri contenuti nei metodi specializzati, si
ottiene un inseme molto complesso e strutturato che rappresenta in modo soddisfacente
una galassia spirale.
Oltre a mostrare una solida architettura software per un generatore procedurale, la guida mi
ha anche fornito alcuni utili suggerimenti come l’utilizzo di distribuzioni normali per determi-
Generazione procedurale di galassie
8 Stato dell’arte
Figura 2.4: Un’immagine dallo showcase di Galaxy Space
nare le posizioni, così da poter decidere in quali punti concentrare la densità delle stelle in
modo casuale ma realistico.
2.1.5 Conclusione
In luce di queste considerazioni è stato scelto di realizzare un programma dalla struttura
simile a quella di Evans, ma con funzionalità aggiuntive per la generazione di sistemi pla-
netari e di pianeti, mentre l’aspetto grafico verrà completamente separato e sarà realizzato
interamente all’interno di Unity.
Trattandosi solo di un generatore dimostrativo non è stato comunque possibile utilizzare il
codice fornito tale e quale, ed è stato deciso di riscrivere da zero il codice sorgente adattan-
dolo alle necessità del progetto, ovvero popolare la galassia in modo realistico con stelle di
tipi diversi distribuite con probabilità precise nei vari settori e aggiungere sistemi planetari
alle stelle generate.
2.2 Generazione procedurale
2.2.1 Random noise generation
Uno dei metodi più comuni per realizzare la generazione procedurale è quello di generare
del noise 1 e poi costruire sulle sue proprietà le caratteristiche degli oggetti desiderati. Que-
sto approccio è molto utile per la generazione di oggetti continui come mappe, per esempio
combinando il noise con varie funzioni al fine di renderlo più regolare si possono generare
1il noise (rumore) è un segnale casuale
Generazione procedurale di galassie
9
Figura 2.5: La galassia generata dal codice di esempio fornito da Evans
proceduralmente heightmap o decidere di quali colori siano le varie zone.
Ci sono varie tecniche di generazione di noise che possono essere utilizzate per ottenere
un segnale che non è completamente casuale ma che mantiene delle proprietà strutturate.
Un esempio è il Perlin noise, che pur essendo casuale ha la proprietà di mantenere i sui det-
tagli tutti della stessa dimensione. Questo approccio però non si adatta alla generazione di
una galassia, in quanto questa è divisa in zone be precise secondo distribuzioni statistiche
delle quale è necessario avere il controllo. Perlin noise è però eccellente per la genera-
zione procedurale di textures, ed è la soluzione adottata dagli assets PlanetGenerator e
StarGenerator (vedi 5.2.2 e 5.2.3).
2.2.2 Unity generic asset generation
La seconda alternativa analizzata si propone di creare l’intero modello della galassia, ge-
rarchia ed assets compresi, in Unity. Per fare ciò si dovrebbe sviluppare una struttura di
progetto totalmente generica per poter contenere tutti i contenuti generati proceduralmen-
te. Per quanto sia avrebbe il vantaggio di un’integrazione diretta con Unity, risulterebbe
ridondante avere una struttura così dettagliata e generica sia nel generatore vero e proprio
(codice Java) che nel motore Unity (C#). Questa alternativa è quindi stata scartata.
2.2.3 Unity simple procedural generation
Uno dei modi più semplici per generare proceduralmente dei contenuti è quello di combina-
re tra loro vari elementi esistenti, invece che generare elementi diversi ogni volta. Questo
Generazione procedurale di galassie
10 Stato dell’arte
Figura 2.6: Un segnale bidimensionale generato tramite Perlin noise
è reso semplice dall’interfaccia di Unity, che permette di creare elementi in modo rapido e
senza l’ausilio di codice. Nel nostro caso sarebbe possibile creare dapprima una serie di
assets (stelle e pianeti) e poi distribuire le loro posizioni nello spazio basandosi sul genera-
tore procedurale in Java che ha potuto effettuare la generazione delle posizioni in maniera
autonoma.
Questa soluzione non soddisfa il requisito di avere una rappresentazione precisa delle ca-
ratteristiche di ogni elemento, ma è un buon punto di partenza. Da qui è stato deciso che
la parte di rappresentazione sarà eseguita totalmente da Unity, nel quale verranno instan-
ziati e regolati i parametri di alcuni assets tramite codice. La presenza di un prefab statico
pone anche il problema che, nel caso venisse aggiornato l’asset, sarebbe necessario rico-
struire il prefab manualmente, mentre la gestione dinamica permette di rigenerare il prefab
aggiornato automaticamente.
2.3 Rappresentazione grafica
2.3.1 Shader Manuali
Sviluppare uno shader manualmente, scrivendo il codice richiesto nei linguaggi specifici per
questo compito, è una faccenda dispendiosa in termine di tempo e conoscenze necessarie.
Contenendo questo progetto molti altri obiettivi è subito stata scartata l’ipotesi di generare
da zero degli shader che si adattassero ai nostri scopi.
2.3.2 ShaderForge
Purtroppo discontinuato, questo asset permette di realizzare degli shaders tramite un editor
visuale a nodi, risparmiandosi lo sviluppo dello shader via codice. Anche se ottimo per
la creazione di sostanze ed effetti, creare un pianeta attraverso questo shader richiede un
Generazione procedurale di galassie
11
dispendioso lavoro di ricerca o generazione di textures adatte e combinazione di effetti. Per
quanto riguarda gli scopi di questo progetto questa soluzione è troppo di basso livello.
2.3.3 Human Unit
Scorrendo gli assets disponibili sullo store di Unity due di essi sono subito risaltati nettamen-
te superiori alla concorrenza. Si tratta di assets che offrono shaders con i quali renderizzare
stelle e pianeti rispettivamente, creati dai russi di Human Unit e disponibili per un prezzo
contenuto (9.50$ e 13$, comparati ad altri assets dai risultati inferiori e dal prezzo di 20 e
oltre). Anche qui ho scoperto che erano già stati acquistati per il progetto Cassiopeiae, e mi
sono subito stati forniti perché ne verificassi l’usabilità e le potenzialità.
Figura 2.7: Un pianeta generato tramite demo web di Planet Generator
Per quanto forniscano risultati eccellenti, il loro caso d’uso era stato probabilmente pensato
come un semplice copia-incolla dei prefab forniti, uno alla volta, all’interno di scene 3D,
mentre il progetto necessita di essere in grado di generare svariate stelle e pianeti unici,
contemporaneamente all’interno della stessa scena e con prestazioni elevate. Inoltre la
qualità del codice e della documentazione si è rivelata a volte carente, spaziando fino a
grossolani errori nella battitura di varie parole inglesi che compongono i nomi di prefab o
metodi. Ho dunque dedicato del tempo per realizzare una dimostrazioni di come questo
assets potesse essere adattato alle necessità del progetto, da prima tramite uno showcase
di quali risultati grafici si potessero ottenere, e in seguito con una tech-demo di generazione
di molteplici pianeti unici e indipendenti la cui rappresentazione grafica corrisponde ai dati
Generazione procedurale di galassie
12 Stato dell’arte
Figura 2.8: Una stella presa dallo showcase di Star Generator
Figura 2.9: Un’altra stella presa dallo showcase di Star Generator
del pianeta stesso.
Questi assets sono entrambi basati su ShaderForge, permettendo quindi se necessario di
entrare nei dettagli di come siano stati realizzare e modificare parametri e proprietà non
esposte all’utente finale.
2.3.4 Space Graphics Toolkit
Un asset dall’aspetto ancora più allettante di quelli forniti da Human Unit, questo pacchetto
comprende anche effetti fantascientifici come la deformazione della luce vicino ad un buco
nero o la dilatazione delle stelle spesso associata con il salto nell’iperspazio. Purtroppo il
suo costo di 99$ ed il fatto che gli assets di Human Unit fossero già presenti nel proget-
to hanno fatto si che l’idea venisse scartata, lasciando questo pacchetto come possibile
upgrade per futuri sviluppi del progetto.
2.3.5 Assets Statici
Sullo store di Unity è possibile trovare una gran varietà di pianeti e stelle già precostruiti, ma
la gran parte di questi assets precludono la possibilità di generare dinamicamente contenuti.
Generazione procedurale di galassie
13
Figura 2.10: Una stella presa dallo showcase di Space Graphics Toolkit
Figura 2.11: La resa grafica di una galassia presa dallo showcase di Space Graphics Toolkit
Questa variante si sarebbe adattata bene alla Simple Unity Procedural Genration 2.2.3, ma
essendo stata scartata, di conseguenza anche la presenza di assets statici nel progetto è
stata esclusa.
2.3.6 Conclusione
È infine stato deciso che gli assets di Human Unit sarebbero stati analizzati più in dettaglio,
e dopo essersi rivelati in grado di fornire le funzionalità richieste sono stati adottati come la
soluzione ufficiale ai bisogni grafici del progetto.
Generazione procedurale di galassie
14 Stato dell’arte
Generazione procedurale di galassie
15
Capitolo 3
Nozioni astronomiche
Per realizzare un generatore di galassie realistiche, è necessario avere un’idea di come la
nostra galassia e tutti gli oggetti che la popolano siano distribuiti. Ricercando questo ar-
gomento mi sono reso conto di quanto lo spazio sia ancora sconosciuto, specialmente per
quanto riguarda il numero e la posizione dei pianeti.
I dati che ho raccolto sono poi stati semplificati ad un livello di compromesso tra realismo
e semplicità, scartando una vasta gamma di parametri il cui impatto è stato valutato come
trascurabile. Nel caso di dati sconosciuti o dei quali non abbiamo abbastanza campioni per
estrarre una distribuzione probabilistica, mi sono basato sul nostro sistema solare come
rappresentate così da avere dei dati credibili anche se non scientificamente accurati.
Un’importante semplificazione rispetto al funzionamento reale della galassia è quella di
considerare le stelle come immobili, mentre in realtà queste orbitano tutte il centro della
galassia, nel quale si suppone risieda un buco nero. Un modello del genere risulterebbe
immensamente caotico, e le stelle sono quindi trattare come se fossero fisse in un momento
preciso di questa rotazione. Questi concetti sono spiegati in dettaglio nella teoria di densità
delle onde, ma esplorarli più in dettaglio esula dagli scopi del progetto 1.
3.0.1 Galassia
Con il termine galassia intendiamo in questo documento una galassia spirale come quella
nella quale risiede la terra. Questo tipo di galassia è composto da un nucleo centrale,
chiamato anche core o bulge, di giovani stelle che ruotano vorticosamente attorno ad un
buco nero. Questa zona è di forma sferica ed il suo raggio è maggiore all’altezza del disco
galattico che la circonda.
La seconda zona è appunto il disco galattico, la parte che si estende radialmente dal centro
e che forma la parte più vasta della galassia. La maggior parte delle stelle nel disco è
distribuita sui rami (arms), ovvero tentacoli che si estendono spiraleggiando dal centro al
1anche se una chiara idea della reale rotazione della galassia si può ottenere dall’animazione a questo linkhttps://www.youtube.com/watch?v=Xtw4cEjFBDs
Generazione procedurale di galassie
16 Nozioni astronomiche
bordo della galassia. L’altezza del disco è nettamente inferiore al suo raggio.
Infine ci sono stelle sparse sopra e sotto il disco, in quella che viene definita corona (halo),
che occupa il volume di una sfera dal raggio poco più grande di quello del disco ma è
nettamente meno densamente popolate da stelle, tendenzialmente molto vecchie.
3.0.2 Stelle
Le caratteristiche alle quali siamo interessati riguardo le stelle sono:
• Colore
• Raggio
• Temperatura
Queste informazioni sono correlate in modo stretto e lo schema in figura 3.1 è funto da guida
per la creazione di stelle consistenti con la realtà.
La distribuzione delle stelle nella galassia si basa sul presupposto che le stelle più lontane
siano le più vecchie, e di conseguenza le più fredde (categorie G, K, M), mentre il centro
della galassia è popolato dalle stelle più giovani e calde (categorie O, B, A).
3.0.3 Sistemi planetari
Le regole secondo le quali attribuire ad ogni stella un dato numero di pianeti non sono co-
nosciute precisamente. L’osservazione dei pianeti sfrutta tecniche i cui risultati variano a
dipendenza delle condizioni del sistema osservato, creando una situazione dove le informa-
zioni abbondano solo per determinate tipologie di pianeti e sistemi.
I sistemi generati all’interno di questo progetto si basano su regole generiche relative ai tipi
di stelle:
• Le stelle di tipo O emettono un effetto fotoevoprante che blocca la formazione di
pianeti, e ne sono quindi prive.
• Le stelle di tipo M hanno una massa troppo bassa per attrarre grossi corpi celesti, e
sono quindi circondate da pianeti di taglia piccola.
• La metallicità di un pianeta (che nella nostra semplificazione è indirettamente propor-
zionale all’età della stella) influisce sulla taglia e quantità dei pianeti, quindi stelle più
giovani sono circondate da più pianeti che possono raggiungere le taglie più grandi.
• Le stelle dalla metallicità bassa non posseggono giganti gassosi tra i loro satelliti
Questo crea un andamento dove le stelle più giovani sono circondate da sistemi più nume-
rosi con pianeti più voluminosi, ad eccezione delle stelle di categoria O che sono tenden-
zialmente prive di pianeti.
Generazione procedurale di galassie
17
Figura 3.1: Uno schema che illustra temperatura, raggio, massa e colore delle variecategorie di stelle
3.0.4 Orbite
Le orbite dei singoli pianeti attorno ad una stella sono molto varie, e la loro distribuzione
radiale sembra casuale in quanto si possono osservare molti tipi diversi di disposizioni.
È invece risaputo che le orbite più vicine alla stella sono tutte contenute all’incirca nello stes-
so piano (che non è però coincidente con il piano galattico) ma più ci si allontana più l’orbita
può inclinarsi, fino ad essere quasi perpendicolare alle altre. La direzione di rotazione orbi-
tale è uguale per tutti i pianeti di un sistema, in quanto si pensa che in origine fossero tutti
parte di una nube di polvere dalla quale hanno ereditato il senso di moto.
Generazione procedurale di galassie
18 Nozioni astronomiche
Figura 3.2: Conformazione orbitale di alcuni sistemi osservati
3.0.5 Pianeti
3.0.5.1 Tipologie di pianeti
Esistono varie tipologie di pianeti, ma per semplicità le categorie alle quali questi possono
appartenere sono limitate in questo progetto. Ai nostri scopi un pianeta può essere
Desolato una roccia priva di vita e dalle caratteristiche inospitali
Abitabile ricoperto principalmente da oceani e con atmosfera respirabile
Gigante Gassoso composto da vortici turbinanti di gas
Oceanico raggruppa pianeti come Nettuno e Urano, teoricamente giganti ghiacciati, e tutti quei
pianeti composti da sostanze fuse e che sembrano quindi interamente ricoperti di
liquido.
3.0.5.2 Distribuzione orbitale
Le dimensioni ed il tipo dei pianeti in un sistema planetario dipendono dal raggio della sua
orbita, secondo le seguenti regole:
• nella fascia più vicina (fino a 10-15 UA) i pianeti sono di piccole dimensioni, vicine a
quelle della terra (0.5-3 raggi terrestri). In genere sono pianeti desolati, ma si ipotizza
che questa sia la fascia che potrebbe contenere pianeti abitabili.
Generazione procedurale di galassie
19
• la fascia intermedia (da 10-15 UA fino a 20-30 UA) contiene pianeti giganteschi (10-30
raggi terrestri), desolati o giganti gassosi.
• l’estremità esterna è popolata da pianeti di dimensioni medie (3-10 raggi terrestri),
desolati o oceanici.
3.0.5.3 Fascia abitabile
Se un pianeta si trova all’interno della fascia abitabile per un determinato tipo di stella, è
possibile che questo sia abitabile. Come riferimento è stato utilizzato lo schema in figura
3.3.
Figura 3.3: Fasce abitabili delle varie tipologie di stelle
Generazione procedurale di galassie
20 Nozioni astronomiche
Generazione procedurale di galassie
21
Capitolo 4
GalGen
Il generatore di galassie procedurale sviluppato per questo progetto si occupa di popolare
uno spazio 3D con una distribuzione realistica di stelle e di creare sistemi planetari attorno
a queste stelle. Il generatore è stato creato per esser eseguito su di un server, non è quindi
sottoposto ai requisiti di alte performances derivanti dal client mobile come invece la parte
di visualizzazione. Nonostante questo il programma deve comunque rimanere scalabile e
performante in vista di requisiti di galassie sempre più vaste.
4.1 Realismo e semplificazioni
Il generatore cerca di utilizzare al meglio le proprietà e regole viste nel capitolo riguardan-
te le nozioni astronomiche, ma alcuni compromessi sono stati presi per rendere il risultato
finale utilizzabile nel contesto di Cassiopeiae, o perché altrimenti la complessità del tutto
sarebbe aumentata spropositatamente.
In primis la distanza relativa tra le stelle non è misurata in anni luce ma rimane senza unità
di misura, in quanto sarebbe poi estremamente scomodo utilizzare questi valori enormi in
una rappresentazione grafica, dove le dimensioni degli oggetti sono di un ordine di grandez-
za nettamente inferiore.
La seconda semplificazione è quella di considerare le stelle fisse, invece che farle orbitare
a velocità diverse attorno al centro della galassia. Questo perché, se si vuole mantenere
una forma riconoscibili di galassia a spirale, il modello di rotazione risulterebbe piuttosto
complicato, ed inoltre si avrebbe una galassia dove ogni distanza è perennemente in mu-
tamento, rendendo fare delle previsioni all’interno del gameplay di Cassiopeiae totalmente
impossibile.
L’ultima semplificazione è quella di avere tutti i piani orbitali di un sistema paralleli al piano
galattico. Questo aspetto è reso irrilevante dal fatto che quando vogliamo rappresentare un
sistema planetario questo viene sempre ruotato così da vedere le orbite tendenzialmente
orizzontali, e quindi la sottigliezza della sua inclinazione rispetto al piano galattico è persa.
Generazione procedurale di galassie
22 GalGen
Questa è comunque una scelta che può essere facilmente scartata nel caso si voglia au-
mentare il realismo, e il sistema si presta con poche modifiche a contenere questo ulteriore
parametro di inclinazione.
4.2 Funzionamento
GalGen genera una galassia partendo da due parametri principali: la dimensione della ga-
lassia, in unità arbitrarie, ed il numero di stelle con le quali popolarla. Secondariamente è
possibile scegliere qual’è l’altezza del disco galattico e quante braccia lo compongano. Con
questi dati la routine riempie una sfera di raggio vicino 1 alla dimensione desiderate con
pianeti e stelle.
Una volta invocato, il generatore di galassie divide subito il processo in tre compiti distinti:
popolare il nucleo, il disco e la corona, per poi unire tutte le stelle generate in una sola lista.
In ognuna di queste sezioni di galassia vengono generate stelle in proporzione al numero
totale di stelle desiderate (non avendo a disposizione valori empirici sono state scelte le pro-
porzioni di 1/10 nel nucleo, 8/10 nel disco e 1/10 nella corona). Essendo l volumi occupati
dal nucleo e dal disco parzialmente sovrapposti al centro della galassia, questa zona risulta
particolarmente densa di stelle.
Da questo punto in avanti, ogni generatore specifico verrà chiamato dal precedente nell’or-
dine GalaxyGenerator -> StarGenerator -> SolarSystemGenerator -> PlanetGenerator, rice-
vendo quando necessario alcuni parametri conosciuti dal generatore invocante, per esempio
SolarSystemGenerator passa a PlanetGenerator il raggio orbitale al quale si trova il pianeta
come parametro per poter generare un pianeta consistente.
4.3 Struttura
Come accennato in precedenza il generatore di galassie si compone di vari generatori spe-
cializzati. Trovare una divisione dei compiti per ogni classe è risultato piuttosto complicato
in quanto molte decisioni sono prese sulla base di parametri presenti più in alto nella gerar-
chia. In genere si è optato per passare tutti i parametri necessari ai generatori successivi,
così da avere per esempio la logica riguardante i pianeti nel PlanetGenerator, anche se si
sarebbe potuto decidere il raggio (dipendente dal raggio orbitale) nel SolarSystemGenera-
tor, contemporaneamente al raggio orbitale.
Ogni generatore è statico e tutti i parametri sono passati all’invocazione del suo metodo
principale generate. Tutti i generatori ritornano un oggetto o una lista di oggetti del tipo
richiesto, che viene salvata in un campo dell’oggetto direttamente superiore nella gerarchia.
1essendo le stelle distribuite secondo una campana di gauss, queste possono risultare anche oltre al raggiodato
Generazione procedurale di galassie
23
4.4 Componenti
4.4.1 GalaxyGenerator
Il primo e più semplice dei generatori, non fa altro che invocare generate sui tre generatori
CoreGenerator, DiscGenerator e HaloGenerator, per poi unire i risultati (tre liste di stelle) in
un unica lista.
Ognuno dei componenti decide le posizione ed il tipo di ogni stella che gli viene chiesto di
generare, distribuendole in un’area determinata dai parametri principali, raggio galattico ed
altezza del disco.
4.4.1.1 CoreGenerator
CoreGenerator si occupa di riempire il centro della galassia con stelle giovani in modo molto
denso. Prendendo ispirazione dal generatore utilizzato in precedenza, un effetto visuale
interessante si ottiene se queste stelle non vengono semplicemente distribuite in una sfera
al centro della galassia, ma se la sezione centrale viene creata componendo più sfere dai
centri posizionati casualmente attorno all’origine. Questo simula il fatto che ci siano vari
clusters di stelle al centro della galassia.
In aggiunta essendo questa sezione attorno al centro della galassia, l’effetto di rotazione
simulata dal nostro generatore (di intensità proporzionale al raggio) è molto intenso, e quindi
viene applicato il metodo swirl con parametri maggiori di intensità. Il risultato è un nucleo
denso e turbinante di stelle brillanti.
4.4.1.2 DiscGenerator
Il compito di DiscGenerator è quello di popolare il piano galattico con le braccia della galas-
sia. Per fare ciò inizialmente si costruiscono dei cilindri, uno per ogni coppia di braccia, che
si estendono su tutto il diametro del disco. Le stelle sono distribuite secondo una campana
di gauss sugli tutte e tre le dimensioni del cilindro, ottenendo in pratica le densità maggiori al
centro dell’asse (che corrisponde al centro della galassia) e vicini all’asse lungo la sezione.
Questo crea quello che visivamente sembra un cono, anche se la distribuzione genera valori
all’interno di un cilindro, visto che la probabilità di generare una stella ai margini del cilindro
è bassa, e anche se venisse generata sarebbe con grande probabilità vicina all’asse.
Il processo è ripetuto una volta per ogni due braccia, ruotando l’asse del cilindro lungo la
normale del piano galattico , ed infine le stelle sono ruotate attraverso il metodo swirl per
simulare la rotazione delle stelle nella galassia.
Ogni braccio contiene stelle di tutte le età, ma la distribuzione è stata spostata artificialmente
verso le stelle più vecchie per avere più contrasto rispetto al core.
Generazione procedurale di galassie
24 GalGen
Figura 4.1: Il risultato visivo della generazione del nucleo della galassia
Figura 4.2: Le braccia della galassia prima di venire ruotate
4.4.1.3 HaloGenerator
La corona della galassia non è altro che una sfera di densità molto bassa e popolata da
stelle principalmente vecchie. Non viene applicato nessuno swirl, anche perché essendo
Generazione procedurale di galassie
25
Figura 4.3: Le braccia della galassia nel loro stato finale
una struttura molto poco densa, non si noterebbe.
4.4.2 StarGenerator
Una volta che GalaxyGenerator ha deciso in quale punto generare una stella, e quale sarà il
suo tipo, i dettagli riguardanti le proprietà della stella come nome, temperatura et cetera, so-
no scelti da StarGenerator, che contiene una tabella dei possibili valori per le caratteristiche
fisiche di ogni tipo di stella secondo lo schema 3.1 visto in precedenza.
4.4.3 SolarSystemGenerator
Ogni stella generata da StarGenerator viene circondata da un sistema planetario. Il numero
di pianeti che compongono questo sistema è deciso dal tipo di stella, utilizzando una di-
stribuzione normale possibilmente moltiplicata per un fattore esterno, un numero che può
essere passato al generatore di galassie per generare una quantità maggiore di pianeti per
sistema, in quanto le statistiche reali, che indicano in media un singolo pianeta per sistema,
potrebbero generare un risultato troppo spoglio.
Essendo le orbite distribuite in modo apparentemente casuale, si usa una distribuzione
uniforme per determinare il raggio di ogni orbita. Una volta deciso il raggio, questo viene uti-
lizzato per generare una quantità di rotazione 2 che inclina l’orbita, con le orbite più lontane
influenzate maggiormente.
Le ultime due informazioni generate da SolarSystemGenerator sono raggio e tipo del piane-
ta, che dipendono anch’esse dal raggio dell’orbita e dal tipo di stella al centro del sistema.
Tendenzialmente i raggi planetari si distribuiscono secondo la figura 3.2 indipendentemente
2rispetto all’asse z, parallelo o contenuto nel piano planetario
Generazione procedurale di galassie
26 GalGen
dal tipo di stella, mentre per la tipologia di pianeta si utilizza una tabella specifica al tipo di
stella e che contiene fascia abitabile, presenza o meno di giganti gassosi e altre regole. A
questo punto viene invocato PlanetGenerator e gli vengono passate tutte le informazioni già
generate riguardanti il pianeta.
4.4.4 PlanetGenerator
Ricevendo il tipo di pianeta da SolarSystemGenerator, PlanetGenerator si occupa solamen-
te di generare delle informazioni coerenti attraverso una serie di distribuzioni (uniformi o
normali) per riempire i campi delle caratteristiche dei pianeti. Una volta generate queste in-
formazioni e con l’aggiunta del resto dei parametri (raggio e orbita) PlanetGenerator ritorna
un’istanza del pianeta completo richiesto da SolarSystemGenerator.
4.4.5 Nota sui satelliti
Non essendo ancora implementati a nessun livello nel progetto Cassiopeiae, non è stato
realizzato alcun SatelliteGenrator ne SatelliteSystemGenerator. Nel caso si dovesse svi-
luppare in futuro un sistema di satelliti attorno ai pianeti, questo ricalcherebbe finemente al
generazione di pianeti attorno ad una stella, richiedendo quindi un lavoro minimo in quanto
basterebbe riutilizzare o estendere SolarSystemGenarator e PlanetGenerator.
4.5 Gerarchia
Gli oggetti creati sono tutti integrati nella gerarchia ereditata dal database di Cassiopeiae.
Nello specifico significa che le stelle sono l’elemento in cima alla gerarchia, ed esse con-
tengono ognuna il proprio sistema planetario (potenzialmente vuoto). Il sistema planetario
contiene ogni pianeta che lo popola, ed ognuno di essi può contenere un sistema di satelliti.
4.6 Distribuzioni Statistiche
Una parte importante del progetto è l’utilizzo di varie distribuzioni statistiche al fine di ot-
tenere una ripartizione degli elementi nello spazio che possieda un componente casuale
ma rimanendo comunque realistica. A questo scopo oltre alla distribuzione uniforme fornita
dal generatore di numeri pseudorandom di Java è stato necessario utilizzare alcune forme
più avanzate di distribuzioni statistiche, nello specifico varianti della la distribuzione normale
(campana di Gauss).
4.6.1 Distribuzione normale
Invece che basarmi su una libreria esterna, ho preferito implementare il semplice metodo
della trasformazione Box-Muller che permette di generare due valori indipendenti estratti da
Generazione procedurale di galassie
27
una distribuzione normale sfruttando il generatore di numeri pseudorandom di Java.
Questo metodo utilizza i logaritmi per generare, a partire da un valore V preso da una di-
stribuzione uniforme, un raggio secondo la formula R =√−2 lnV . Questa formula fornisce
un raggio tra 0 e 1, ma con una maggiore probabilità di essere vicino a 0. Similmente viene
scelto un angolo tra 0 e 2π tramite un altro valore W dalla distribuzione uniforme (θ = 2πW ).
I valori che simulano la distribuzione normale sono R sin θ e R cos θ.
Figura 4.4: Uno schema che aiuta a capire come la trigonometria possegga le caratteristichenecessarie a generare una distribuzione normale
L’implementazione calcola entrambi i valori della distribuzione normale anche se uno solo
viene richiesto, e salva l’altro in un buffer così da poterlo riutilizzare alla prossima chiamata.
Generazione procedurale di galassie
28 GalGen
4.6.2 Distribuzioni limitate
Un problema che potrebbe sorgere utilizzando le distribuzioni normali è che, seppur con una
bassa probabilità, potrebbero essere generati dei valori molto lontani dalla media. Questo
darebbe origine a stelle lontanissime o pianeti enormi per esempio, casi che seppur rari
porterebbero a dover considerare un gran numero di aberrazioni e le conseguenti misure da
prendere per integrarle nella simulazione. Si è rivelato più semplice sviluppare un metodo
per ottenere dei valori assicurati in un certo intervallo. L’implementazione scelta è la più
diretta (e la meno performante, ma la parte di generazione non è sottoposta ai requisiti
di performance come la rappresentazione grafica), e cioè quella di ripetere le estrazioni di
valori se questi non sono compresi nel range desiderato. Con più tempo a disposizione, o
in sviluppi futuri, sarebbe certamente stato possibile implementare metodi più complessi e
performanti, come l’inversa phi, mentre la semplice troncatura del valore ottenuto verso il
range desiderato creerebbe una densità maggiore ai bordi ed è quindi subito stato escluso.
4.7 Distanze e misure
Le misure dei vari oggetti sono espresse nell’unità di misura effettivamente utilizzata dall’a-
stronomia per misurare gli stessi. Vale a dire che il raggio di un pianeta è misurato in raggi
terrestri (earth radii), il raggio di una stella è misurato in raggi solari (sun radii) e le distanze
orbitali in unità astronomiche [AU]. Le distanze relative tra le stelle non posseggono invece
unità di misura, in quanto il generatore riempie una galassia delle dimensioni passate come
parametro. È compito di GalVis ridimensionare la galassia e dare un senso alle distanze
interstellari.
4.8 Output
Il risultato finale, una volta che tutti gli oggetti sono stati creati in Java, viene serializzato ver-
so un file testuale in formato JSON. Questo non sarà l’utilizzo che verrà fatto del generatore
di galassie, che sarà invece utilizzato per riempire un database, ma permette di ottenere
una forma utilizzabile e comunque molto vicina all’uso previsto.
4.8.1 JSON
Serializzando tutti gli oggetti ottenuti tramite la libreria GSON, il risultato finale ha la forma
di un file testuale contenente un array JSON dove ogni oggetto rappresenta una stella, che
può a sua volta contenere un sistema planetario al cui interno sono listati i pianeti che lo
compongono.
Il modello di tutti gli oggetti è stato preso dal modello correntemente utilizzato da Cassio-
peiae, e sono state apportate delle piccole modifiche solo dove strettamente necessario,
Generazione procedurale di galassie
29
principalmente all’interno dell’oggetto Planet, visto che le sue caratteristiche sono state de-
finite principalmente in questo progetto una volta verificato cosa si può ottenere dallo shader
grafico dei pianeti, e di conseguenza quali caratteristiche sia importante memorizzare e qua-
li invece non avrebbero alcun impatto.
Come accennato più su, il modello è stato modificato per adattarlo a JSON, in particolare
le referenze cicliche che sarebbero risultate problematiche (come una stella che contiene il
suo sistema planetario in un campo che a sua volta contiene un riferimento alla stella cen-
trale) sono state sostituite con referenze all’identificatore unico dell’oggetto, permettendo
cosi di serializzare semplicemente un numero invece dell’intero oggetto. Queste modifi-
che permettono al progetto di esistere indipendentemente da Cassiopeiae, ma sono state
apportate comunque con coscienza che quando il generatore sarà integrato nel progetto
potrebbero dover essere modificate.
4.8.2 Linguaggio alternativo alla deserializzazione
Anche se non ha visto la luce nella forma finale del progetto, del tempo è stato speso per
realizzare un linguaggio che permettesse al client di estrarre le informazioni necessarie a
rappresentare stelle e pianeti senza dover possedere un modello statico del contenuto del
file come la deserializzazione classica invece richiede. L’intenzione era quella di poter ag-
giornare il modello del generatore senza che questo comportasse una patch del client per
aggiornare di conseguenza il corrispondente modello utilizzato per la deserializzazione.
Per fare ciò era stato ideato un linguaggio in grado di interpretare delle semplici formule del
tipo seguente:
HU_water_level = water_level * 0.25 + 0.5
Questa formula avrebbe letto il valorewater_level dal file JSON basandosi solo sul nome,
senza appoggiarsi ad un modello, ed effettuato le operazioni aritmetiche necessarie a tra-
sformare il valore in un numero che si prestasse al campo HU_water_level presente nello
shader, in pratica traducendo a runtime i valori contenuti nel JSON (valori realistici) nei valori
necessari allo shader per rappresentare i vari oggetti.
Il linguaggio è stato sviluppato in modo funzionante nell’arco di una settimana e compren-
deva strutture logiche come if per poter decidere quale formula utilizzare a dipendenza ad
esempio del tipo di pianeta, permettendo di scrivere per esempio:
HU_population = if type "earthlike" then population / 10_000_000 else
if type "barren" then population / 50_000_000 + 5_000 fi
fi
Anche se è stato possibile utilizzarlo inizialmente, con lo svilupparsi del progetto si sono
profilati alcuni problemi le cui soluzioni avrebbero spinto il linguaggio a diventare sempre più
Generazione procedurale di galassie
30 GalGen
simile ad un deserializzatore, perdendo i vantaggi che si speravano di ottenere. Alla fine è
stato scelto di scartare il linguaggio e tornare alla deserializzazione classica, principalmente
per risparmiare il tempo necessario a sviluppare e mantenere un linguaggio proprietario.
Generazione procedurale di galassie
31
Capitolo 5
GalVis
La seconda parte del lavoro consiste nel visualizzare i dati generati in precedenza nel mo-
tore Unity. Il codice prodotto per questa dimostrazione servirà poi da base al progetto Cas-
siopeiae per visualizzare la galassia all’interno dello scenario di gioco, e quindi sono stati
implementati vari metodi per visualizzare la galassia, i sistemi planetari ed i singoli pianeti.
Ogni oggetto visualizzato deve corrispondere nella sua rappresentazione ai dati che lo han-
no generato, per permettere all’utente di creare rapide associazioni visive del tipo "mare
beige -> pianeta inquinato" o "colore metallico -> risorse minerarie abbondanti", ma allo
stesso tempo le palette di colori e gli effetti utilizzati dovrebbero rimanere realistiche o al-
meno credibili. Un eccezione sono le stelle che, come in ogni altro contesto fantascientifico,
sono riprodotte in modo da poterne vedere chiaramente le caratteristiche come macchie,
getti et cetera, mentre nella realtà senza strumenti vedremmo solo puntini luminosi o, se
abbastanza vicini, ne rimarremmo accecati.
Una feature che non è richiesta è un sistema di esplorazione della galassia, come per
esempio una lista dei sistemi o una telecamera libera in grado di muoversi nella galassia, in
quanto queste funzionalità sono ancora in sviluppo all’interno del progetto Cassiopeiae, an-
che se comunque è stato speso del tempo per accertarsi di abilitare la futura realizzazione
di queste features.
5.1 Funzionamento
5.1.1 Livelli di visualizzazione
La visualizzazione della galassia è stata separata in livelli, ognuno dei quali possiede la sua
scala ed i suo specifici fattori di ingrandimento per poter rendere visibili oggetti che altrimenti
sarebbero minuscoli considerando distanze e proporzioni realistiche.
Generazione procedurale di galassie
32 GalVis
5.1.1.1 GalacticView
Il primo livello è la mappa galattica, chiamata GalacticView, nella quale è possibile visua-
lizzare l’insieme delle stelle generate in precedenza. Ogni stella è rappresentata con un
oggetto totalmente spoglio di effetti luminosi o animazioni, in quanto più di mille stelle sono
contemporaneamente visibili sullo schermo la maggior parte del tempo, ed è impensabile
(con l’ottimizzazione attuale della parte grafica) che un client mobile riesca ad elaborare in
tempo reale un numero simile di effetti complessi. La galassia ruota su se stessa per au-
mentare l’effetto tridimensionale, ma nell’astrazione dei dati ogni stella è invece fissa in un
punto preciso dello spazio.
Figura 5.1: Un’immagine della galassia nel visualizzatore GalVis
5.1.1.2 SystemView
Scendendo nel secondo livello, la SystemView, possiamo osservare il funzionamento di
un sistema planetario. Centrata sulla stella e di poco rialzata rispetto al piano delle orbi-
te, questa vista simula in tempo reale sia rotazione che rivoluzione dei pianeti, mostrando
chiaramente le orbite e le loro inclinazioni, quali pianeti popolano il sistema e le dimensioni
relative tra di essi. Qui la proporzione tra stella e pianeti, e anche le dimensioni relative tra
i pianeti, sono leggermente ritoccate, visto che sarebbe difficile visualizzare una stella che
può essere facilmente fino a cento volte più grande di un pianeta nella stessa schermata
di una decina di pianeti. Nella pratica le dimensioni della stella, che rimane comunque più
grande di qualunque pianeta, è fortemente ridotta mentre i pianeti più piccoli, che possono
avere un raggio di un cinquantesimo dei pianeti più grandi, vengono visualizzati come se
avessero un raggio minimo di 10 raggi terrestri, cosi che siano sempre visibili all’utente.
Generazione procedurale di galassie
33
Figura 5.2: Una stella circondata dai suoi pianeti nel visualizzatore GalVis
5.1.1.3 PlanetView
L’ultimo livello è l’osservazione ravvicinata di un singolo pianeta, PlanetView,che permette
di apprezzarne l’atmosfera, il ciclo giorno-notte, i rilievi e tutte le altre qualità rappresentate
graficamente (la lista è piuttosto lunga). Anche qui si devono tenere in conto dimensioni mol-
to diverse, ma poiché la telecamera si focalizza su di un singolo oggetto il problema non è
cosi complesso come in precedenza. Il pianeta osservato riempie sempre la maggior parte
dello schermo, essendo la telecamera posizionata ad una distanza che prende in conside-
razione la dimensione del pianeta, ma mantenendo un’apparente diversità di proporzioni tra
pianeti di dimensione diversa.
5.1.2 Interpretazione dei dati
I dati generati in precedenza sono fedelmente utilizzati per produrre la visualizzazione gra-
fica. I dati contenuti nel file JSON vengono deserializzati nello stesso identico modello di
gerarchia descritto in precedenza con l’ausilio dell’asset JSON.net. Da qui il modello viene
esteso per fare si che ogni oggetto contenga anche una referenza al GameObject di Unity
che viene utilizzato per rappresentarlo.
Una volta che la gerarchia rappresentante la galassia è stata ricostruita, un paio di classi
dedicate caricano un GameObject adatto nel campo ad esso dedicato. Queste classi sono
PlanetGenerator e StarGenerator, e contengono tutte le procedure che si dedicano a tra-
durre i dati in informazioni utilizzabili dagli shader planetari e stellari rispettivamente. Il loro
compito ricalca quello che inizialmente sarebbe stato dominio del linguaggio alternativo alla
deserializzazione, ovvero di tradurre dati reali (ie. raggio = 2.3 raggi terrestri) in informazioni
nella forma richiesta dallo shader (ie. dimensione tra 0 e 5 in float). Questo significa che
ogni classe contiene le istruzioni esatte per la traduzione e si occupa di instanziare un og-
Generazione procedurale di galassie
34 GalVis
Figura 5.3: La resa di un piccolo pianeta desolato
getto a partire dai prefabs forniti dai nostri assets, per poi modificare i valori dei suoi campi
rendendo l’oggetto una rappresentazione precisa dei dati utilizzati.
5.2 Assets
Gli assets utilizzati per poter dare una rappresentazione agli oggetti sono PlanetGenerator
e StarGenerator, entrambi degli sviluppatori russi Human Unit. Questi sono disponibili sullo
store di Unity ad un prezzo molto basso se confrontati con la concorrenza, ed offrono deci-
samente la migliore qualità grafica tra tutti gli assets analizzati.
Entrambi sono costruiti nello stesso modo, ovvero viene dato a disposizione uno shader 1 da
utilizzare per renderizzare un oggetto, pianeta o stella rispettivamente. Questo shader, che
crea un effetto visivo molto piacevole per entrambi i tipi di oggetti, è composto da una serie
di parametri che possono esser modificati a piacimento sia dall’editor di Unity stesso sia da
un qualunque script in C#. Questi parametri rappresentano una grande varietà di elementi
come caratteristiche atmosferiche, clima del pianeta o tipo di popolazione. Con una piccola
eccezione riguardante i giganti gassosi, tutti questi parametri sono comodamente controllati
da uno script fornito da Human Unit. Per i giganti gassosi invece è necessario modificare
direttamente lo shader accedendo ai tre colori che lo compongono, sue uniche proprietà.
1ovvero una procedura che si occupa di definire le proprietà di ogni pixel visibile dell’oggetto da renderizzare
Generazione procedurale di galassie
35
Figura 5.4: La resa di un grande pianeta desolato
5.2.1 Problemi riscontrati
Per quanto di primo acchito sembrassero perfetti questi assets si sono rivelati comunque
piuttosto complessi da padroneggiare, in quanto sembrano essere stati pensati per un uso
più semplice di quello richiesto da questo progetto. Nel caso d’uso per il quale immagino
siano stati creati gli shaders, l’utente dovrebbe limitarsi ad instanziare un singolo pianeta
dopo averne modificato manualmente le proprietà attraverso l’editor di Unity. Per quanto
riguarda questo progetto è invece necessario instanziare diversi pianeti a runtime in modo
che ognuno rimanga completamente indipendente dagli altri e modificare tutte le proprietà
in modo automatico attraverso degli script. Inoltre ci sono alcuni dettagli fastidiosi, come
ad esempio vari errori nei nomi di proprietà o di oggetti (ie. "Barren" è scritto "Baren").
Un altro problema è stata la discontinuazione di alcuni strumenti nel passaggio alla nuova
versione di Unity (2018), che hanno reso impossibile l’utilizzo di un generatore di skybox
fornito inseme a questi due assets. L’ultimo e più importante problema e che gli oggetti non
possono essere illuminati da luci di tipo point, ed è stato necessario adottare delle tecniche
più complicate per simulare la luce di una stella sui suoi pianeti.
Un problema che non ho riscontrato, ma del quale il readme degli assets avverte è quello
dell’esportazione degli oggetti verso piattaforme mobile android. In quel caso è necessario
seguire la procedura descritta nel readme per ottenere degli oggetti utilizzabili.
Generazione procedurale di galassie
36 GalVis
5.2.2 Planet Generator
PlanetGenerator crea gli shader necessari a renderizzare la superficie e l’atmosfera dei pia-
neti. La scelta principale da effettuare per un pianeta è quella della heightmap da utilizzare
per generare la superficie. Sono disponibili alcune heightmaps differenti:
Arctic questa heightmap non è stata utilizzata in quanto è molto irrealistica. La superficie
del pianeta è attraversata da oblique parallele di protuberanze, e questo parallelismo
conferisce un aspetto artificiale al pianeta.
Arid è una heightmap pianeggiante con alcune alture, e viene usata per generare pianeti
abitabili con una grande massa di terre emerse e sporadici laghi e fiumi tra di esse.
Barren (erroneamente chiamato baren) ricopre la superficie del pianeta di crateri, in modo
simile alla luna e a marte. Viene usata per i pianeti desolati.
Continental genera una heightmap simile alla superficie terrestre, con aree emerse montagnose
molto frequenti confronto alle altre heightmaps.
Desert crea una superficie quasi totalmente piana ma con chiazze di dettagli sparse, e viene
usata per un secondo tipo di pianeta desolato.
Jungle simile a Continental, ma le zone emerse simulano l’aspetto di una palude, con oceani
simili a grossi laghi sparsi tra di esse.
Lava utilizzata per i giganti ghiacciati, questa heightmap genera delle scanalature nel pia-
neta. Questo effetto è utilizzato per simulare una superficie irregolare come fondo
dell’oceano dei pianeti ricoperti di liquido.
Tutte le altre proprietà sono state combinate per colorare queste superfici, e grande cura
è stata prestata ad avere una serie di colorazioni realistiche. Come riferimento sono state
usate fotografie dei pianeti del nostro sistema solare, senza filtri.
5.2.3 Star Generator
Per le stelle è stato necessario creare uno stile omogeneo il più realistico possibile, ma non
essendo possibile guardare una stella senza alcun tipo di filtro non è stato possibile avere
un riferimento. Come base è stata utilizzata una stella dalle caratteristiche simile al nostro
sole già presente tra quelle fornite dall’asset. Questa è stata scelta in quanto era una delle
poche stelle realistiche, la maggior parte delle altre comprendeva effetti molto forzati come
getti, raggi ed altre componenti non adatte allo stile del progetto.
Da questa stella sono state create tutte le rappresentazioni dei vari tipi stellari, adattando
colore, luminosità e dimensione ai dati discussi nei capitoli precedenti.
Generazione procedurale di galassie
37
5.3 Farland Skies
Essendo il generatore di skybox allegato ai due assets di Human Unit inutilzzabile, è stato
selezionato un altro generatore, l’asset Farland Skies. Questo permette di generare sky-
boxes con la quantità desiderata di stelle e nebulose e di adattarne i colori a piacimento.
Con questo strumento si può generare una skybox corrispondente alla sezione di galassia
desiderata ed utilizzarla quando si entra nella System View di una stella. Per esempio la
skybox utilizzata per stelle nel nucleo è formata da nebulose più chiare, mentre quella di
stelle nella corona è fortemente rarefatta.
Generazione procedurale di galassie
38 GalVis
Generazione procedurale di galassie
39
Capitolo 6
Conlusione
6.1 Risultati
Il progetto sviluppato riesce a generare proceduralmente galassie da 10’000 stelle (la con-
segna richiedeva almeno 1’000 stelle) nell arco di 1 secondo. Questo risultato è nettamente
più veloce di quanto si immagina§§sse in un primo tempo, ovvero che la generazione di
un’intera galassia sarebbe stata dell’ordine delle ore.
Per la parte grafica invece è possibile simulare in tempo reale una galassia contenente al-
l’incirca 2000 stelle, così come i sistemi più popolosi (verosimilmente attorno ai 30 pianeti)
su di una macchina dotata di processore i5 2.5Ghz. Questo è per il momento un benchmark
soddisfacente, non essendo stato richiesto di testare le perfomances su dispositivi mobile.
Lo stile grafico è soddisfacente, anche se piuttosto semplice in quanto la maggior parte de-
gli scenari potrebbe essere reso più realistico con l’aggiunta di effetti grafici, specialmente
nella visione galattica.
6.2 Sviluppi futuri
Rimangono alcune funzionalità utili che si sarebbero potute sviluppare con a disposizione
più tempo:
• rotazione del piano di un sistema planetario rispetto al piano galattico
• sistema di satelliti per ogni pianeta
• rappresentazione della galassia sotto forma di nube e non di inseme di punti
• aggiunta di altre caratteristiche negli oggetti del modello e relativa rappresentazione
grafica
• sistema di illuminazione più avanzato
Generazione procedurale di galassie
40 Conlusione
• interfaccia di navigazione per GalVis
Il prossimo passo, l’integrazione all’interno di Cassiopeiae, richiederà certamente di adat-
tare parte del progetto, ma particolare cura è stata posta nel produrre un codice che si
presti ad essere modificato. Le differenze conosciute tra questo progetto e gli standard di
Cassiopeiae sono state prese in considerazione durante lo sviluppo e le soluzioni realizzate
dovrebbero prestarsi agevolmente a funzionare anche nella loro forma futura, ad esempio
quando si utilizzerà un database invece che un file JSON per persistere i dati della galassia
generata, o quando la piattaforma di esecuzione sarà un device mobile.
Generazione procedurale di galassie