Как я могу создать эффект блеска?

9

Я пытаюсь создать блестящий эффект для моего шейдера в реальном времени, но я не знаю как.

Вот один пример и другой пример .

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

Какой метод я могу использовать для реализации этого?

Мат
источник
Это может быть достигнуто с помощью эффекта пост-обработки, похожего на цветение, но с применением шаблона (текстура звезды) к фазе понижающей выборки. Это всего лишь жесткие предположения.
akaltar
1
Разве нормальная и зеркальная карта не позволят вам сделать это с помощью текстуры?
JohnB
Я сделал некоторый тест, используя карту нормалей. Но самое сложное - заставить их блестеть в соответствии с ориентацией взгляда и ориентацией света.
МАТ

Ответы:

10

Что ж, когда нас попросят спроектировать любой шейдер, мы должны начать с разбивки на мелкие проблемы. И, как вы заметили, эффект сверкания на самом деле не делает шейдер хорошо выглядящим, но общее освещение и эффект при использовании только одного из них не будут выглядеть так же хорошо.

Прежде всего, давайте заявим, что не является частью шейдера:

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

Во-вторых, давайте разберем настоящий шейдер на отдельные эффекты:

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

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

введите описание изображения здесь Обратите внимание, что такие ткани имеют бесконечно много нормалей, но методика, описанная здесь, приближается к наиболее значимым нормам

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

Полное объяснение здесь . И вам, вероятно, нужно реализовать это в фрагментном шейдере, а не в технике вершин, о которой они говорят. Другие анизотропные модели также могут применяться.

Теперь о блестящем эффекте:

Это можно сделать в мировом пространстве / локальном текстурном пространстве или на экране экрана в качестве отдельного прохода.

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

  • Создайте высокочастотный 2D шум на поверхности сетки, используя ее текстурные координаты, шум Перлина кажется хорошим кандидатом.
  • Примените максимальный фильтр, используя ядро ​​3x3 на шум. Это создаст эффект, подобный изображению ниже, и здесь описан фильтр max .

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

Обратите внимание, что приведенное выше изображение является просто примером фильтра max, и применение его к шуму даст что-то похожее на звездное поле.

  • Сделав это, примените фильтр Гаусса с определенным отклонением шума, чтобы получить форму звезды.

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

Пример фильтра Гаузиана, применяемого к максимальному (ed) шуму.

  • Последний шаг - объединить это с оригинальной текстурой сетки и светом. Лучше всего это сделать, используя двоичную операцию (|) or-ing с исходной текстурой / цветом сетки, при этом из шума будет извлечен только белый цвет и удалены все черные пиксели. Что касается света (и, возможно, других зеркальных карт), то лучше всего добавить его или смодулировать с ранее объединенными пикселями. Вам также может понадобиться эффект постобработки свечения для лучшего свечения.

Обратите внимание, что этот метод может потребовать значительной оптимизации для шейдеров реального времени.

concept3d
источник
3

Есть интересная статья AMD - Начало процедурного .

Кажется, что блестки сложнее, чем я думаю.
Достойное решение: используйте трехмерное положение для индексации функции трехмерного шума, добавьте вектор вида, используйте функцию ГРП для дальнейшей рандомизации.

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);
Мат
источник