Як я можу створити ефект блиску?


9

Я намагаюся створити блискучий ефект для свого шейдера в реальному часі, але не знаю як.

Ось один приклад та інший приклад .

введіть тут опис зображення

Яку техніку я можу використати для цього?


Це може бути досягнуто за допомогою ефекту після обробки, подібного до цвітіння, але застосовуючи візерунок (текстуру зірки) до фази нижньої вибірки. Це все просто спекуляція жорстка.
акалтар

1
Чи не дозволила вам нормальна та дзеркальна карта зробити це за допомогою текстури?
JohnB

Я зробив тест, використовуючи звичайну карту. Але найважче - зробити так, щоб вони блищали відповідно до орієнтації зору та орієнтації світла.
MaT

Відповіді:


10

Що ж, коли нас попросять розробити будь-який шейдер, ми повинні почати з розбиття речей на менші проблеми. І як зауважте, блискучий ефект насправді не робить шейдер добре виглядати, але загальне освітлення та ефект, використовуючи лише один з них, не виглядатимуть так добре.

Перш за все, зазначимо те, що безпосередньо не входить до шейдера:

  1. Затінення не є частиною шейдера, і це робиться за допомогою окремого тіньового проходу.
  2. Я припускаю, що існує оклюзія навколишнього середовища (особливо, що це зображення, показане в питанні, особливо не використовує візуалізацію в реальному часі, але це припущення).

По-друге, давайте розбимо фактичний шейдер на окремі ефекти:

  1. Існує таке анізотропне освітлення, що дуже важливо для загального вигляду шейдера. Причина цього полягає в тому, що фактичний матеріал містить тканини, ці блискучі тканини змушують світловідбиття мати спрямований зміщення, роблячи найбільшу кількість відбитого світла в тому певному напрямку.

введіть тут опис зображення

введіть тут опис зображення Зауважте, що такі тканини мають нескінченно багато нормалів, але описана тут техніка наближається до найбільш значущої норми

Для того , щоб наблизити найбільш істотних нормальні, один з способів зробити, це використовувати координати текстури і розрахувати дотичні сітки, а замість обчислення N . L ви обчислите 1- (NT).

Повне пояснення тут . І вам, мабуть, потрібно реалізувати це в фрагменті шейдера, а не вершинній техніці, про яку вони говорять. Також можуть застосовуватися інші анізотропні моделі.

Тепер для блискучого ефекту:

Це можна зробити у просторі світу / місцевому просторі текстури або просторі екрану як окремий пропуск.

Алгоритм, який я можу придумати, використовує техніку обробки зображень (якщо припустити, що сітка має текстурні координати).

  • Згенеруйте високочастотний 2D шум на поверхні сітки за допомогою текстурних координат, перлін-шум здається хорошим кандидатом.
  • Застосуйте максимальний фільтр, використовуючи ядро ​​3х3 на шум. Це призведе до ефекту, подібного до зображення нижче, і тут описаний максимальний фільтр .

введіть тут опис зображення

Зверніть увагу, що наведене вище зображення є лише прикладом максимального фільтра, і застосувавши його до шуму, ви отримаєте щось подібне до зіркового поля.

  • Після цього застосуйте фільтр Гаусса з певним відхиленням шуму, щоб отримати форму зірки.

введіть тут опис зображення

Приклад фільтра Гаусса, застосованого на максимальному (ед) шумі.

  • Заключний крок - поєднувати це з оригінальною текстурою сітки та світлом. Це найкраще зробити за допомогою (|) або двобічної операції з оригінальною текстурою / кольором сітки, це займе лише білий від шуму та видалить усі чорні пікселі. Що стосується світла (і, можливо, інших окулярних карт), найкраще зробити це додати його або модулювати його за допомогою раніше поєднаних пікселів. Можливо, вам також знадобиться ефект післяобробки світіння для кращого світіння.

Зауважте, що ця методика може потребувати значної оптимізації для роботи в режимі реального часу.


3

Є цікава стаття AMD - Отримання процедур .

Здається, блискітки важче, ніж я думаю.
Гідне рішення: Використовуйте 3D-позицію для індексації функції 3D-шуму, додайте вектор перегляду, використовуйте функцію frac для подальшої рандомізації речей.

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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.