La base fisica dei colori di una chiazza di petrolio è l' iridescenza e anche correlata agli anelli di Newton . In particolare, lo spessore dello strato di olio è dell'ordine della lunghezza d'onda della luce. Poiché la luce si riflette dalla superficie superiore e inferiore dell'olio, a qualsiasi data lunghezza d'onda, ad alcuni angoli le due riflessioni saranno sfasate e si annulleranno a vicenda; ad altri angoli i riflessi saranno in fase e si sommeranno. Questo accade ad angoli diversi per ogni lunghezza d'onda, quindi illuminare l'olio con la luce bianca produce tutti quei colori. Se lo illuminassi con una sola frequenza (ad es. Luce laser) vedresti solo una serie di anelli chiari e scuri.
Se ignori la rifrazione nello strato di olio, semplicemente elaborando la geometria della situazione, puoi scoprire che la luminosità della luce riflessa per una determinata lunghezza d'onda dovrebbe variare come
sin(2.0 * pi * oilThickness / (dot(L, H) * wavelength)) * 0.5 + 0.5
Teoricamente questo dovrebbe essere integrato su tutte le lunghezze d'onda, ma in pratica probabilmente puoi semplicemente farlo per rosso, verde e blu - diciamo rispettivamente 700, 550 e 400 nm. La modifica dello spessore dell'olio modifica il raggio apparente degli anelli di colore. Avrei probabilmente 2.0 * pi * oilThickness / wavelength
incluso un singolo valore RGB fornito allo shader come valore uniforme. Potresti moltiplicarlo per una trama per simulare lo spessore variabile dell'olio, se lo desideri - questo è probabilmente ciò che dà la maggior parte della trama interessante nell'immagine sopra.
Questo produce un valore di colore RGB che puoi moltiplicare nel tuo BRDF. Il dot(L, H)
fattore verrebbe utilizzato per le luci puntiformi / direzionali e puoi sostituirlo dot(N, V)
per applicarlo anche a un riflesso della mappa ambientale.
Disclaimer: non ho provato questo in uno shader, ho appena disegnato alcuni diagrammi e mi sono convinto che "dovrebbe funzionare" ... quindi fammi sapere i risultati se lo provi! :)