Come creare uno shader pixel "retrò" per gli sprite 2D trasformati che mantengono la fedeltà dei pixel?


10

L'immagine seguente mostra due sprite resi con campionamento di punti su uno sfondo:

inserisci qui la descrizione dell'immagine

  • Il cranio sinistro non ha rotazione / ridimensionamento applicati, quindi ogni pixel si abbina perfettamente allo sfondo.
  • Il cranio destro viene ruotato / ridimensionato e ciò si traduce in pixel più grandi che non sono più allineati agli assi .

Come potrei sviluppare un pixel shader che renderebbe lo sprite trasformato sulla destra con pixel allineati agli assi della stessa dimensione del resto della scena?

Ciò potrebbe essere correlato al modo in cui il ridimensionamento dello sprite è stato implementato nei vecchi giochi come Monkey Island, perché è l'effetto che sto cercando di ottenere, ma con l'aggiunta della rotazione.


modificare

Secondo i suggerimenti di kaoD, ho cercato di affrontare il problema come post-processo. L'approccio più semplice è stato il rendering prima su una destinazione di rendering separata (downsampling per corrispondere alla dimensione del pixel desiderata) e quindi l'upscaling quando si esegue il rendering una seconda volta. Ha soddisfatto le mie esigenze di cui sopra.

Per prima cosa ho provato a farlo Linear -> Pointe il risultato è stato questo:

inserisci qui la descrizione dell'immagine

Non c'è distorsione ma il risultato appare sfocato e perde la maggior parte dei colori delle luci. Secondo me rompe il look retrò di cui avevo bisogno.

La seconda volta che ho provato Point -> Pointe il risultato è stato questo:

inserisci qui la descrizione dell'immagine

Nonostante la distorsione, penso che potrebbe essere abbastanza buono per le mie esigenze, sebbene appaia meglio come fermo immagine che in movimento.

Per dimostrare, ecco un video dell'effetto, sebbene YouTube ne abbia filtrato i pixel:

http://youtu.be/hqokk58KFmI

Tuttavia, lascerò la domanda aperta per qualche giorno in più nel caso in cui qualcuno trovi una soluzione di campionamento migliore che mantenga l'aspetto nitido mentre diminuisce la quantità di distorsione durante lo spostamento.


Dovrebbe essere un teschio ...?
DeadMG

@DeadMG Un teschio di bue, immagino?
David Gouveia,

Bell'effetto, sembra migliore di quanto pensassi (l'ho provato su una risoluzione e palette estremamente basse, 40x30 EGA.) È praticamente l'aspetto che otterrai nel tuo shader postfx. A proposito, dubito che esista una soluzione di campionamento migliore che mantenga l'effetto come previsto. NN è praticamente ciò che dà
quell'aspetto

@kaoD Ma ricorda che sto applicando due passaggi. Il secondo passaggio che ricopre l'immagine sarà comunque il vicino più vicino per preservare l'atmosfera retrò. Ma penso che potrebbero esserci dei benefici nel provare diverse tecniche di campionamento per il primo passaggio. Attualmente sto esaminando Scale2x!
David Gouveia,

@kaoD No, mi arrendo. La modifica dei parametri dello shader tra ciascuna chiamata sprite SpriteBatchrichiede l'utilizzo della modalità Immediata, quindi non vale la pena. Vado con questo :)
David Gouveia,

Risposte:


3

Dovresti applicare lo shader DOPO che lo sprite è stato ruotato.

Se l'intera scena non è ancora stata ombreggiata e i tuoi sprite sono effettivamente pixelati, quello che ti serve è una sorta di filtro post-FX per l'intera scena. La media delle regioni di pixel funzionerà bene. Non è esattamente quello che intendi (sembrerà un po 'reticolato quando ti muovi / ruoti) ma potrebbe fare il trucco.

L'unico modo per mantenere quel look retrò fedele a quello che vuoi è in realtà disegnare tu stesso le tue rotazioni di sprite. Non ha nulla a che fare con il modo in cui è stato implementato il ridimensionamento: la risoluzione era in realtà scarsa, a proposito, hai provato con risoluzioni estremamente basse? Potrebbe anche fare il trucco e sembrerà più naturale poiché, beh, in realtà è ciò che ha causato l'effetto che stai cercando. Ed è economico! Molto a buon mercato! In effetti sarà più economico di quello che hai già (meno esecuzioni di shader di frammenti).

L'effetto è rovinato nell'immagine di esempio perché la risoluzione è elevata rispetto agli sprite, quindi ti consente di vedere i pixel reali sulla scena.


Sì, non sto ancora usando alcun shader. Sono solo sprite regolari con trame a risoluzione molto bassa, rese con il default di XNA SpriteBatchcon il campionamento dei punti attivato. Ma un post-FX potrebbe davvero funzionare. Per i principianti, proverò il rendering con campionamento lineare su una destinazione di rendering, quindi eseguirò il rendering dell'intera destinazione di rendering sul backbuffer con campionamento puntuale.
David Gouveia,

@DavidGouveia non perdere l'occasione di sottovalutare la tua risoluzione. Se vuoi davvero ottenere l'effetto originale è il tuo colpo migliore. Se hai bisogno della tua alta risoluzione (se una parte del tuo GFX è ad alta risoluzione o vuoi abbinare le risoluzioni native) puoi comunque eseguire il rendering in un buffer off-screen a bassa risoluzione e quindi dipingerlo nel tuo framebuffer ad alta risoluzione come un intero quad-schermo con filtro disattivato. Tieni presente che devi ovviamente abbinare le proporzioni per evitare pixel rettangolari, ovviamente.
Kaao

Controlla la mia modifica :) Penso che abbia risolto la maggior parte del problema, anche se sono ancora curioso di sapere se esiste una soluzione di campionamento migliore del vicino più vicino per questo problema. Lascerò la domanda per un po 'di più.
David Gouveia,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.