Temporal Anti-Aliasing: L'Idea che Ha Cambiato Tutto
Prima che DLSS potesse ricostruire frame, il TAA ha insegnato ai motori a ricordarli.
DLSS, FSR, XeSS e PSSR sono tutti, nel cuore, algoritmi temporali. Non ricostruiscono un'immagine da un singolo frame; accumulano informazioni attraverso molti frame. La tecnica da cui discendono è il Temporal Anti-Aliasing (TAA), ed è la singola tecnica di rendering più importante dell'ultimo decennio. Se capisci il TAA, il resto del corso è in discesa.
Il problema dell'aliasing, rivisitato
Nel crash course abbiamo visto che un pixel è o "dentro il triangolo" o "fuori dal triangolo" al suo campione centrale. Quella decisione binaria produce bordi a gradini (aliasing geometrico), tremolio sui dettagli piccoli (aliasing speculare) e "crawling" sulle linee sottili (aliasing sub-pixel).
Gli approcci classici all'anti-aliasing tentano tutti di prendere più campioni per pixel all'interno di un singolo frame:
- SSAA (super-sampling): renderizzare a 2× o 4× di risoluzione, downsample. Bellissimo, brutalmente costoso.
- MSAA (multi-sample): rasterizzare i bordi geometrici in più posizioni sub-pixel, shadeare una sola volta. Veloce per forward rendering, ma si rompe nel deferred shading, ed è il motivo per cui MSAA è morto verso il 2014.
- FXAA / SMAA: blur economici basati su edge detection applicati come post-process. Sembrano soft, non risolvono lo shimmer.
Quando deferred rendering e PBR sono diventati lo standard, l'industria era in stallo. MSAA era incompatibile con l'architettura di rendering; SSAA era troppo costoso; FXAA era un cerotto. Qualcos'altro doveva cedere.

Il trucco temporale
L'intuizione dietro il TAA: un pixel non deve prendere tutti i suoi campioni in una volta sola. Può prenderne uno questo frame, uno leggermente diverso il prossimo, un altro quello dopo, e mediarli nel tempo. Finché la camera e la scena non si muovono troppo veloci, il risultato converge verso quello che produrrebbe un costoso pass SSAA ma distribuito su tanti frame economici.
Lo si fa con due ingredienti:
- Sampling con jitter. Ogni frame, la matrice di proiezione viene spostata di una piccola quantità sub-pixel, in modo che il "centro" di ogni pixel cada in una posizione leggermente diversa all'interno del pixel. Su 8–16 frame, le posizioni dei campioni coprono l'area del pixel come un reticolo a bassa discrepanza.
- Reprojection della history. Per mediare attraverso i frame devi sapere dove ogni pixel era nel frame precedente. Per quello usi i motion vectors: un vettore per pixel che dice "questo pixel era nella posizione (x', y') l'ultimo frame".
Il pattern del jitter è quasi sempre una sequenza di Halton una sequenza deterministica a bassa discrepanza che riempie il quadrato unitario in modo più uniforme di qualsiasi numero casuale. Una scelta comune è Halton(2, 3) con 8 o 16 offset unici per ciclo.

L'algoritmo TAA, in pseudocodice
// Per ogni pixel del nuovo frame:
vec4 current = sample_current_frame(uv); // appena rasterizzato
vec2 mv = sample_motion_vector(uv); // indica dov'ERA il pixel
vec4 history = sample_previous_frame(uv - mv); // reprojection della history
vec4 blended = mix(history, current, 0.1); // 10% nuovo, 90% vecchio
write(blended);
Quel fattore di blend ~10% è il cuore di tutto. Ogni frame, il pixel mantiene il 90% di quello che aveva e aggiunge il 10% del nuovo campione (con jitter). Dopo ~20 frame i contributi sommano l'equivalente di un pixel super-sampled a 20 campioni. Anti-aliasing quasi gratis se puoi fidarti della history.
I due modi di fallire
Non puoi fidarti della history alla cieca. Due cose la possono rovinare:
- Il pixel non esisteva il frame scorso. Un nuovo triangolo è apparso (qualcosa è uscito da dietro un muro), o la camera ha girato e ha rivelato una nuova parte del mondo. Questo è il disocclusion. La history è sbagliata; usarla produce scie di ghosting.
- Il pixel esisteva ma aveva un aspetto diverso. Una luce si è accesa, un oggetto in movimento ha cambiato orientamento, un highlight speculare si è spostato sulla superficie. Usare una history stantia produce smearing.
Il TAA vero spende la maggior parte della sua complessità nel gestire questi due casi. Gli strumenti standard sono:
- Velocity rejection: se la magnitudine del motion vector supera una soglia, pesare meno la history.
- Depth rejection: se la profondità alla posizione reprojected è molto diversa dalla profondità attuale, la geometria sotto quel pixel è diversa rifiuta.
- Color clamping (neighborhood clipping): guarda il vicinato 3×3 del frame corrente, trova i valori di colore min/max e clampa il campione di history dentro quel box nello spazio colore YCoCg. Se la history è in disaccordo col vicinato locale, spingila verso il vicinato. Questo singolo trucco uccide la maggior parte del ghosting ed è in ogni implementazione TAA moderna.

Perché il TAA sembra soft
La fama del TAA come "sfocato" viene da tre sorgenti:
- Il blend stesso. Mescolare pixel vecchi e nuovi è un filtro low-pass sul dettaglio. Le feature nette da 1 pixel vengono smerigliate nel blend.
- Errore di reprojection. I motion vector non sono perfetti non includono il movimento delle ombre, la rifrazione o il jitter sub-pixel quindi la history viene campionata da una posizione leggermente sbagliata e filtrata bilinearmente, il che ammorbidisce.
- Rejection aggressivo della history. Quando il TAA è conservativo, butta via history valida e ricade su un singolo campione con jitter, che a quel punto rompe l'anti-aliasing.
La maggior parte delle implementazioni TAA moderne applica un pass di sharpening sopra per compensare. Il TAA di Unreal Engine 4, il TSR di Unreal 5 e il TAA di CryEngine hanno tutti un filtro di sharpening integrato.
TAA upscaling: da dove è venuto DLSS
Ecco la frase finale che rende possibile il resto del corso:
Una volta che puoi accumulare informazione sub-pixel attraverso i frame, non devi puntare alla stessa risoluzione. Puoi renderizzare il nuovo frame a risoluzione più bassa, e accumularlo in un buffer di history a risoluzione più alta. Su un numero sufficiente di frame, la history converge a un'immagine vera ad alta risoluzione.
Questo è il TAA upsampling o TAAU. Unreal Engine l'ha aggiunto nella 4.19 (2018). Funziona. È l'antenato diretto di DLSS, FSR 2, XeSS e PSSR. Ogni "AI upscaler" moderno è, nel cuore, TAAU con il color clamping e la logica di validazione della history calibrati a mano sostituiti da una rete neurale che fa un lavoro molto migliore.

Nel prossimo capitolo guardiamo la struttura dati che rende tutto questo possibile: i motion vector, cosa sono davvero, come il motore li produce e perché sbagliarli è la singola maggior fonte di artefatti in ogni upscaler.