Evoluzione dei motori grafici - Doom III, Half-Life 2, Unreal 2

Articolo Tecnico su:
Evoluzione dei motori grafici - Doom III, Half-Life 2, Unreal 2


: Duke




Premessa.
Un paio di doverose premesse: un motore 3d è composto da svariati elementi, che vanno dalla IA, alla fisica, alle interfacce utente, alla sezione audio per finire con la vera e propria gestione del mondo, che vediamo tramite la renderizzazione di ambienti pseudo 3D.
Col tempo, lentamente tutto tende a migliorarsi, limando i difetti ed ampliando i pregi, in maniera naturale. Migliorare non innovare.
Migliorare è un processo lento e costante, innovare è l'attimo esplosivo che porta a qualcosa di completamente diverso. La fisica, l'IA, le interfacce utente migliorano mentre la renderizzazione degli ambienti si innova. Il motivo è semplice: tutti sappiamo cosa aspettarci per giudicare un comportamento “realistico” ed è a quello vogliamo arrivare.
In generale, riusciamo a distinguere un comportamento “idiota” da uno plausibile che è esattamente ciò che vorremmo. Con il tempo, la potenza dei prossimi HW, ci si avvicinerà sempre piì ad una finzione credibile, un poco per volta.
La rappresentazione a video, invece, non sarà mai “realmente finta”, proprio perché “filtrata” da un monitor. Quando si guarda la TV non si ha alcun dubbio tra quale sia realtà e quale sia finzione ed allo stesso modo quando avremo il fotorealismo non avremo neanche lontanamente una “finzione credibile”, perchè sarà sempre un monitor quello che avremo di fronte.
Pensando ai motori 3D ed alle loro innovazioni la prima cosa che viene in mente è la “grafica”, in senso lato: il resto semplicemente si migliora. In questo articolo si parla in modo informale delle differenti tecnologie di rappresentazione a video, nei limiti che una conoscenza non professionale comporta. Se siete programmatori, girate al largo: è per il vostro bene! :D

Iniziamo?
Partiamo dal una considerazione: la “grafica” è un connubio di HW/SW, quindi se in un determinato momento abbiamo avuto a disposizione realmente delle features, queste sono state legate in modo inscindibile all'HW del momento. Possiamo vedere un parallelismo tra i principali motori 3D e le features HW supportate dalle schede video.
Passiamo ad alcune osservazioni riguardo i tre principali motori grafici del prossimo futuro, nei limiti di ciò che ci è concesso sapere ad oggi: Unreal 2, Half-Life 2 e Doom3. Qualcuno obietterà che due devono ancora uscire, ma se siete concordi con me nell’affermare che un motore grafico è legato alle features HW del momento e che queste ultime sono accessibili tramite interfacce software come il Direct 3D, allora “analizzando” le differenze tra le varie versioni di queste ultime, possiamo mettere in luce le differenze principali tra i motori che vi si appoggiano.

Unreal 2 rappresenta al meglio le Direct X 8/8.1, Doom3 le (Open GL 2.0 con ottimizzazioni proprietarie, che grosso modo equivalgono alle) DX9 ed HL2? Bella domanda, da ciò che ho visto e letto in giro, “sembra” un DX 8.1 con i fiocchi, “sporcato” di DX9: un tramite ideale tra due generazioni differenti.

Cosa abbiamo qui?
Cominciamo a vedere U2 (o Unreal Tournament 2003): quali grosse differenze possiamo notare con, Unreal o Unreal Tournament? Ambienti piì grandi e dettagliati, una fisica piì “credibile” ed un audio piì ricco. E poi? Ombre ed effetti di luce piì “gagliardi”, ovviamente. La domanda sorge spontanea: sarebbe stato possibile realizzare gli stessi identici schemi con i motori precedenti?
Se la risposta è no, perchè?
Dunque, come sapete l'introduzione delle DX8 e delle GF3 ha portato due grandi innovazioni: i vertex ed i pixel shaders. Tutti sappiamo che cosa è uno shader (una specie di motore programmabile che accetta una serie di istruzioni, di variabili e costanti, applica un programma definito dai caratteri precedenti e descritto tramite un linguaggio di basso livello ad un vertice, o gruppo di vertici, oppure ad un pixel, o gruppi di pixel) DX8.

Cosa avevamo a disposizione prima degli shader? Dove stà il “bello”?
Prima avevamo comunque dei motori, solo che questi sapevano compiere 10, 100, 1000 operazioni (su un oggetto), eventualmente combinandone tra loro un certo numero, per ottenere i vari effetti.
Ricordate l'NSR delle GF2 (Nvidia Shader Rasterizer)? Ecco, quello è stata la massima espressione di questo concetto: una GPU munita di pipeline con due sole texture unit poteva processare fino a 7 effetti alla volta, con lo scopo di ottenere un effetto piì complesso (o reale).
Quindi era possibile, per esempio, ottenere un effetto acqua spettacolare, con tutte le riflessioni e le rifrazioni del caso (certo andava bene solo nelle demo, pena fps ignobili... però era possibile).

Quest'ultima frase dovrebbe già fare intuire i limiti di un architettura rigida (DX7): oltre alla limitazione alla fantasia degli autori, la realizzazione di effetti complessi distrugge le prestazioni.
Quindi, alla domanda “Sarebbe stato possibile realizzare gli stessi identici schemi con i motori precedenti?”, la risposta migliore è: quelli “leggeri”, si, ma con grosse richieste HW e con GPU decisamente piì veloci (tanti Mhz) e con molta RAM mentre quelli piì pesanti no, o meglio, all'estremo si, ma solo teoricamente. Il motore di U2 fa questo e niente di piì, niente di meno. L'ho fatta troppo facile? Si, vediamo di approfondire.

Direct X: Versioni a confronto
Prendiamo un dado ed immaginiamo di volerlo rappresentare a video. Un dado è un cubo con gli spigoli smussati, quindi potremmo, per esempio, costruire un semplice cubo “tagliare” e raccordare gli spigoli per poi applicarci le texture (DX7) oppure scrivere un piccolo shader, in questo caso vertex, che schiacci tutti i vertici nel modo migliore (DX8). In questo secondo caso abbiamo da giostrare “solo” 12 triangoli (6 quadrati delle facce) ed ai raccordi “pensa” la scheda video. Nel primo ci smaziamo noi a costruire il wireframe ad hoc. Inoltre gli shaders agiscono in maniera dinamica: il nostro dado potrebbe pulsare, per esempio. In DX7 ci si dovrebbe calcolare i vertici per ogni nuova posizione, passarli alla SV che poi macinerebbe il tutto per realizzare il frame, con le DX8 una volta “generato” il primo cubo la CPU non si dovrebbe occupare d'altro.

Apro una parentesi: la CPU trasforma le istruzioni in un linguaggio comprensibile alla SV, quindi, per ora, la primissima parte del lavoro di costruzione della matrice relativa è ancora affibbiato al processore. Dopo ci pensano le nostre prodigiose ATI o Nvidia, ma un minimo di pappa pronta serve ancora.

Tornando a noi, a differenza sostanziale è questa: a video non vediamo nulla di concettualmente sconvolgente, ma piì passa il tempo e piì vediamo processi che finalmente sono applicabili in modo fruibile (non a mezzo frame/ora). Nella stessa ottica vengono le DX9 che non innovano ma migliorano. Cosa? Gli shader appunto: nelle DX8 sono difficilmente programmabili e limitati: poche istruzioni (e variabili)/programma, impossibilità di eseguire piì programmi per farne uno complesso. Inoltre viene introdotta esplicitamente la gestione delle ombre, che non sono piì generici effetti a video, ma hanno una loro dignità.

Doom 3: Massima espressione dei Vertex Shader
Doom3, come idea di base, non fa un uso smodato di poligoni: spreme all'inverosimile i pixel shaders. Immaginiamo di voler rappresentare un tubo che corre lungo una parete ed illuminato da una luce, che magari si muove: per avere la migliore resa possiamo usare moltissimi poligoni ed una texture ad alta risoluzione con qualche effetto di contorno e sbatterci una fonte di luce (con il calcolo delle relative ombre), oppure usare pochi poligoni, sfruttare effetti shaders per dire alle texture del tubo come modificarsi in base alla posizione della sorgente luminosa ma anche, e piì semplicemente, usare effetti per far sembrare lisce superfici frastagliate da pochi triagoli.

Certo, serve un motore (ed uno studio delle capacità HW) con i controfiocchi, ma Carmack è un Dio, quindi il probema non si pone. :D Inoltre, considerato che si usano effetti sulle texture per alleggerire il calcolo dei vertici (effetto statico), e che di conseguenza, mancando poligoni, tutte le tecniche e gli effetti che ne fanno uso devono essere emulati tramite shaders (effetti dinamici), e che tutti gli shaders (quelli statici e dinamici) devono andare quasi sempre in contemporanea, le variabili ed il grado di complessità delle istruzioni aumenta esponenzialmente.

Un altro punto importante è che, vista la complessità degli shaders che servono, non si può pensare di fare tutto in assembly: e qui le DX9 offrono una specie di C per la scrittura di questi “motori”, rendono piì facile la vita ai programmatori che sono incentivati a sfruttare a fondo queste nuove possibilità. Tornando a noi, si risparmiano risorse sui vertici e si investono sulle texture. Però facendo così si liberano risorse per la gestione delle ombre e per i vertex shaders. In che senso? Bene, pensiamo al nostro omino 3d: fico, dettagliato e munito di ombra. In se non è un modello complesso, molte delle sue parti sono in realtà un pezzo unico (per risparmiare poligoni), quindi per farle muovere si ricorre alla deformazione tramite programmini appositi, sarà poi l'illusione data dagli effetti sulle texture a non farci vedere l'inganno. Ok, diciamo che il nostro omino ha alzato il braccio: in realtà non ha mosso tanti poligoni, giusto? Quindi i calcoli per l'ombra saranno ridotti, considerando poi che oggi giorno c'è un buffer apposito, direi che il tutto risulta accessibile. Certo servono schede che facciano questo in HW, schede DX9.

Half Life 2
Per HL2 non mi sento di sbilanciarmi piì di tanto, ma sembra che gli effetti DX9 siano stati usati per cose specifiche come l'acqua, al fine di alleggerire i punti critici ma per il resto non si vedono effetti e soluzioni che non siano già comparse nei vari demo che hanno accompagnato le schede video da due anni a questa parte, solo che qui hanno un senso. Se questa chiaccherata imprecisa e per nulla tecnica è servita a chiarire un poco le differenze tra i motori grafici DX8 e DX9, direi che non posso chiedere di piì. In caso negativo, sappiate che ci sono valanghe di siti in inglese ma anche italiani che parlano dei singoli aspetti, ma il tempo e l'attenzione che richiedono sono moooooolto superiori a quelli richiesti per queste due paginette, e se non si è nel mestiere non so quanto convenga.

Fonti: http://developer.nvidia.com/docs/IO/1305/ATT/GDC2K1_DX8_Pixel_Shaders.ppt http://www.unreal2.com
http://www.itportal.it/developer/cpp/motori3d/
http://www.multiplayer.it/itaprogaming/docs&tuts/3d&effetti/3d&effetti.asp