Jak mogę stworzyć efekt brokatu?

9

Próbuję stworzyć błyszczący efekt dla mojego modułu cieniującego w czasie rzeczywistym, ale nie wiem jak.

Oto jeden przykład i inny przykład .

wprowadź opis zdjęcia tutaj

Jakiej techniki mogę użyć, aby to zaimplementować?

Mata
źródło
Można to osiągnąć poprzez efekt postprocesowy, podobny do rozkwitu, ale stosując wzór (teksturę gwiazdy) do fazy pobierania próbki. To wszystko tylko trudne spekulacje.
akaltar
1
Czy normalna i lustrzana mapa nie pozwoliłaby ci tego zrobić poprzez teksturę?
JohnB
Zrobiłem test przy użyciu normalnej mapy. Ale trudno jest sprawić, by błyszczały zgodnie z orientacją widoku i orientacją światła.
MaT

Odpowiedzi:

10

Cóż, kiedy zostaniemy poproszeni o zaprojektowanie dowolnego shadera, powinniśmy zacząć od podzielenia rzeczy na mniejsze problemy. I tak jak zauważamy, efekt połysku tak naprawdę nie sprawia, że ​​shader wygląda dobrze, ale ogólne oświetlenie i efekt, użycie tylko jednego z nich nie będzie wyglądać tak dobrze.

Przede wszystkim określmy, co nie jest bezpośrednio częścią modułu cieniującego:

  1. Cieniowanie nie jest częścią modułu cieniującego i odbywa się to za pomocą osobnej karty cieniowania.
  2. I zakładać, że jest okluzji otoczenia (zwłaszcza, że przedstawione w pytaniu ten obraz jest szczególnie prawdziwe w czasie nieużywania renderujący ale to założenie).

Po drugie, podzielmy rzeczywisty moduł cieniujący na osobne efekty:

  1. Istnieje anizotropowe oświetlenie, co jest bardzo niezbędne dla ogólnego wyglądu shadera. Powodem tego jest to, że rzeczywisty materiał zawiera tkaniny, tkaniny te błyszczące powoduje odbicie światła ma kierunkową polaryzacji, jak najbardziej ilość odbitego światła w tym określonym kierunku.

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj Należy pamiętać, że takie tkaniny mają nieskończenie wiele normalnych, ale opisana tutaj technika jest zbliżona do najbardziej znaczącej normalnej

W celu zbliżenia najbardziej znaczący normalny, jeden sposób to zrobić, jest użycie współrzędnych tekstur i stycznych oblicz siatki, a zamiast obliczania N . L obliczasz 1- (NT).

Pełne wyjaśnienie tutaj . Prawdopodobnie musisz zaimplementować to w module cieniującym fragmenty, a nie w technice wierzchołków, o której mówią. Mogą również obowiązywać inne modele anizotropowe.

Teraz efekt połysku:

Można to zrobić w przestrzeni świata / lokalnej przestrzeni tekstur lub w przestrzeni ekranu jako osobne przejście.

Algorytm, który mogę wymyślić, wykorzystuje technikę przetwarzania obrazu (zakładając, że siatka ma współrzędne tekstury).

  • Generuj szum 2D o wysokiej częstotliwości na powierzchni siatki, używając jego współrzędnych tekstury, hałas perlin wydaje się dobrym kandydatem.
  • Zastosuj filtr maksymalny za pomocą jądra 3x3 w hałasie. Spowoduje to wygenerowanie efektu podobnego do poniższego obrazu, a tutaj opisano maksymalny filtr .

wprowadź opis zdjęcia tutaj

Zauważ, że powyższy obraz jest tylko przykładem filtra maksymalnego, a zastosowanie go do szumu da coś podobnego do pola gwiazdowego.

  • Po wykonaniu tej czynności zastosuj filtr Gaussa z pewnym odchyleniem hałasu, aby uzyskać kształt gwiazdy.

wprowadź opis zdjęcia tutaj

Przykład zastosowania filtra Gausiana dla maksymalnego (ed) hałasu.

  • Ostatnim krokiem jest połączenie tego z oryginalną fakturą siatki i światłem. Najlepiej jest to zrobić przy użyciu (|) lub binarnej operacji z oryginalną teksturą / kolorem siatki, to zabierze tylko biel z szumu i usunie wszelkie czarne piksele. Jeśli chodzi o światło (i ewentualnie inne mapy zwierciadlane), najlepszą rzeczą do zrobienia jest dodanie go lub modulowanie za pomocą wcześniej połączonych pikseli. Możesz także potrzebować efektu końcowego przetwarzania blasku, aby uzyskać lepszy blask.

Uwaga: ta technika może wymagać znacznej optymalizacji dla modułu cieniującego w czasie rzeczywistym.

concept3d
źródło
3

Jest ciekawy artykuł AMD - Pierwsze procedury .

Wygląda na to, że iskierki są trudniejsze niż myślę.
Przyzwoite rozwiązanie: użyj pozycji 3D, aby zindeksować funkcję szumów 3D, dodaj wektor widoku, użyj funkcji frac, aby dalej losować.

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);
Mata
źródło