Il motion blur è una tecnica atta a riprodurre il normale effetto di sfocamento di un oggetto che si muove a forte velocità. Questo permette di dare un maggiore senso di velocità agli oggetti e per questo moltissimi videogiochi usano questo effetto. Se ad esempio un personaggio muove una spada questa sarà più realistica se lascerà una scia dietro di essa (spesso nei videogiochi si esagera volutamente l'effetto per dare l'idea che il colpo sia ancora più potente e veloce). Per una cosa così astratta esistono numerosi approcci ma quelli che tratterò ora saranno il motion blur per ripetizione (tra i più usati), quello per deformazione e quello per accumulo di buffer (il più pesante ma il più spettacolare). Per tutti consiglio prima di leggere il minitutorial sulla dissolvenza in alphablending.
MotionBlur per ripetizione
Questo effetto è molto semplice, molto leggero se ben applicato ed efficace per la maggior parte delle situazioni. Il concetto è molto semplice: un oggetto che si muove occupava precedentemente delle diverse posizioni. Ad intervalli regolari memorizzate la posizione (comprensiva di angoli e scala) dell'oggetto e disegnate l'oggetto sia nella posizione attuale che in quelle precedenti ma aumentando gradatamente la trasparenza in modo che quelli in coda siano più trasparenti di quelli in testa. Sarà sufficiente regolare la distanza, la trasparenza ed il numero di volte che si vuole disegnare un oggetto (per oggetti veloci saranno necessari più disegni mentre per quelli lenti meno). Se ad esempio dovete renderizzare uno spadaccino potete renderizzare la spada in più posizioni e creerete la scia. Molto adatto per giochi di combattimento o sportivi (es la pallina da tennis), un pò meno per i giochi d'auto.
MotionBlur per deformazione
Questa tecnica è più difficoltosa e in genere richiede un vertex shader. Semplicemente deformate l'oggetto nella direzione opposta in cui viaggia aumentando la trasparenza diminuendo il valore dell'alpha nei vertici che si allontanano dall'oggetto. Per deformare è sufficiente moltiplicare i vertici per il vettore direzione e traslarlo. In alternativa potete creare delle mesh che rappresentino la deformazione (non consigliato). Per vedere la trasparenza sarà sufficiente l'uso dell'alphablending. Per un esempio vi basterà dare un'occhiata all'esempio della microsoft incluso nell'SDK.
MotionBlur per accumulo di buffer
Questa è senza dubbio la tecnica più spettacolare, forse non adatta a tutte le situazioni ma sicuramente quella di maggiore impatto visivo. La tecnica è relativamente semplice. Renderizzate su una texture l'intera scena (quindi rendering su texture fondamentale da conoscere) e disegnatelo sullo schermo tramite un rettangolo impostando la trasparenza con il TFactor ma sul backbuffer principale non dovrete mai effettuare il clear (la pulitura dello schermo). In questo modo il rettangolo si sovrapporrà alla immagine preesistente cancellando lentamente l'immagine in fondo. Gli oggetti in movimento avranno delle sfumature derivanti dalla diversa posizione degli oggetti mentre quelli immobili appariranno nitidi perchè sovrapponendo la stessa immagine più volte non si creerà la distorsione. La foto in alto riguarda proprio il motion blur per accumulo di buffer. Per il rettangolo potete usare il formato di vertice che più vi piace (potete anche usare un TLVertex già trasformato). Per il motionBlur usate questa impostazione dell'alphablending.
device.RenderState.SourceBlend = Blend.SourceAlpha
device.RenderState.DestinationBlend = Blend.InvSourceAlpha
device.TextureState(0).AlphaArgument1 = TextureArgument.TFactor
device.RenderState.TextureFactor = Color.FromArgb(tFactor, 255, 255, 255).ToArgb
Il pregio di questa tecnica è che potete modificare l'effetto semplicemente variando il valore di tFactor (più basso è più sfocato sarà il risultato), il difetto è che il motion blur verrà applicato a tutto, anche agli oggetti immobili se spostate ad esempio la telecamera (ma creerete qualcosa di molto realistico se usarete valori di trasparenza non troppo bassi). Quindi per ogni passo semplicemente renderizzatela su una texture invece che sul device e renderizzate la texture sul device senza il clear in modo che ricopra tutto lo schermo.
Tecnica avanzata
Dato che in questa maniera dovreste applicare l'effetto ad ogni oggetto sullo schermo conviene eseguire un rendering su texture con 2 diverse texture. In una copierete le parti della scena che volete in motion blur, usate la seconda per accumulare le texture al posto del device ed infine copiate questa sul device insieme alle cose che non volete abbiano l'effetto di motion blur applicato. La tecnica del motion blur è indipendente dalla complessità della scena e quindi risulta migliore rispetto ad applicare le precedenti 2 su tutti gli oggetti (a meno che non adoperiate un vertex shader). La qualità dipenderà comunque dalla grandezza della texture (meglio usare una texture di almeno 512 x 512). Ricordate anche di impostare la projection matrix regolando l'aspect ad 1 (essendo la texture quadrata il rapporto altezza - larghezza è uno) ma di rimetterlo bene per quando tornete a renderizzare sullo schermo.
Esempio VB.Net