Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Coordinate di mondi ampi

Nota

Le coordinate di mondi ampi sono utili principalmente nei progetti 3D; raramente sono necessarie nei progetti 2D. Inoltre, a differenza del rendering 3D, il rendering 2D attualmente non beneficia di una maggiore precisione quando le coordinate di mondi ampi sono abilitate.

Perché utilizzare le coordinate di mondi ampi?

In Godot, sia la simulazione fisica sia il rendering si basano su numeri a virgola mobile. Tuttavia, in informatica, i numeri a virgola mobile hanno precisione e intervallo limitati. Questo può essere un problema per i giochi con mondi enormi, come i giochi di simulazione spaziale o planetaria.

La precisione è al massimo quando il valore è vicino a 0.0. La precisione diminuisce gradualmente man mano che il valore si allontana da 0.0. Ciò si verifica ogni volta che l'esponente del numero in virgola mobile aumenta, ovvero quando il numero in virgola mobile supera una potenza di 2 (2, 4, 8, 16, ...). Ogni volta che ciò accade, il passo minimo del numero aumenta, risultando in una perdita di precisione.

In pratica, ciò significa che man mano che il giocatore si allontana dall'origine del mondo (Vector2(0, 0) nei giochi 2D o Vector3(0, 0, 0) nei giochi 3D), la precisione diminuirà.

Tale perdita di precisione si manifesta sotto forma di oggetti che sembrano "vibrare" quando sono lontani dall'origine del mondo, poiché la posizione del modello si arrotonderà al valore più vicino rappresentabile in un numero in virgola mobile. Ciò può anche causare problemi fisici che avvengono solo quando il giocatore è lontano dall'origine del mondo.

L'intervallo determina i valori minimo e massimo che si possono memorizzare nel numero. Se il giocatore cerca di superare questo intervallo, non ci riuscirà e basta. Tuttavia, in pratica, la precisione in virgola mobile diventa quasi sempre un problema prima dell'intervallo.

L'intervallo e la precisione (passo minimo tra due intervalli di esponente) sono determinati dal tipo di numero in virgola mobile. L'intervallo teorico consente di memorizzare valori estremamente elevati in float a precisione singola, ma con una precisione molto bassa. In pratica, un tipo in virgola mobile che non può rappresentare tutti i valori interi non è molto utile. A valori estremi, la precisione diventa così bassa che il numero non riesce nemmeno a distinguere due valori interi separati l'uno dall'altro.

Questo è l'intervallo in cui è possibile rappresentare i singoli valori interi in un numero in virgola mobile:

  • Intervallo di float a precisione singola (rappresenta tutti i numeri interi): tra -16,777,216 e 16,777,216

  • Intervallo di float a precisione doppia (rappresenta tutti i numeri interi): tra -9 quadrilioni e 9 quadrilioni

Intervallo

Passo singolo

Passo doppio

Commento

[1; 2]

~0.0000001

~1e-15

La precisione aumenta avvicinandosi a 0.0 (questa tabella è abbreviata).

[2; 4]

~0.0000002

~1e-15

[4; 8]

~0.0000005

~1e-15

[8; 16]

~0.000001

~1e-14

[16; 32]

~0.000002

~1e-14

[32; 64]

~0.000004

~1e-14

[64; 128]

~0.000008

~1e-13

[128; 256]

~0.000015

~1e-13

[256; 512]

~0.00003

~1e-13

[512; 1024]

~0.00006

~1e-12

[1024; 2048]

~0.0001

~1e-12

[2048; 4096]

~0.0002

~1e-12

Intervallo massimo a precisione singola consigliato per un gioco 3D in prima persona senza problemi di rendering o di fisica.

[4096; 8192]

~0.0005

~1e-12

Intervallo massimo a precisione singola consigliato per un gioco 3D in terza persona senza problemi di rendering o di fisica.

[8192; 16384]

~0.001

~1e-12

[16384; 32768]

~0.0019

~1e-11

Intervallo massimo a precisione singola consigliato per un gioco 3D dall'alto senza problemi di rendering o di fisica.

[32768; 65536]

~0.0039

~1e-11

Intervallo massimo a precisione singola consigliato per un qualsiasi gioco 3D. Oltre questo punto, solitamente è richiesta la doppia precisione (grandi coordinate mondiali).

[65536; 131072]

~0.0078

~1e-11

[131072; 262144]

~0.0156

~1e-10

> 262144

> ~0.0313

~1e-10 (0.0000000001)

Oltre questo valore, la precisione doppia rimane molto più precisa della precisione singola.

Utilizzando float a precisione singola, è possibile oltrepassare gli intervalli suggeriti, ma si verificheranno artefatti più evidenti e saranno più comuni i problemi di fisica (ad esempio, il giocatore non è capace di camminare dritto in certe direzioni).

Vedi anche

Consultare l'articolo Demystifying Floating Point Precision per ulteriori informazioni.

Come funzionano le grandi coordinate mondiali

Le grandi coordinate mondiali (note anche come fisica a doppia precisione) aumentano il livello di precisione di tutti i calcoli in virgola mobile all'interno del motore.

Per impostazione predefinita, float è a 64 bit in GDScript, ma Vector2, Vector3 e Vector4 sono a 32 bit. Ciò significa che la precisione dei tipi vettoriali è molto più limitata. Per risolvere ciò, possiamo aumentare il numero di bit utilizzati per rappresentare un numero in virgola mobile in un tipo Vector. Ciò si traduce in un aumento esponenziale della precisione, il che significa che il valore finale non è solo due volte più preciso, ma potenzialmente migliaia di volte più preciso a valori elevati. Anche il valore massimo rappresentabile aumenta notevolmente passando da un float a precisione singola a un float a precisione doppia.

Per evitare problemi di arrotondamento dei modelli quando sono molto lontani dall'origine del mondo, il motore di rendering 3D di Godot aumenterà la precisione delle operazioni di rendering quando sono abilitate le grandi coordinate mondiali. Gli shader non utilizzano float a doppia precisione per motivi di prestazioni, ma è utilizzata una soluzione alternativa per emulare la doppia precisione per il rendering usando float a precisione singola.

Nota

Abilitare le grandi coordinate mondiali comporta una penalizzazione sulle prestazioni e sull'utilizzo della memoria, soprattutto sulle CPU a 32 bit. Abilitare le grandi coordinate mondiali solo se effettivamente necessarie.

Questa funzionalità è pensata per piattaforme desktop di fascia media/alta. Le grandi coordinate mondiali potrebbero non funzionare bene sui dispositivi mobili di fascia bassa, a meno che non si adottino misure per ridurre l'utilizzo della CPU con altri mezzi (ad esempio, diminuendo il numero di tick di fisica al secondo).

Sulle piattaforme di fascia bassa, è possibile utilizzare un approccio di spostamento dell'origine per permettere di avere mondi grandi, senza ricorrere a fisica e rendering a doppia precisione. Lo spostamento dell'origine funziona con i float a precisione singola, ma introduce maggiore complessità nella logica di gioco, soprattutto nei giochi multigiocatore. Pertanto, lo spostamento dell'origine non è approfondito in questa pagina.

A chi servono grandi coordinate mondiali?

Le grandi coordinate mondiali sono tipicamente richieste per i giochi di simulazione 3D su scala spaziale o planetaria. Questo si estende anche ai giochi che richiedono di supportare velocità di movimento molto elevate, ma anche di movimenti molto lenti e precisi a volte.

D'altro parte, è importante utilizzare grandi coordinate mondiali solo quando servono effettivamente (per motivi di prestazioni). Le grandi coordinate mondiali di solito non servono per:

  • Giochi 2D, in quanto i problemi di precisione sono solitamente meno evidenti.

  • Giochi con mondi di piccole o medie dimensioni.

  • Giochi con mondi di grandi dimensioni, ma suddivisi in diversi livelli con sequenze di caricamento intermedie. È possibile centrare ogni porzione di un livello attorno all'origine del mondo per evitare problemi di precisione senza penalizzare le prestazioni.

  • Giochi open world con un'area giocabile a piedi non superiore a 8192×8192 metri (centrata attorno all'origine del mondo). Come mostrato nella tabella precedente, il livello di precisione rimane accettabile entro tale intervallo, anche per un gioco in prima persona.

In caso di dubbio, probabilmente non c'è bisogno di utilizzare grandi coordinate mondiali nel progetto. Per riferimento, la maggiorità dei moderni titoli open world AAA non utilizza un sistema di grandi coordinate mondiali e si affida ancora a float a precisione singola, sia per il rendering sia per la fisica.

Abilitare grandi coordinate mondiali

Questo processo richiede di ricompilare l'editor e tutti i binari dei modelli di esportazione che si intende utilizzare. Se si intende esportare il progetto solo in modalità di rilascio, è possibile saltare la compilazione dei modelli di esportazione di debug. In ogni caso, sarà necessario compilare una build dell'editor in modo da poter testare il proprio mondo ad alta precisione senza dover esportare il progetto ogni volta.

Consultare la sezione Compiling per le istruzioni di compilazione per ciascuna piattaforma di destinazione. Sarà necessario aggiungere l'opzione SCons precision=double durante la compilazione dell'editor e dei modelli di esportazione.

I file binari risultanti saranno denominati con il suffisso .double per distinguerli dai file binari a precisione singola (che non hanno alcun suffisso di precisione). È quindi possibile specificare i file binari come modelli di esportazione personalizzati nelle preimpostazioni di esportazione del progetto, nella finestra di dialogo Esporta.

Compatibilità tra build a singola precisione e a doppia precisione

Quando si salva una risorsa binaria attraverso il singleton ResourceSaver, nel file viene memorizzato un flag speciale se la risorsa è stata salvata mediante una build che usa numeri a doppia precisione. Pertanto, tutte le risorse binarie verranno modificate su disco quando si passa a una build a doppia precisione e vengono sovrascritte.

Sia le build a singola precisione sia le build a doppia precisione supportano l'uso del singleton ResourceLoader sulle risorse che utilizzano questo flag speciale. Ciò significa che le build a singola precisione possono caricare risorse salvate mediante una build a doppia precisione, e viceversa. Le risorse testuali non memorizzano un flag di doppia precisione, poiché non lo richiedono per una lettura corretta.

Incompatibilità note

  • In un gioco multigiocatore in rete, il server e tutti i client dovrebbero utilizzare lo stesso tipo di build per garantire che la precisione rimanga costante tra i client. Utilizzare tipi di build diversi potrebbe funzionare, ma possono verificarsi diversi problemi.

  • L'API di GDExtension cambia in modo incompatibile nelle build a doppia precisione. Ciò significa che le estensioni si devono ricompilare per funzionare con le build a doppia precisione. Dal lato dello sviluppatore dell'estensione, la definizione REAL_T_IS_DOUBLE è abilitata quando si compila una GDExtension con precision=double. È possibile usare real_t come alias per float nelle build a singola precisione e double nelle build a doppia precisione.

Limitazioni

Poiché gli shader di rendering 3D non utilizzano effettivamente float a doppia precisione, esistono alcune limitazioni quando si tratta di precisione del rendering 3D:

  • La mappatura triplanare non usufruisce da una maggiore precisione. I materiali che utilizzano la mappatura triplanare presenteranno un evidente tremolio quando sono lontani dall'origine del mondo.

  • GPUParticles3D nodes with Local Coords disabled will not benefit from increased precision. This can cause visible particle snapping to occur when far away from the world origin. Nodes with Local Coords enabled, as well as CPUParticles3D nodes, will still benefit from increased precision.

  • Shaders using the skip_vertex_transform or world_vertex_coords render modes don't benefit from increased precision.

  • Nelle build a doppia precisione, le coordinate nello spazio mondiale in una funzione fragment() di uno shader non si possono ricostruire dallo spazio di visualizzazione, ad esempio:

    vec3 world = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
    

    Invece, calcolare le coordinate nello spazio mondiale nella funzione vertex() e passarle tramite un varying, ad esempio:

    varying vec3 world;
    void vertex() {
        world = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
    }
    

Il rendering 2D attualmente non usufruisce dalla maggiore precisione quando sono abilitate grandi coordinate mondiali. Ciò può causare un arrotondamento evidente dei modelli quando sono lontani dall'origine del mondo (a partire da pochi milioni di pixel ai livelli tipici di zoom). I calcoli fisici 2D usufruiranno comunque dalla maggiore precisione.