Come posso creare un effetto glitter?


9

Sto cercando di creare un effetto scintillante per il mio shader in tempo reale, ma non so come.

Ecco un esempio e un altro esempio .

inserisci qui la descrizione dell'immagine

Quale tecnica posso usare per implementare questo?


Potrebbe essere ottenuto tramite un effetto Post-process, simile alla fioritura, ma applicando un motivo (una trama a stella) alla fase di down-sample. Questa è solo una dura speculazione.
Akaltar,

1
Una mappa normale e speculare non ti permetterebbe di farlo tramite una trama?
John B,

Ho fatto alcuni test usando la normale mappa. Ma la cosa difficile è farli brillare secondo l'orientamento della vista e l'orientamento della luce.
MaT

Risposte:


10

Bene, quando ci viene chiesto di progettare uno shader, dovremmo iniziare suddividendo le cose in piccoli problemi. E proprio come nota l'effetto scintillante in realtà non rende lo shader bello, ma l'illuminazione generale e l'effetto, usando solo uno di essi, non saranno altrettanto belli.

Innanzitutto diciamo cosa non fa direttamente parte dello shader:

  1. L'ombreggiatura non fa parte dello shader e viene eseguita tramite un passaggio di ombreggiatura separato.
  2. I assumo c'è occlusione ambientale (soprattutto quali l'immagine mostrata in questione è particolarmente non utilizza real rendering tempo ma che è una supposizione).

In secondo luogo, suddividiamo lo shader reale in effetti separati:

  1. C'è un'illuminazione anisotropa, questo è molto essenziale per l'aspetto generale dello shader. Il motivo dietro questo, è che il materiale reale contiene tessuti, questi tessuti lucidi fanno sì che il riflesso della luce abbia un orientamento direzionale, producendo la maggior quantità di luce riflessa in quella determinata direzione.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine Si noti che tali tessuti hanno infiniti molti normali, ma la tecnica qui descritta si avvicina al normale più significativo

Al fine di approssimare il più significativo normale, un modo per farlo è quella di utilizzare tessitura coordinate e tangenti Calcola della maglia, e invece di calcolare N . L si calcola 1- (NT).

Spiegazione completa qui . E probabilmente dovrai implementarlo nello shader di frammenti piuttosto che nella tecnica di vertice di cui parlano. Possono essere applicati anche altri modelli anisotropi.

Ora per l'effetto scintillante:

Questo può essere fatto nello spazio mondo / spazio trama locale o spazio schermo come passaggio separato.

L'algoritmo a cui riesco a pensare, usa la tecnica di elaborazione delle immagini (supponendo che la mesh abbia dei bordi di trama).

  • Genera un rumore 2D ad alta frequenza sulla superficie della mesh usando le sue coordinate di trama, il rumore perlin sembra un buon candidato.
  • Applicare un filtro max usando il kernel 3x3 sul rumore. Ciò genererà un effetto simile all'immagine seguente e il filtro massimo è descritto qui .

inserisci qui la descrizione dell'immagine

Si noti che l'immagine sopra è solo un esempio del filtro massimo e applicandolo sul rumore si otterrà un valore simile a un campo stellare.

  • Una volta fatto questo, applica un filtro gaussiano con una certa deviazione sul rumore per ottenere una forma a stella.

inserisci qui la descrizione dell'immagine

Esempio di filtro gausiano applicato sul rumore massimo (ed).

  • L'ultimo passo è quello di combinare questo con la trama e la luce della maglia originale. Questo viene fatto meglio usando un'operazione binaria (|) o con la trama / colore della mesh originale, questo prenderà solo il bianco dal rumore e rimuoverà i pixel neri. Per quanto riguarda la luce (e possibilmente altre mappe speculari) la cosa migliore da fare è aggiungerla o modulare con i pixel precedentemente combinati. Potrebbe anche essere necessario un effetto di post-elaborazione del bagliore per un bagliore migliore.

Nota, questa tecnica potrebbe richiedere un'ottimizzazione significativa per uno shader in tempo reale.


3

C'è un interessante articolo AMD - Getting Procedural .

Sembra che le scintille siano più difficili di quanto penso.
Soluzione decente: usa la posizione 3D per indicizzare la funzione del rumore 3D, aggiungi il vettore della vista, usa la funzione frac per randomizzare ulteriormente le cose.

Sparkle:
float specBase = saturate(dot(reflect(-normalize(viewVec), normal),
lightDir));
// Perturb a grid pattern with some noise and with the view-vector
// to let the glittering change with view.
float3 fp = frac(0.7 * pos + 9 * Noise3D( pos * 0.04).r + 0.1 * viewVec);
fp *= (1 - fp);
float glitter = saturate(1 - 7 * (fp.x + fp.y + fp.z));
float sparkle = glitter * pow(specBase, 1.5);
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.