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


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.