Rendering in Unreal Engine
Presentazione del rendering nei motori di gioco
Il rendering si riferisce al processo di generazione di un'immagine finale (frame) sullo schermo da una raccolta di oggetti in una scena.
Il software utilizzato per renderizzare un frame è chiamato motore di rendering e questi motori sono normalmente classificati come:
Rendering offline: progettato per un rendering di alta qualità che privilegia la qualità rispetto al tempo di elaborazione. Viene utilizzato in genere in applicazioni in cui il tempo di rendering non è importante rispetto alla qualità del frame finale renderizzato.
Rendering in tempo reale: progettato pensando alle prestazioni e al rendering rapido dei frame. I target tipici di frame rate in tempo reale sono 30 (33 ms), 60 (16 ms) e 120 (8 ms) frame per second (FPS), ma i frame rate effettivi possono variare nel tempo a seconda di una serie di fattori. I progetti sviluppati con il rendering in tempo reale devono trovare un equilibrio tra prestazioni e qualità per mantenere frame rate costanti. I motori di rendering in tempo reale vengono in genere utilizzati per i media interattivi, come videogiochi, simulazioni e visualizzazione architettonica.
Unreal Engine è un potente pacchetto di strumenti progettati per il rendering in tempo reale per soddisfare le esigenze di una varietà di piattaforme, dai dispositivi mobili ai potenti computer desktop. Unreal Engine è in grado di eseguire rendering di alta qualità sia in tempo reale che offline. È possibile utilizzarlo per creare qualsiasi cosa, dalle esperienze interattive 2D e 3D su piattaforme mobili, console e desktop, al rendering dei frame finali per produzioni cinematografiche e televisive.
A differenza di altri motori in tempo reale sul mercato, Unreal Engine offre molte funzionalità proprietarie progettate specificamente pensando al tempo reale e alle prestazioni. L'obiettivo è ridurre la complessità nello sviluppo e ottenere risultati più rapidamente mantenendo alta la qualità e le prestazioni.
Funzioni, come il sistema
Presentazione del rendering in Unreal Engine
I motori di gioco eseguono una serie di passaggi, spesso chiamati pipeline di rendering, per eseguire il rendering di un'immagine (o di un frame) sullo schermo. Questa sezione descrive come Unreal Engine esegue questa operazione utilizzando il percorso di rendering differito predefinito e confronta i passaggi con il percorso di rendering posticipato di Unity quando appropriato.
Unity Engine viene fornito con tre pipeline di rendering distinte: Integrato, Universale e Alta definizione. Ogni pipeline è progettata per casi d'uso specifici e in genere viene selezionata prima di iniziare un nuovo progetto.
Unreal Engine è dotato di una pipeline di rendering unificata che ridimensiona le singole funzioni in base alla piattaforma di destinazione, dai dispositivi portatili e mobili all'attuale generazione di console e PC. Ciò significa che è possibile scegliere un percorso di rendering e le funzionalità supportate che meglio si adattano al progetto senza essere vincolati in un singolo percorso.
La pipeline di rendering di Unreal Engine può essere utilizzata con il suo percorso predefinito di rendering differito oppure può essere configurata per l'esecuzione in un percorso di
L'immagine seguente mostra una visualizzazione di alto livello dei passaggi eseguiti da Unreal Engine in ogni frame per eseguire il rendering di un'immagine finale utilizzando il percorso rendering differito:
Il processo scorre da sinistra a destra e i passaggi da 2 a 5 vengono eseguiti in parallelo.
Di seguito, viene spiegato ciascuno di questi passaggi nella pipeline di rendering e cosa serve per eseguire il rendering di ogni frame.
Preparazione e occlusione della scena
Unreal Engine ha tre thread principali: i thread gioco (CPU), disegno e GPU.
Prima di avviare il processo di rendering, il thread di gioco (o CPU) raccoglie le trasformazioni di tutti gli oggetti nella scena. Ciò include l'elaborazione di tutte le animazioni, le simulazioni fisiche e l'intelligenza artificiale (AI) prima di raccogliere la trasformazione finale di ogni oggetto.
Le informazioni sulla trasformazione vengono quindi trasmesse al thread disegno sulla CPU. Il thread disegno esegue il processo di eliminazione, che crea un elenco di oggetti visibili nella visualizzazione corrente della telecamera e rimuove tutti gli altri oggetti non visibili alla telecamera. Non è necessario disegnare questi oggetti e non eseguirne il rendering migliora le prestazioni.
Questo processo esegue i passaggi seguenti (in ordine):
Eliminazione tronco: rimuove gli oggetti che non sono visibili all'interno del tronco (visuale) della telecamera.
Eliminazione occlusione: controlla con precisione lo stato di visibilità di tutti gli oggetti rimanenti nella scena. Questo metodo è costoso e quindi viene eseguito alla fine del processo di occlusione, in cui gli oggetti visibili rimanenti vengono ulteriormente testati per vedere se sono occlusi (nascosti) da altri oggetti.
L'elenco finale degli oggetti visibili viene trasmesso al thread GPU per iniziare il processo di rendering.
Equivalente a Unity
Unity esegue l'eliminazione del tronco e dell'occlusione durante la pipeline di rendering. Inoltre, può eseguire l'eliminazione a distanza con la sua API CullingGroup. Una combinazione di queste tecniche crea l'elenco finale degli oggetti visibili nella scena.
Rendering della geometria
In questo passaggio, Unreal Engine esamina l'elenco degli oggetti visibili nella scena e li prepara per il passaggio successivo in cui converte i dati dei vertici 3D in dati pixel visualizzati sullo schermo.
Shader dei vertici
Uno shader è un bit di codice che viene eseguito direttamente sulla GPU e viene utilizzato per eseguire una serie di calcoli. Sono efficienti e la GPU può eseguire molti calcoli di shader in parallelo.
Il vertex shader esegue i passaggi seguenti:
Converte le posizioni dei vertici locali in posizioni mondo: i dati dei vertici degli oggetti sono memorizzati nello spazio locale, ma una volta che l'oggetto è posizionato nel mondo, le informazioni sui vertici devono essere convertite in coordinate dello spazio mondo.
Gestisce l'ombreggiatura e la colorazione dei vertici: lo shader dei vertici gestisce l'attenuazione dei vertici e tutti i dati di colore dei vertici nell'oggetto stesso.
Può applicare offset aggiuntivi alle posizioni dei vertici: lo shader dei vertici può sfalsare la posizione di qualsiasi vertice sullo schermo per ottenere effetti specifici. Questo viene fatto attraverso il materiale dell'oggetto ed è chiamato offset della posizione mondo.
Passaggio di profondità
Prima di eseguire il rendering dei singoli oggetti, Unreal Engine esegue un passaggio di profondità, o passaggio Z anticipato, per determinare la posizione degli oggetti in relazione l'uno all'altro. In questo modo si evita che Unreal Engine esegua il rendering degli stessi pixel sullo schermo più volte. Questo è chiamato scoperto e può avere un impatto significativo sulle prestazioni. Il motore cerca di evitarlo il più possibile.
Draw call
Dopo il passaggio di profondità, la GPU esegue il rendering di ogni oggetto disegnando contemporaneamente tutti i poligoni che condividono le stesse proprietà, ad esempio mesh e materiali. Nota come drawcall.
Tutti i poligoni di un oggetto a cui è assegnato lo stesso materiale vengono conteggiati come la stessa drawcall. Tuttavia, ogni materiale unico richiede la propria drawcall separata. Ad esempio, ogni oggetto sullo schermo richiede almeno una draw call, ma potrebbe averne di più a seconda del numero di materiali assegnati all'oggetto.
Equivalente a Unity
La pipeline di rendering di Unity esegue passaggi simili in cui esegue un passaggio di profondità e usa drawcall per disegnare gli oggetti nella scena.
Rasterizzazione e buffer della geometria
Il processo di rasterizzazione converte i dati dei vertici 3D in dati pixel 2D visualizzati sullo schermo. Questo processo inizia dopo che il vertex shader ha terminato l'elaborazione di tutti i dati.
Il buffer della geometria (GBuffer) di Unreal Engine include una serie di immagini che archiviano informazioni sulla geometria della scena. Queste immagini includono in genere informazioni sull'illuminazione per il colore di base, la normale mondo, il metallico, la rugosità e lo speculare nella scena. Queste immagini nel GBuffer sono composte per comporre l'immagine finale che si vede sullo schermo.
Il processo di conversione di queste immagini composte avviene per ogni frame di cui viene eseguito il rendering e per ogni draw call in cui i dati dei vertici vengono convertiti in dati pixel e disegna le parti corrette delle immagini nel GBuffer.
Equivalente a Unity
Il percorso di rendering differito di Unity utilizza anche un GBuffer per archiviare informazioni critiche sulla scena. Nel caso di Unity, il GBuffer archivia informazioni simili sulla scena (a cui si fa riferimento con nomi diversi): albedo, speculare, normale e informazioni emissive/di illuminazione degli oggetti.
Rendering delle texture
Unreal Engine esegue il rendering delle texture utilizzando lo streaming delle texture per ottimizzarne il caricamento nella scena. Il sistema di streaming delle texture utilizza le mipmap di texture. Si tratta di una sequenza precalcolata di immagini della stessa texture a diverse risoluzioni. Puoi immaginarle come livelli di dettaglio (LOD) delle texture invece che delle mesh. Il motore crea automaticamente queste mipmap in cui ogni immagine ha la metà della risoluzione di quella precedente.
Unreal Engine trasmette in streaming la mipmap della texture durante il gioco in base alla distanza dalla telecamera. Questa operazione viene eseguita automaticamente per ottimizzare la larghezza di banda e il consumo di memoria, oltre a ridurre il rumore più lontano dalla telecamera.
Le dimensioni delle texutre devono essere una potenza di 2 per ricevere le mipmap. Le dimensioni comuni delle texture includono 3840 x 2160 pixel (4K) e 1920 x 1080 pixel (HD). Tenere presente che le texture non devono avere un rapporto specifico, anche una trama di 1920 x 480 pixel riceverà mipmap.
Equivalente a Unity
Il sistema Mipmap Streaming di Unity utilizza le mipmap di texture per trasmettere le texture nel runtime. Analogamente a Unreal Engine, questo sistema trasmette automaticamente la mipmap di texture appropriata in base alla distanza e all'angolo con la telecamera.
Shader dei pixel e materiali
Una volta che gli oggetti sono stati completamente renderizzati su GBuffer, Unreal Engine inizia a ombreggiare ogni oggetto sullo schermo utilizzando le proprietà del materiale di ogni oggetto con il pixel shader.
Uno shader di pixel esegue una serie di calcoli per modificare il colore di un pixel sullo schermo. I pixel shader vengono eseguiti sulla GPU e sono estremamente efficienti. Guidano il sistema dei materiali di Unreal Engine e vengono utilizzati nel calcolo dell'illuminazione, della nebbia, dei riflessi e degli effetti di post-elaborazione.
Il sistema dei materiali utilizza i modelli di shader HLSL (High-Level Shader Language) insieme all'Editor dei materiali per creare i materiali finali applicati agli oggetti sullo schermo. Questi materiali possono utilizzare parametri, come ad esempio le texture, per definire l'aspetto di ogni oggetto.
Equivalente a Unity
Unity è fornito di diversi shader predefiniti (equivalenti ai materiali in Unreal Engine) oltre al suo grafico shader per creare shader per il progetto. L'Editor materiali di Unreal Engine è l'equivalente dello Shader Graph di Unity.
Riflessi
Dopo aver ombreggiato tutti gli oggetti nella scena, Unreal Engine inizia a eseguire il rendering dei riflessi degli oggetti in base alle proprietà del materiale.
Unreal Engine utilizza quattro sistemi per eseguire il rendering dei riflessi sulla scena. Questi sistemi vengono eseguiti nel seguente ordine:
Riflessi planari: acquisizione dei riflessi da e verso un piano.
Screen Space Reflections (SSR) (Riflessi a schermo): utilizza le informazioni disponibili sullo schermo per disegnare riflessi precisi per gli oggetti in tempo reale.
Riflessi lumen: risolve i riflessi dell'intera gamma di valori di rugosità nella scena. Queste riflessi includono il supporto per lo skylight, i materiali trasparenti, la traslucenza e persino i materiali dell'acqua a strato singolo.
Unreal Engine si fonde tra i tre metodi, dando priorità ai riflessi dello spazio sullo schermo, quindi ricorrendo ai riflessi planari e, infine, ricorrendo alle acquisizioni dei riflessi. Il risultato finale del riflesso è combinato con le immagini di rugosità, speculari e metalliche nel GBuffer.
Se utilizzi l'Illuminazione globale Lumen, sono usati automaticamente i riflessi Lumen. Tuttavia, è possibile anche utilizzare i riflessi Lumen senza Lumen GI, nel qual caso Unreal Engine utilizza l'illuminazione con baking con i riflessi lumen.
Equivalente a Unity
Illuminazione e ombre statiche
Dopo il rendering dei riflessi, Unreal Engine esegue il rendering dell'illuminazione statica e delle ombre per tutti gli oggetti nella scena.
Unreal Engine utilizza il proprio sistema
Questo sistema è molto veloce ma richiede più memoria e deve essere pre-calcolato ogni volta che c'è un cambiamento di scena.
Il sistema Lightmass Global Illumination è una buona opzione per i progetti destinati a dispositivi mobili e a bassa potenza.
Equivalente a Unity
I sistemi Progressive Lightmapper e Enlighten Baked Global Illumination di Unity forniscono una funzionalità simile durante il pre-calcolo dell'illuminazione per la scena.
Illuminazione e ombre dinamiche
Dopo il rendering dell'illuminazione statica, Unreal Engine esegue il rendering dinamico (in tempo reale) dell'illuminazione e delle ombre con Lumen, il suo sistema di illuminazione globale dinamica.
Lumen è un sistema di riflesso e di illuminazione globale completamente dinamica progettato per le console di nuova generazione e i PC di fascia alta. Il sistema utilizza diversi metodi di ray tracing per risolvere l'illuminazione globale dei riflessi su larga scala.
Lumen fornisce rimbalzi diffusi infiniti e funziona perfettamente con Nanite Virtualized Geometry. Inoltre, il sistema funziona in combinazione con le Mappe d'ombra virtuali per creare ombre morbide ad alta risoluzione e in tempo reale.
Lumen sostituisce i riflessi dello spazio sullo schermo quando viene utilizzato nella scena.
Equivalente a Unity
Unity utilizza Enlighten Realtime Global Illumination per fornire un'illuminazione dinamica nella scena. Questo sistema fornisce un'illuminazione globale in tempo reale utilizzando informazioni di visibilità precalcolate insieme a mappe di luce per calcolare il rimbalzo indiretto della luce al runtime.
Questo differisce da Lumen, in quanto Lumen non richiede alcun dato pre-calcolato per fornire rimbalzi di luce indiretti.
Nebbia e trasparenza
Dopo aver eseguito il rendering dell'illuminazione dinamica e delle ombre, Unreal Engine esegue poi il rendering degli effetti di nebbia e trasparenza.
Unreal Engine esegue il rendering degli effetti nebbia con il suo sistema di Nebbia ad altezza esponenziale, che esegue il rendering della densità della nebbia in base all'altezza e alla distanza dalla telecamera. Inoltre, il sistema può generare nebbia volumetrica.
Gli oggetti trasparenti utilizzano un materiale traslucido e vengono renderizzati in questa fase del processo. Quando si utilizza il percorso di rendering differito, Unreal Engine utilizza le informazioni disponibili in GBuffer per eseguire il rendering della trasparenza. In alternativa, è possibile configurare il materiale in modo che utilizzi il percorso di rendering in avanti per produrre un effetto di trasparenza più preciso.
Equivalente a Unity
Unity supporta la nebbia lineare, esponenziale e quadrata esponenziale nella scena.
Effetti di post-elaborazione
Una volta renderizzati la nebbia e la trasparenza, Unreal può applicare effetti aggiuntivi all'immagine. Questi effetti sono chiamati effetti di post-elaborazione perché vengono applicati dopo che è stata elaborata l'immagine finale. Gli effetti si basano sul pixel shader e utilizzano le informazioni disponibili in GBuffer.
Alcuni effetti comuni di post-elaborazione includono sfocatura leggera, profondità di campo, raggi di luce, tonemapping e motion blur.
Nell'ambito di questa fase di post-elaborazione, Unreal Engine può applicare la Super risoluzione temporale (TSR). La TSR è un Upscaler temporale indipendente dalla piattaforma che Unreal Engine utilizza per renderizzare bellissime immagini 4K. Le immagini hanno una frazione del costo ammortizzando alcuni dei costosi calcoli di rendering su molti frame.
Nella catena di rendering, Temporal Super Resolution avviene dopo la profondità di campo e tutto ciò che segue viene ingrandito, come il motion blur, la sfocatura e così via.
Una volta applicati questi effetti a GBuffer, Unreal Engine esegue il rendering dell'immagine finale sullo schermo.
I passaggi descritti sopra generano un singolo frame sullo schermo. Questi step vengono spesso ripetuti tra le 30 e le 60 volte al secondo, a seconda del framerate target del gioco.
Equivalente a Unity
Unity è dotato di soluzioni di post-elaborazione basate sulla pipeline di rendering scelta. Molti degli effetti disponibili sono simili a quelli disponibili in Unreal Engine.
Inoltre, Unity 6 è dotato della Post-elaborazione spaziale-temporale (STP), uno scaler nativo basato su software che utilizza tecniche di sovracampionamento spaziale e temporale per produrre un'immagine di alta qualità con anti-aliasing.
Panoramica delle funzioni di rendering in Unreal Engine
Ora che sono stati compresi i passaggi eseguiti da Unreal Engine per eseguire il rendering di un frame sullo schermo, è possibile conoscere le funzionalità di rendering specifiche fornite con il motore.
Per saperne di più sulle funzioni di rendering di Unreal Engine, fai riferimento alla documentazione Illuminare l'ambiente.