Як я можу процедурно відрегулювати оправи здоров’я неправильної форми?


35

Питання про традиційну прямокутну або сердечну базу здоров'я - це щось добре зрозуміле і легко вирішене. Але яке прийняте рішення для таких "креативно-образних" барів для здоров'я, як макет, зроблений нижче?

Порожнє здоров'я Повне здоров'я, часткове здоров'я

Очевидним способом цього було б мати спрайти "між", тому третім зображенням буде власний спрайт, а також безліч інших переходів для різних рівнів здоров'я. Але це здається дійсно неелегантним, і кількість внутрішніх людей, необхідних для створення плавного переходу між станами здоров'я, було б великим.

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

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


5
"N̶a̶n̶o̶m̶a̶c̶h̶i̶n̶e̶s̶ Shaders, син"
Mukesh Ingham

Я відчуваю, що цей перехід можна було б визначити математично, звідти ви можете змусити комп'ютер обчислювати піксельні координати, щоб показати / приховати, а не попередньо їх попереджати
Річард Тінгл

Як у формі серця «легко вирішити» серцеподібну смугу здоров’я?
MooseBoys

1
@MooseBoys Я говорив про здоров'я на основі серця, а не у формі серця. Подумайте Легенда про ігри Zelda. Вибачте, що не ясніше.
msd7734

@RichardTingle, хороша ідея :)
Jon

Відповіді:


48

Існує дуже простий спосіб досягти цього за допомогою шейдерів, вам потрібні три текстури: порожня панель здоров'я, текстура панелі здоров'я та маска з градієнтом розподілу здоров’я з одним крайнім (наприклад, найтемнішим не чорним чи найбільш прозорим значенням альфа) на одному кінці та інші з іншого кінця. Найкраще це показано на зображенні, я наразі не можу зробити малюнок вигнутого градієнта лише лінійним - але я впевнений, що у ваших художників не виникне жодних проблем: введіть тут опис зображення Тепер у шейдері вибірку текстур та порогове значення маски, відкидання всіх пікселів, які не є яскравіше, ніж поріг введення (базується на введенні% шейдера).
Ти міг би використовуйте математичну формулу для маскування замість текстури, але якби ви це зробили, ви б все одно дуже обмежений формами, які ви можете (= прості) створити за допомогою вказаних формул - і знайти їх не є тривіальним.
* дивіться коментарі


9
У багатьох випадках (включаючи приклад ОП) використання окремої текстури для кольору є надмірною. У більшості випадків ви можете просто переробити градієнт маски сірого до кольорів, визначених як уніформа для шейдера, при цьому все одно відкидаючи будь-які значення маски нижче певного порогового значення.
bcrist

1
Насправді вам не потрібні найтемніші та не чорні, ви можете використовувати альфа-канал для екранування пікселів, які ви не хочете.
Джек Едлі,

1
@JackAidley впевнений, що це було б можливо, але я хотів, щоб рішення було максимально гнучким - у більшості назв AAA у вас немає hp просто "червоного кольору", але він текстурований.
wondra

1
@bcrist хороший момент, я вважав, що пропонується це як оптимізація. Але я не зміг намалювати його належним чином, тому вирішив зберегти це якомога простіше і залишити оптимізацію для реалізації.
wondra

@wondra Для багатьох випадків, включаючи приклад вигляду в ОП, ви можете використовувати процедурний градієнт або одновимірний пошук кольорів (з рівнем маски як вхідний), а не текстуру.
Випадково832

34

Реалізовано математично, як піксельний шейдер:

На процесорі обчисліть HealthDirection та його "крапковий продукт з V2 введіть тут опис зображення

На GPU обчисліть нормалізований напрямок від центральної точки для кожного пікселя. Порівняйте кожен крапковий продукт із HealthDirections ', щоб вибрати, чи слід відтіняти "фон" чи колір. введіть тут опис зображення

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

Намалюйте смугу спочатку, застосувавши алгоритм до квадрата; кольори виводу між rangeMin та rangeMax (можна було запекти) та clip () або вивести прозорим будь-де. Далі намалюйте (модифікований) спрайт над ним, використовуючи альфа. Я простежив твою смужку в CAD, заповнив її, потім "магією розмахував" суцільну кольорову форму в Paint, щоб видалити її. Шахта виглядає як лайно завдяки змішуванню AutoCAD та Paint вручну; якщо припустити, що ви змішуєте внутрішні краї до прозорих, ваші будуть виглядати ідеально .

Біла межа - це межі квадра. Це та червоний X - лише для ознайомлення:

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

"Спрайт з отвором" не потрібно надавати одночасно з панеллю здоров'я. Їх слід оформити і намалювати все одразу, після того, як всі бари здоров'я стануть готовими. Оскільки алгоритм є автономним у шейдері, ви також можете додати інстанцію до нього, а потім, також, намалювати всі панелі здоров’я одним інстальованим викликом малювання. Малювання кожної панелі здоров'я на екрані повинно приймати 2 виклики DrawInstanced (...) і бути "божевільним швидким".


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

@JackAidley, будь ласка, будьте більш конкретні, тому що я не вважаю це маскування; смужка прогресу повністю відображається лише на двох трикутниках без відбору проб після першого проходу. У спрайті просто трапляється отвір у ньому та "гарненька" вся справа в кінці. (Це різновиди маски, але не як невід'ємна частина алгоритму?) Спасибі
Jon

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

@JackAidley, але фонового спрайту немає? Веселка малюється, використовуючи лише чотири світові позиції float3; немає УФ-променів, немає "фонового спрайту". Крім того, ви стурбовані тим, що піксельний шейдер заграє, працюючи на деяких крихітних квадратиках? Також RangeMin та RangeMax кліп () більшість цих фрагментів, миттєво.
Джон

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