Come posso ridurre l'aliasing nell'effetto bagliore del mio contorno?


42

Sto cercando di replicare l'effetto del contorno luminoso nel gioco Left 4 Dead. L'effetto fa risplendere il contorno di un oggetto, anche quando l'oggetto è occluso. Ecco uno screenshot dell'effetto:

inserisci qui la descrizione dell'immagine

Sono in qualche modo in grado di replicare questo effetto nel mio programma basato su OpenGL. Questo è quello che sto facendo attualmente:

  • Crea una trama di colore e profondità che è la metà della dimensione dello schermo per il rendering degli oggetti luminosi
  • Cancella il colore bagliore / trame di profondità. Il colore è passato al nero.
  • Per ogni oggetto luminoso, renderlo alla trama luminosa come un colore solido
  • Esegui una sfocatura gaussiana separabile sulla trama bagliore
  • Rendering della scena a piena risoluzione come di consueto
  • Miscela in modo additivo la trama bagliore con la scena normale, ma usa la trama profondità bagliore per mascherare l'oggetto, lasciando solo il contorno sfocato.

Ecco uno screenshot del mio approccio:

inserisci qui la descrizione dell'immagine

Ecco lo shader di frammenti che combina la trama luminosa con la scena:

uniform sampler2D glowColorTex;
uniform sampler2D glowDepthTex;
uniform sampler2D sceneColorTex;
void main()
{
    vec2 uv = gl_TexCoord[0].st;

    vec4 color = texture2D( sceneColorTex, uv);

    float depth = texture2D( glowDepthTex, uv).r;
    if(depth == 1.0) {
        color += 2.0 * texture2D( glowColorTex, uv);
    }

    gl_FragColor = color;
}

Come puoi vedere, sembra funzionare per la maggior parte, ma l'aliasing sul contorno è davvero pessimo.

Qualcuno ha qualche suggerimento per appianare il bordo interno del contorno?

Dovrei campionare i valori di profondità vicini di ciascun pixel e ridimensionare il bagliore in base al numero di valori di profondità pari a 1,0?

O esiste un approccio migliore che produrrà risultati più fluidi?

Risposte:


13

Forse invece di verificarlo con il buffer di profondità a bassa risoluzione potresti usare il test dello stencil. Quando si esegue il rendering della scena normale, è sufficiente eseguire il rendering dell'oggetto che dovrebbe brillare nel buffer dello stencil (senza test di profondità, credo) e quindi fondere l'intera trama del bagliore, ma configurare lo stencil-test per passare solo dove si trova il buffer dello stencil non impostato, quindi mascherando l'oggetto ad alta risoluzione.

In questo modo si ottiene la sagoma esatta dell'oggetto originale, mentre una levigatura dei bordi porterebbe solo a risultati approssimativi, ma forse questi sarebbero sufficienti per te.


Grazie, sicuramente aiuta. Speravo in una tecnica che potesse supportare una qualche forma di antialiasing, ma questo è ancora un grande miglioramento.
Flashk,
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.