Quando devo usare un passaggio temporale fisso o variabile?


256

Un loop di gioco dovrebbe essere basato su intervalli di tempo fissi o variabili? Uno è sempre superiore o la scelta giusta varia a seconda del gioco?

Passo temporale variabile

Gli aggiornamenti di fisica vengono passati un argomento "tempo trascorso dall'ultimo aggiornamento" e sono quindi dipendenti da framerate. Questo può significare fare calcoli come position += distancePerSecond * timeElapsed.

Pro : liscio, più facile da codificare
Contro : non deterministico, imprevedibile a passi molto piccoli o grandi

esempio deWiTTERS :

while( game_is_running ) {
    prev_frame_tick = curr_frame_tick;
    curr_frame_tick = GetTickCount();
    update( curr_frame_tick - prev_frame_tick );
    render();
}

Passo temporale fisso

Gli aggiornamenti potrebbero anche non accettare un "tempo trascorso", poiché presumono che ogni aggiornamento sia per un periodo di tempo fisso. I calcoli possono essere eseguiti come position += distancePerUpdate. L'esempio include un'interpolazione durante il rendering.

Pro : prevedibile, deterministico (più facile da sincronizzare in rete?), Codice di calcolo più chiaro
Contro : non sincronizzato per monitorare la v-sync (causa grafica nervosa a meno che non si interpoli), frame rate massimo limitato (a meno che non si interpoli), difficile lavorare all'interno di framework che assumere fasi temporali variabili (come Pyglet o Flixel )

esempio deWiTTERS :

while( game_is_running ) {
    while( GetTickCount() > next_game_tick ) {
        update();
        next_game_tick += SKIP_TICKS;
    }
    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                    / float( SKIP_TICKS );
    render( interpolation );
}

Alcune risorse


6
Usa timestep variabili per il tuo gioco e passi fissi per la fisica
Daniel Little,

7
Non direi che il passo temporale variabile è più facile da programmare esattamente perché con il passo temporale fisso "non devi confondere tutti i calcoli con la variabile timeElapsed ovunque". Non che sia così difficile, ma non aggiungerei "più facile da programmare" come professionista.
pek,

È vero, penso che mi stavo riferendo a come non avresti bisogno di interpolare passi di tempo variabili.
Nick Sonneveld,

@pek sono d'accordo con te. Il passo temporale variabile ha un ciclo di gioco codificato più semplice, ma hai molto altro da programmare nelle tue entità che si occupano di quella variabilità al fine di "stimolarlo". Il passaggio temporale fisso ha un ciclo di gioco più complicato da codificare (perché devi compensare accuratamente le variazioni di approssimazione temporale e ricalcolare quale ritardo aggiuntivo aggiungere o quanti aggiornamenti saltare per mantenerlo fisso) ma ha una codifica più semplice per le entità che lo faranno avere sempre a che fare con lo stesso intervallo di tempo. Nel complesso nessuna delle approvazioni è chiaramente più semplice dell'altra.
Drago di Shivan,

Puoi controllare questi visuall da questo strumento: s3.amazonaws.com/picobots/assets/unity/jerky-motion/… anche se non ti dà un'idea di come apparirebbero quando il frame rate è variabile
Buddy

Risposte:


134

Esistono due problemi relativi alla domanda.

  • Il rateo della fisica dovrebbe essere legato al frame rate?
  • La fisica dovrebbe essere intensificata con delta costanti?

In Glen Fielder's Fix your time step dice "Free the Physics". Ciò significa che la frequenza di aggiornamento della fisica non deve essere legata alla frequenza dei fotogrammi.

Ad esempio, se il framerate del display è 50 fps e la simulazione è progettata per funzionare a 100 fps, è necessario eseguire due passaggi di fisica per ogni aggiornamento del display per mantenere la fisica sincronizzata.

Nelle raccomandazioni di Erin Catto per Box2D sostiene anche questo.

Quindi non legare il passo temporale alla frequenza dei fotogrammi (a meno che tu non debba farlo davvero).

La frequenza dei passi della fisica dovrebbe essere legata alla frequenza dei fotogrammi? No.


I pensieri di Erin su step fisso vs stepping variabile:

Box2D utilizza un algoritmo computazionale chiamato integratore. Gli integratori simulano le equazioni della fisica in momenti discreti. ... Inoltre non ci piace il passaggio del tempo a cambiare molto. Una fase temporale variabile produce risultati variabili, il che rende difficile il debug.

I pensieri di Glen su stepping fisso vs variabile:

Correggi il tuo timestep o esplodi

... Se hai una serie di vincoli a molla molto rigidi per gli ammortizzatori in una simulazione di auto, allora piccoli cambiamenti in dt possono effettivamente far esplodere la simulazione. ...

La fisica dovrebbe essere intensificata con delta costanti? Sì.


Il modo per far avanzare la fisica con delta costanti e non legare ancora la frequenza di aggiornamento della fisica alla frequenza dei fotogrammi è utilizzare un accumulatore di tempo. Nel mio gioco faccio un ulteriore passo avanti. Applico una funzione di livellamento al tempo in arrivo. In questo modo i picchi di FPS di grandi dimensioni non fanno saltare troppo la fisica, ma vengono simulati più rapidamente per un fotogramma o due.

Dici che con un tasso fisso, la fisica non si sincronizzerebbe con il display. Ciò è vero se la frequenza fisica target è vicina alla frequenza fotogrammi target. È peggio che la frequenza dei fotogrammi è maggiore della frequenza fisica. In generale, è meglio scegliere una frequenza di aggiornamento della fisica pari al doppio dell'FPS target, se è possibile.

Se non puoi permetterti una grande frequenza di aggiornamento della fisica, considera di interpolare le posizioni della grafica tra i fotogrammi per far sì che la grafica disegnata si muova più agevolmente di quanto non si muova effettivamente la fisica.


1
Ho giocato a The Floor is Jelly prima e dopo aver aggiornato la mia macchina ed è stato sciocco: non era la stessa cosa perché la fisica era effettivamente invocata dal loop di gioco (e quindi legata al frame rate) e non da un timer. La mia vecchia macchina era pessima, quindi cambiava costantemente tra rallentatore e movimento troppo veloce e aveva un grande impatto sul gameplay. Ora è solo un movimento molto veloce. Comunque quel gioco è un ottimo esempio di quanto possa essere problematico questo problema (comunque un gioco carino).
MasterMastic,

55

Penso che ci siano davvero 3 opzioni, ma le stai elencando come solo 2:

opzione 1

Fare niente. Tentare di eseguire l'aggiornamento e il rendering a un determinato intervallo, ad esempio 60 volte al secondo. Se rimane indietro, lascialo e non preoccuparti. I giochi rallenteranno a scatti al rallentatore se la CPU non riesce a tenere il passo con il gioco. Questa opzione non funziona affatto per i giochi multiutente in tempo reale, ma va bene per i giochi a giocatore singolo ed è stata utilizzata con successo in molti giochi.

opzione 2

Utilizzare il tempo delta tra ogni aggiornamento per variare il movimento degli oggetti. Ottimo in teoria, soprattutto se nulla nel tuo gioco accelera o decelera, ma si muove solo a velocità costante. In pratica, molti sviluppatori lo implementano male e ciò può portare a un rilevamento e una fisica delle collisioni incoerenti. Sembra che alcuni sviluppatori pensino che questo metodo sia più semplice di quello che è. Se si desidera utilizzare questa opzione è necessario intensificare notevolmente il gioco e mettere in evidenza alcuni matematici e algoritmi di grande portata, ad esempio utilizzando un integratore di fisica Verlet (anziché l'Euler standard che la maggior parte delle persone usa) e usando i raggi per il rilevamento delle collisioni piuttosto che semplici controlli a distanza di Pitagora. Ho fatto una domanda al riguardo su Stack Overflow qualche tempo fa e ho ottenuto delle ottime risposte:

https://stackoverflow.com/questions/153507/calculate-the-position-of-an-accelerating-body-after-a-certain-time

Opzione 3

Usa l'approccio "correggi il tuo passo temporale" di Gaffer. Aggiorna il gioco a passi fissi come nell'opzione 1, ma fallo più volte per fotogramma reso - in base a quanto tempo è trascorso - in modo che la logica di gioco tenga il passo con il tempo reale, pur rimanendo a passi discreti. In questo modo, è facile implementare la logica di gioco come gli integratori Euler e il semplice rilevamento delle collisioni. Hai anche la possibilità di interpolare le animazioni grafiche basate sul delta time, ma questo è solo per effetti visivi e nulla che influisca sulla tua logica di gioco principale. Potresti potenzialmente metterti nei guai se i tuoi aggiornamenti sono molto intensi: se gli aggiornamenti restano indietro, avrai sempre più bisogno di loro per tenere il passo, rendendo il tuo gioco ancora meno reattivo.

Personalmente, mi piace l'opzione 1 quando posso cavarmela e l'opzione 3 quando devo sincronizzarmi in tempo reale. Rispetto che l'opzione 2 può essere una buona opzione quando sai cosa stai facendo, ma conosco i miei limiti abbastanza bene da starne alla larga.


per quanto riguarda l'opzione 2: Non sono sicuro che un raycast possa mai essere più veloce dei controlli a distanza di Pitagora, tranne se si è molto bruti nell'applicazione di Pitagora, ma un raycast sarà anche molto costoso se non si aggiunge una fase.
Kaj,

4
Se usi Verlet con intervalli di tempo ineguali, stai gettando il bambino con l'acqua del bagno. Il motivo per cui Verlet è tanto stabile quanto è perché gli errori si annullano nelle fasi temporali successive. Se i passi del tempo non sono uguali, ciò non accade e si ritorna nell'esplosione della terra della fisica.
drxzcl,

Opzione 3: sembra la descrizione di Joel Martinez dell'approccio XNA.
piedi il

1
Questa è davvero una buona risposta Tutte e tre le opzioni hanno il loro posto ed è importante capire quando sono appropriate.
Adam Naylor,

Tutti i MMO su cui ho lavorato (EQ, Landmark / EQNext [cry], PS2 [brevemente] ed ESO), abbiamo sempre usato un frame time variabile. Non sono mai stato parte di quella particolare decisione, mi sono presentato dopo il fatto e ho fatto uso di ciò che gli altri hanno deciso.
Mark Storer,

25

Mi piace molto il modo in cui XNA Framework implementa la fase temporale fissa. Se un determinato richiamo richiede un po 'troppo tempo, chiamerà ripetutamente l'aggiornamento fino a quando non "raggiunge". Shawn Hargreaves lo descrive qui:
http://blogs.msdn.com/b/shawnhar/archive/2007/11/23/game-timing-in-xna-game-studio-2-0.aspx

In 2.0, il comportamento Disegna è cambiato:

  • Chiama Aggiorna tutte le volte che è necessario per aggiornarti sull'ora corrente
  • Chiama Disegna una volta
  • Attendere fino al momento del prossimo aggiornamento

Il più grande professionista secondo me è quello che hai menzionato, che rende tutti i tuoi calcoli del codice di gioco molto più semplici perché non devi includere quella variabile temporale dappertutto.

nota: xna supporta anche il timestep variabile, è solo un'impostazione.


Questo è il modo più comune di fare un loop di gioco. Tuttavia, non è eccezionale per la durata della batteria quando si lavora con dispositivi mobili.
knight666,

1
@ knight666; stai suggerendo che utilizzando un timestep più lungo, la quantità ridotta di iterazioni farà risparmiare la durata della batteria?
falstro,

Si tratta ancora di un aggiornamento variabile: il delta di aggiornamento cambia in base al tempo impiegato dal rendering per il frame anziché a un valore fisso (ovvero 1/30 di secondo).
Dennis Munsie,

1
@Dennis: a quanto ho capito, la funzione di aggiornamento viene chiamata con un delta fisso ...
RCIX,

3
@ knight666 Uh - come lo pensi? Se hai vsync attivo e non balbetti - questi metodi dovrebbero essere identici! E se hai vsync spento, ti aggiorni più spesso del necessario e probabilmente sprechi la CPU (e quindi la batteria) non lasciandola inattiva!
Andrew Russell,

12

C'è un'altra opzione: disaccoppiare l'aggiornamento del gioco e l'aggiornamento della fisica. Cercare di adattare il motore fisico al timestep del gioco porta a problemi se si corregge il timestep (il problema di sfuggire al controllo perché l'integrazione ha bisogno di più timestep che richiedono più tempo che richiede più timestep), o renderlo variabile e ottenere una fisica traballante.

La soluzione che vedo molto è far funzionare la fisica su un timestep fisso, in un thread diverso (su un core diverso). Il gioco si interpola o estrapola dati i due frame validi più recenti che può afferrare. L'interpolazione aggiunge un po 'di ritardo, l'estrapolazione aggiunge qualche incertezza, ma la tua fisica sarà stabile e non farà perdere il controllo del tuo tempo.

Questo non è banale da implementare, ma potrebbe dimostrarsi una prova futura.


8

Personalmente, utilizzo una variazione di variabile time-step (che è una specie di ibrido di fisso e variabile credo). Sottolineo che ho testato questo sistema di cronometraggio in diversi modi e mi trovo a usarlo per molti progetti. Lo consiglio a tutto? Probabilmente no.

I miei loop di gioco calcolano la quantità di frame da aggiornare (chiamiamola F), quindi eseguo gli aggiornamenti logici F discreti. Ogni aggiornamento di logica assume un'unità di tempo costante (che è spesso 1/100 di secondo nei miei giochi). Ogni aggiornamento viene eseguito in sequenza fino a quando non vengono eseguiti tutti gli aggiornamenti logici F discreti.

Perché aggiornamenti discreti nei passaggi logici? Bene, se provi ad usare passi continui e improvvisamente hai problemi fisici perché le velocità calcolate e le distanze da percorrere vengono moltiplicate per un valore enorme di F.

Una cattiva implementazione di questo farebbe semplicemente F = ora corrente - aggiornamenti dell'ultimo frame time. Ma se i calcoli sono troppo indietro (a volte a causa di circostanze al di fuori del tuo controllo come un altro processo che ruba il tempo della CPU), vedrai rapidamente terribili salti. Rapidamente, quell'FPS stabile che hai cercato di mantenere diventa SPF.

Nel mio gioco, consento il rallentamento "liscio" (una sorta di) per limitare la quantità di recupero della logica che dovrebbe essere possibile tra due pareggi. Lo faccio bloccando: F = min (F, MAX_FRAME_DELTA) che di solito ha MAX_FRAME_DELTA = 2/100 * sa 3/100 * s. Quindi, invece di saltare i frame quando è troppo indietro rispetto alla logica di gioco, scarta qualsiasi perdita di frame (che rallenta le cose), recupera alcuni frame, disegna e riprova.

In questo modo, mi assicuro anche che i controlli del lettore siano sempre più sincronizzati con ciò che viene effettivamente mostrato sullo schermo.

Lo pseudocodice del prodotto finale è qualcosa del genere (delta è F menzionato in precedenza):

// Assume timers have 1/100 s resolution
const MAX_FRAME_DELTA = 2
// Calculate frame gap.
var delta = current time - last frame time
// Clamp.
delta = min(delta, MAX_FRAME_RATE)
// Update in discrete steps
for(i = 0; i < delta; i++)
{
    update single step()
}
// Caught up again, draw.
render()

Questo tipo di aggiornamento non è adatto a tutto, ma per i giochi in stile arcade, preferirei molto vedere il gioco rallentare perché ci sono molte cose in corso che perdere i frame e perdere il controllo del giocatore. Preferisco anche questo ad altri approcci a tempo variabile che finiscono per avere difetti irreversibili causati dalla perdita di frame.


Concordo pienamente con quest'ultimo punto; praticamente in tutti i giochi, l'input dovrebbe 'rallentare' quando il framerate diminuisce. Anche se questo non è possibile in alcuni giochi (ad es. Multiplayer), sarebbe comunque meglio se fosse possibile. : P È semplicemente meglio che avere un frame lungo e poi far saltare il mondo di gioco allo stato "corretto".
Ipsquiggle,

Senza hardware fisso come una macchina arcade, avere giochi arcade rallenta la simulazione quando l'hardware non riesce a tenere il passo rende il gioco su una macchina più lenta barare.

Joe importa solo se ci preoccupiamo di "barare". La maggior parte dei giochi moderni non riguarda la competizione tra giocatori, ma solo un'esperienza divertente.
Iain,

1
Iain, stiamo parlando in particolare di giochi in stile arcade qui, che sono tradizionalmente in classifica con punteggio elevato / classifica. Gioco un sacco di shmup e so che se avessi trovato qualcuno che stava pubblicando punteggi con rallentamento artificiale nelle classifiche, avrei voluto che i loro punteggi fossero cancellati.

Non tentando di sminuire la tua risposta, ma interpreterei questo come un passaggio fisso in cui il rendering non è direttamente collegato alla frequenza di aggiornamento della fisica, tranne per il fatto che raggiungere la fisica ha la priorità sul rendering. Ha sicuramente buone qualità.
AaronLS

6

Questa soluzione non si applica a tutto, ma esiste un altro livello di timestep variabile - timestep variabile per ogni oggetto nel mondo.

Sembra complicato, e può esserlo, ma pensalo come un modello del tuo gioco come una simulazione di eventi discreti. Ogni movimento del giocatore può essere rappresentato come un evento che inizia quando inizia il movimento e termina quando termina il movimento. Se esiste un'interazione che richiede la divisione dell'evento (una collisione per esempio), l'evento viene annullato e un altro evento viene inserito nella coda degli eventi (che è probabilmente una coda prioritaria ordinata per ora di fine dell'evento).

Il rendering è totalmente staccato dalla coda degli eventi. Il motore di visualizzazione interpola i punti tra i tempi di inizio / fine dell'evento, se necessario, e può essere accurato o sciatto in questa stima secondo necessità.

Per vedere un'implementazione complessa di questo modello, vedere il simulatore di spazio EXOFLIGHT . Utilizza un modello di esecuzione diverso dalla maggior parte dei simulatori di volo - un modello basato su eventi, piuttosto che il tradizionale modello a fasce orarie fisso. Il ciclo principale di base di questo tipo di simulazione è simile al seguente, in pseudo-codice:

while (game_is_running)
{
   world.draw_to_screen(); 
   world.get_player_input(); 
   world.consume_events_until(current_time + time_step); 
   current_time += time_step; 
}

Il motivo principale per l'utilizzo di uno in un simulatore spaziale è la necessità di fornire un'accelerazione temporale arbitraria senza perdita di precisione. Il completamento di alcune missioni in EXOFLIGHT può richiedere anni di gioco e anche un'opzione di accelerazione 32x sarebbe insufficiente. Avresti bisogno di oltre 1.000.000 di accelerazione per una sim utilizzabile, cosa difficile da fare in un modello time-slice. Con il modello basato sugli eventi, otteniamo frequenze temporali arbitrarie, da 1 s = 7 ms a 1 s = 1 anno.

La modifica della frequenza temporale non modifica il comportamento della sim, che è una caratteristica fondamentale. Se la potenza della CPU non è sufficiente per eseguire il simulatore alla velocità desiderata, gli eventi si accumuleranno e potremmo limitare l'aggiornamento dell'interfaccia utente fino a quando la coda degli eventi non viene cancellata. Allo stesso modo, possiamo far avanzare rapidamente la sim quanto vogliamo ed essere sicuri di non sprecare CPU né sacrificare la precisione.

Quindi riassumendo: possiamo modellare un veicolo in un'orbita lunga e piacevole (usando l'integrazione di Runge-Kutta) e un altro veicolo che rimbalza simultaneamente lungo il terreno: entrambi i veicoli saranno simulati con la precisione appropriata poiché non abbiamo un timestep globale.

Contro: Complessità e mancanza di motori fisici standard che supportano questo modello :)


5

La fase temporale fissa è utile quando si tiene conto dell'accuratezza in virgola mobile e per rendere coerenti gli aggiornamenti.

È un semplice pezzo di codice, quindi sarebbe utile provarlo e vedere se funziona per il tuo gioco.

now = currentTime
frameTime = now - lastTimeStamp // time since last render()
while (frameTime > updateTime)
    update(timestep)
    frameTime -= updateTime     // update enough times to catch up
                                // possibly leaving a small remainder
                                // of time for the next frame

lastTimeStamp = now - frameTime // set last timestamp to now but
                                // subtract the remaining frame time
                                // to make sure the game will still
                                // catch up on those remaining few millseconds
render()

Il problema principale con l'utilizzo di una fase temporale fissa è che i giocatori con un computer veloce non saranno in grado di sfruttare la velocità. Il rendering a 100 fps quando il gioco viene aggiornato solo a 30 fps è lo stesso del rendering a 30 fps.

Detto questo, potrebbe essere possibile utilizzare più di una fase temporale fissa. 60 fps potrebbero essere utilizzati per aggiornare oggetti banali (come l'interfaccia utente o sprite animati) e 30 fps per aggiornare sistemi non banali (come la fisica e) e persino i timer più lenti da fare dietro la gestione delle scene come eliminare oggetti inutilizzati, risorse ecc.


2
Se il gioco è stato creato con cura, il metodo di rendering può eseguire l'interpolazione per fare in modo che gli aggiornamenti a 30 fps non siano gli stessi del rendering a 30 fps.
Ricket,

3

Oltre a ciò che hai già affermato, potrebbe dipendere dall'impressione che desideri che il tuo gioco abbia. A meno che tu non possa garantire che avrai sempre un frame rate costante, allora probabilmente avrai un rallentamento da qualche parte e le fasi temporali fisse e variabili appariranno molto diverse. Risolto avrà l'effetto del tuo gioco che va al rallentatore per un po ', che a volte può essere l'effetto desiderato (guarda uno sparatutto in stile vecchia scuola come Ikaruga in cui enormi esplosioni causano rallentamento dopo aver battuto un boss). I timestep variabili manterranno le cose alla velocità corretta in termini di tempo, ma potresti vedere improvvisi cambiamenti di posizione ecc. Che possono rendere difficile per il giocatore eseguire le azioni con precisione.

Non riesco davvero a vedere che un passaggio a tempo fisso renderà le cose più facili su una rete, sarebbero tutti leggermente fuori sincrono per cominciare e rallentamento su una macchina, ma non un altro spingerebbe le cose più fuori sincrono.

Mi sono sempre orientato verso l'approccio variabile personalmente, ma quegli articoli hanno alcune cose interessanti a cui pensare. Ho comunque trovato passaggi fissi abbastanza comuni, soprattutto su console in cui la gente pensa che il framerate sia costante a 60 fps rispetto alle altissime velocità ottenibili su PC.


5
Dovresti assolutamente leggere il link Gaffer sui giochi nel post originale. Non penso che questa sia una cattiva risposta di per sé, quindi non la voterò in giù, ma non sono d'accordo con nessuno dei tuoi argomenti .
falstro,

Non penso che il rallentamento in un gioco come risultato di un timestep fisso possa mai essere intenzionale, perché è a causa della mancanza di controllo. La mancanza di controllo è per definizione arrendersi al caso e quindi non può essere intenzionale. Può capitare di essere quello che avevi in ​​mente, ma è quanto mi piacerebbe continuare. Per quanto riguarda il timestep fisso in rete, c'è un netto vantaggio lì, poiché mantenere i motori fisici su due macchine diverse in sincronia senza lo stesso timestep è abbastanza impossibile. Poiché l'unica opzione da sincronizzare sarebbe quella di inviare tutte le trasformazioni di entità, sarebbe troppo pesante la larghezza di banda.
Kaj,

0

Usa l'approccio "correggi il tuo passo temporale" di Gaffer. Aggiorna il gioco a passi fissi come nell'opzione 1, ma fallo più volte per fotogramma reso - in base a quanto tempo è trascorso - in modo che la logica di gioco tenga il passo con il tempo reale, pur rimanendo a passi discreti. In questo modo, è facile implementare la logica di gioco come gli integratori Euler e il semplice rilevamento delle collisioni. Hai anche la possibilità di interpolare le animazioni grafiche basate sul delta time, ma questo è solo per effetti visivi e nulla che influisca sulla tua logica di gioco principale. Potresti potenzialmente metterti nei guai se i tuoi aggiornamenti sono molto intensi: se gli aggiornamenti restano indietro, avrai sempre più bisogno di loro per tenere il passo, rendendo il tuo gioco ancora meno reattivo.

Personalmente, mi piace l'opzione 1 quando riesco a cavarmela e l'opzione 3 quando devo sincronizzarmi in tempo reale. Rispetto che l'opzione 2 può essere una buona opzione quando sai cosa stai facendo, ma conosco i miei limiti abbastanza bene da starne lontano


Se hai intenzione di rubare risposte almeno accreditare la persona!
PrimRock,

0

Ho scoperto che i timestep fissi sincronizzati a 60 fps danno un'animazione fluida e speculare. Ciò è particolarmente importante per le applicazioni VR. Qualcos'altro è fisicamente nauseabondo.

I timestep variabili non sono adatti per la realtà virtuale. Dai un'occhiata ad alcuni esempi di Unity VR che utilizzano timestep variabili. È spiacevole

La regola è se il tuo gioco 3D è fluido in modalità VR, sarà eccellente in modalità non VR.

Confronta questi due (app Cardboard VR)

(Timestep variabili)

(Timestep fissi)

Il gioco deve essere multithread al fine di ottenere un time / framerate coerente. La fisica, l'interfaccia utente e il rendering devono essere separati in thread dedicati. PITA è orribile per sincronizzarli, ma i risultati sono il rendering uniforme che si desidera (specialmente per la realtà virtuale).

I giochi per cellulari sono esp. impegnativo perché le CPU e le GPU integrate hanno prestazioni limitate. Usa GLSL (slang) con parsimonia per scaricare quanto più lavoro possibile dalla CPU. Tenere presente che il passaggio dei parametri alla GPU consuma risorse del bus.

Mantieni sempre il tuo framerate visualizzato durante lo sviluppo. Il vero gioco è quello di mantenerlo fisso a 60fps. Questa è la frequenza di sincronizzazione nativa per la maggior parte degli schermi e anche per la maggior parte dei bulbi oculari.

Il framework che stai utilizzando dovrebbe essere in grado di avvisarti di una richiesta di sincronizzazione o utilizzare un timer. Non inserire un ritardo di attesa / attesa per ottenere ciò - anche si notano lievi variazioni.


0

I passi variabili del tempo sono per le procedure che dovrebbero essere eseguite il più spesso possibile: cicli di rendering, gestione degli eventi, elementi della rete ecc.

I passi temporali fissi servono per quando hai bisogno di qualcosa di prevedibile e stabile. Ciò include, ma non è limitato al rilevamento della fisica e delle collisioni.

In termini pratici, la rilevazione della fisica e delle collisioni dovrebbe essere disaccoppiata da qualsiasi altra cosa, secondo il proprio passo temporale. Il motivo per eseguire procedure come queste in un piccolo intervallo di tempo fisso è mantenerle accurate. Le magnitudo dell'impulso dipendono fortemente dal tempo e se l'intervallo diventa troppo grande, la simulazione diventa instabile e cose folli accadono come una palla che rimbalza attraverso il terreno o rimbalza fuori dal mondo di gioco, nessuna delle quali è desiderabile.

Tutto il resto può essere eseguito su un intervallo di tempo variabile (anche se a livello professionale, è spesso una buona idea consentire il blocco del rendering su un intervallo di tempo fisso). Affinché un motore di gioco sia reattivo, cose come i messaggi di rete e l'input dell'utente dovrebbero essere gestiti il ​​più presto possibile, il che significa che l'intervallo tra il polling dovrebbe idealmente essere il più breve possibile. Questo generalmente significa variabile.

Tutto il resto può essere gestito in modo asincrono, rendendo il tempismo un punto controverso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.