Computer Graphics in 10 Minuti
Da un triangolo in memoria a un pixel illuminato a schermo il minimo che ti serve.
La frame generation è un trucco costruito sopra un trucco molto più vecchio: la rasterizzazione real-time. Per capire cosa fa DLSS, devi capire cosa stava facendo la GPU prima che DLSS esistesse. Questo capitolo è un crash course. Torneremo su ogni concetto qui presentato con molto più dettaglio più avanti.
Una scena è una lista di triangoli
Tutto quello che vedi in un gioco 3D real-time un personaggio, un muro, una foglia, una pistola è, al livello più basso, una lista di vertici (punti 3D) connessi in triangoli. Un frame AAA moderno contiene tra i 10 e i 30 milioni di triangoli di geometria visibile.
Ogni vertice porta con sé dei dati: la sua posizione nello spazio 3D, un vettore normale (verso dove guarda la superficie), coordinate texture (UV), magari un tangente, magari colori per vertice, pesi di skinning per l'animazione, e così via.

La pipeline, da capo a fondo
Una GPU disegna un frame facendo passare ogni triangolo attraverso una sequenza fissa di stage. Questa è la pipeline di rasterizzazione. In una forma moderna semplificata:
- Vertex shader gira una volta per vertice. Trasforma il vertice dallo spazio oggetto allo spazio clip usando le matrici model, view e projection. Qui avviene anche lo skinning.
- Primitive assembly & clipping i vertici vengono raggruppati di nuovo in triangoli; i triangoli interamente fuori dal frustum della camera vengono buttati via, quelli che lo attraversano vengono tagliati.
- Rasterizzazione ogni triangolo viene mappato sull'insieme di pixel (più precisamente: fragment) che copre sullo schermo. Qui la geometria diventa pixel.
- Fragment shader (a.k.a. pixel shader) gira una volta per ogni pixel coperto da un triangolo. Qui avviene la maggior parte del lavoro: campionare texture, valutare equazioni di illuminazione, fare normal mapping, parallax, scrivere un colore.
- Output merger depth test (questo pixel è più vicino di quello che c'è già?), blending (semitrasparenza), scrittura nel framebuffer.

Cosa significa davvero "un pixel"
Quando il rasterizer dice che un triangolo copre un pixel, in realtà sta dicendo che il triangolo copre una piccola area quadrata dello schermo. Per decidere se shadeare quel pixel, la GPU si chiede: "il centro di questo quadrato cade dentro il triangolo?" Quel singolo test sì/no è la sorgente dell'aliasing i bordi a gradini che hai visto in ogni immagine 3D non trattata.

L'anti-aliasing è l'intera storia della computer graphics che cerca di risolvere questo singolo problema. Vedremo nel prossimo capitolo come l'anti-aliasing temporale ha sostituito i metodi spaziali più vecchi, e come la stessa macchina sia ciò che DLSS e compagnia usano oggi per fare qualcosa di molto più ambizioso.
Illuminazione in 0,5 ms
Il colore di un pixel viene da un'equazione di shading quasi sempre una variante del physically based rendering (PBR). Il fragment shader cerca albedo (colore base), roughness, valore metallic, normal map, e così via, poi valuta una BRDF a microfacet (Cook-Torrance o simile) contro ogni luce che raggiunge il pixel.
Per il real-time, questo significa:
- Un pugno di luci dirette (il sole, una torcia) valutate direttamente. Costa poco.
- L'illuminazione indiretta (la luce che rimbalza su altre superfici) viene approssimata. O bakata in lightmap statiche, o calcolata dinamicamente con approssimazioni screen-space (SSAO, SSR), o sempre più spesso con ray tracing in real-time (RTX, DXR).
- Le ombre vengono renderizzando la scena una seconda (o quarta) volta dal punto di vista della luce in una shadow map, e poi confrontando le profondità.
Ognuno è costoso. Per la fine del frame la GPU ha toccato ogni pixel dello schermo molte volte: una per scrivere la geometria in un G-buffer, una per le ombre, una per l'illuminazione, una per il post-processing.
Il G-buffer: non un'immagine, molte
I motori moderni fanno deferred shading. Invece di calcolare il colore finale per un pixel mentre rasterizzano la geometria, scrivono dati intermedi per ogni pixel in un insieme di texture chiamate G-buffer (geometry buffer). Poi un pass separato legge il G-buffer e fa la matematica pesante dell'illuminazione.
Un G-buffer tipico contiene:
- La posizione del pixel in world-space (o view-space) (spesso ricostruita dalla profondità).
- La normale della superficie.
- L'albedo (colore base).
- Valori di roughness e metallic.
- Un motion vector di quanto questo pixel si è mosso tra il frame precedente e questo.
Quel motion vector è il singolo pezzo di dato più importante per la frame generation. Tienilo a mente; ci passeremo un intero capitolo.

Il budget del frame
Se il gioco punta a 60 FPS, la GPU ha 16,6 millisecondi per fare tutto questo geometria, G-buffer, ombre, illuminazione, post-processing, UI per ogni frame. In 4K sono 8.294.400 pixel ciascuno toccato molte volte. Matematica in floating point a singola precisione, parallelizzata su migliaia di core, contro i limiti della banda di memoria.
A 120 FPS quel budget si dimezza. A 240 FPS si dimezza di nuovo. In 4K nativo con ray tracing, anche la GPU più costosa del pianeta non riesce a raggiungere questi numeri in un gioco impegnativo. Questo è il muro che la frame generation è stata inventata per scavalcare.
Nel prossimo capitolo vediamo il trucco che ha reso silenziosamente possibile tutto questo: il temporal anti-aliasing, la tecnica che ha insegnato ai motori a ricordarsi il frame precedente.