Come posso implementare un effetto scanline?


8

Sto lavorando su un platform di vecchia scuola in libgdx e voglio che abbia un effetto "scanline", come questo:

maldita castilla scanline effect

Il mio primo tentativo è stato quello di creare una piccola trama e disegnarla su un quad a schermo intero. Ho usato due diverse modalità della fotocamera ortografica (una per la tessera principale del gioco e una seconda per renderizzare la trama della scanline). A volte la trama è bloccata sulla piastrella e a volte è troppo grande e copre l'intero schermo in nero.

Il mio approccio utilizza due telecamere e una trama è ragionevole? Qual è una buona soluzione per ottenere questo effetto?

Risposte:


4

Il problema con il rendering ingenuo di una piccola trama scanline su un grande quad a schermo intero è che la trama si ingrandirà , rendendo quello che era un insieme di scanline a singolo pixel nella trama molto più spesso, più sfocato (a seconda del metodo di interpolazione), e generalmente più brutto.

Dovresti invece tesserela trama attraverso il quad in modo da preservare un rapporto pixel-texel 1: 1. Ciò comporta la regolazione delle coordinate di trama del quad in modo che siano maggiori di 1 nella misura più lontana, e anche l'impostazione del parametro di avvolgimento delle trame da ripetere invece che da bloccare. Se la trama è 64x64 pixel e lo schermo è 1024x768 pixel, puoi immaginare che nell'asse X devi affiancare la trama 16 volte (1024/64). Allo stesso modo, sull'asse Y è necessario affiancarlo 12 volte (768/64). È possibile regolare questa matematica per i limiti effettivi della trama e dello schermo. Usa quei numeri (16 e 12) come estensioni massime delle coordinate di trama del tuo quad e otterrai un risultato molto migliore. A seconda di come la proiezione ortografica è attualmente impostata per le tessere, potrebbe non essere necessario modificarla per renderla.

In alternativa, puoi adottare un approccio shader: renderizza la tua scena normale su una trama, quindi rendi quella trama come un quad a schermo intero, ma ometti ogni strana linea di pixel. Se conosci i limiti dello schermo nello shader, puoi farlo abbastanza facilmente (questo è pseudo-codice , vagamente HLSL-ish, ma dovrebbe tradursi facilmente):

float2    screenSize;
sampler2D textureSampler;
float2    textureCoordinate;

float4 main () { 
   // Interpolation of texture coordinates means that we don't get nice
   // integer boundaries we could take the modulus of.
   float half_y = textureCoordinate.y * screenSize.y * 0.5;
   float delta = round(half_y) - half_y;
   float delta_squared = delta * delta;
   if (delta_squared < 0.1) {
      return texture2D(textureSampler, textureCoordinate);
   } 

   return float4(0,0,0,0);
}

0

Il problema con l'uso di una fotocamera è che ridimensionerà l'immagine. Ciò che essenzialmente vuoi è disegnare sempre la stessa immagine con le stesse dimensioni (100%). Presumo che sia abbastanza grande da coprire sempre l'intero schermo.

In questo caso, una soluzione sarebbe quella di applicare la trasformazione inversa della videocamera sull'immagine in modo tale che venga disegnata con una dimensione "pixel perfetta".

L'opzione più semplice sarebbe ridimensionarla da soli. Per esempio. se la fotocamera viene ingrandita al 75%, l'immagine verrà ridimensionata al 133% ( 1/0.75).


dici che l'immagine deve essere abbastanza grande da coprire l'intero schermo, non è possibile riempire un po 'di spazio con una piccola trama?
Alexandre GUIDET,

@AlexandreGUIDET Non sono sicuro. Uso una trama per dissolvenza in entrata e in uscita, ed è un pixel 1x1 che viene ridimensionato. Per le scanline, vuoi che si ripeta. Dovresti verificare se libGDX ha un'opzione per questo.
ashes999,

@AlexandreGUIDET hai provato questo?
ashes999

Scelgo un approccio diverso usando un'altra fotocamera e disegnando l'effetto scanline sopra la scena. Non sono ancora soddisfatto del risultato perché la scena sembra scivolare dietro le linee di scansione. Cosa ne pensi dell'utilizzo di uno shader invece?
Alexandre GUIDET,
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.