Як написати шейдер, який загоряється, коли предмети знаходяться біля поверхні?


15

У цьому геймплейному відео Overwatch щит персонажа світиться білим кольором у місцях, що знаходяться поблизу геометрії інших об'єктів.

Щит Рейнхарта вирізав геометрію рівня

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

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


2
Якщо ви використовуєте Unity, ця розмова може зацікавити . Перевірте розділ "Основні перехрестя", починаючи з слайда 26.
DMGregory

Отже, відповідь уже висвітлено нижче, але ось відео тепер пояснює це: youtube.com/watch?v=C6lGEgcHbWc
CobaltHex

Відповіді:


28

Загальний контур:

  1. Створіть карту глибини своєї сцени без щита. Ви можете отримати це ефективно безкоштовно, оскільки прозорі об’єкти часто виводяться в пізньому проході. В іншому випадку ви можете створити карту глибини, відображаючи екран екрана sans на RTT за допомогою шейдера глибини.

  2. Візуалізуйте сцену нормально, перенесіть карту глибини до вашої екранізації.

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

Демо

Я написав просту демонстрацію WebGL.

скріншот демонстрації

Рядок за рядком

Давайте детально перейдемо до коду шейдера фрагмента:

float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;

Зробіть карту глибини на кожному фрагменті. Не забудьте розділити розміри вікна перегляду, щоб перетворити фрагмент з екранного простору [0, ширина / висота] в нормалізовані [0,0, 1,0] координати. На даний момент, якщо ви просто встановите колір фрагмента на вибірку пікселя карти глибини, це виглядатиме так:

скріншот карти глибини

Карта глибини має відтінки сірого, тому ви можете отримати значення з будь-якого каналу (я rтут використовував ).

float solidsDiff = 1.0 - smoothstep(
    zNear,
    zFar,
    gl_FragCoord.z / gl_FragCoord.w
  ) - solidsDepth;

Потім ви можете використовувати цей зразок глибини, щоб знайти різницю між глибиною сцени та глибиною фрагмента щита. Не забудьте також нормалізувати свою глибину, взяти її від [zNear, zFar] (найближчої та далекої площин вашої камери) до [0.0, 1.0]. smoothstepробить це прекрасно. 1.0 -, Щоб інвертувати значення такого , що solidsDiffє 1,0 , коли різниця є максимальною (zFar - zNear) і 0,0 в мінімумі (0.0).

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

float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));

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

- 0.005Зсув просто додає білий запас , щоб зробити «перетин» товщі. Спробуйте змінити його!

gl_FragColor = vec4(vec3(1.0), alpha);

І нарешті, застосуйте цю альфа до кольору фрагмента.


Аксесуари

Ви можете зробити вигнутий щит, додати плазму для вигляду "енергетичного щита" (демонстрацію) або дослідити ефекти, лише показуючи перехрестя (демонстрацію) .

Небо Ваша відеокарта - це межа!


Ой. Моя. Гарні новини. Ти для дивовижного підручника.
Синій Буг

5

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


3

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

І напевно є матеріал в Інтернеті, який може вам допомогти. Дивіться цю дискусію, пов’язану з Unity: http://www.superspacetrooper.com/2012/06/tutorial-force-field-weapon-impact-energy-dispersion/, і це питання, пов'язане з UE4: https: //answers.unrealengine. com / questions / 74858 / dynam-forcefield-shader.html . Повний приклад шейдера, реалізація цього ефекту екрана, з доволі недавньої дискусії в Reddit, ви можете побачити: https://www.reddit.com/r/Unity3D/comments/3edi0n/does_any_one_knows_how_to_make_this_shield_effect/ І підручник, який не є саме на це, але достатньо пов'язано з цікавістю: http://www.nightbox-studios.com/2015/09/05/assets-shield-effect-scripts-for-texture3d-perlin-noise-shader/

Крім того, ось посилання на три пов’язані раніше питання на цьому самому веб-сайті, які, ймовірно, можуть бути корисними для розуміння понять, за якими ви хочете досягти:

Космічний щит відблиск

Як реалізувати енергетичний щит starwar в грі

Ефект екрана XNA з проблемою Primative

Нарешті, є досить багато приємних реалізацій щитових шейдерів як в Unity, так і в Unreal Engine у ​​відповідному віртуальному магазині, якщо ви випадково використовуєте будь-який з цих двигунів. Звичайно вони, як правило, платні активи, але майже завжди є відкритим кодом після покупки - і часто дешеві. Навіть якщо ви не станете користуватися цими двигунами, ці активи можуть допомогти пограти і навчитися.

Сподіваюся, це допомагає.


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

Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться. - З огляду
Vaillancourt

@Anko Звичайно, моя погана. Я зазвичай включаю пояснення та збірку посилань, але цього разу ви маєте рацію, справжнє пояснення не було. Я, мабуть, відповідь видалю.
MAND

@AlexandreVaillancourt Мені не подобається ідея просто скопіювати та вставити з іншого посилання, а не перенаправляти ОП до початкового джерела. Тоді, що я вважаю найкращим, це надати посилання в коментарях до питання. Проблема з цим полягає в тому, що ви знаєте багато матеріалів, які можуть вам допомогти, але це занадто багато для коментарів. Але все ж, оскільки тут вже була розміщена відповідна відповідь на пояснення, я просто
стерну
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.