Затінення Toon / Cel із змінною шириною лінії?


15

Я бачу кілька широких підходів до того, як робити затінення чела:

  1. Копіювання та розширення моделі з перевернутими нормалями (для мене не варіант)
  2. Фільтр / шейдер фільтра Собеля підходить до виявлення краю
  3. Буфер трафарету підходить до виявлення ребер
  4. Шейдер для геометрії (або вершини), що обчислює нормали обличчя та ребер

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

Що робити, якщо мені не потрібно піксельне освітлення на моїх місцевостях? (І я, мабуть, не буду, оскільки я планую використовувати освітлення / затінення на основі осередків на основі вершин або текстурних мап.) Чи краще мені буде дотримуватися підходу типу геометрії, чи замість цього підходитимуть до підходу простору / фрагмента екрану щоб зробити речі простішими? Якщо так, то як би я отримав "чорнило" пагорбів у межах сітчастого силуету, а не лише контур усієї сітки (без "чорнильних" деталей всередині цього контуру? (Підказки контуру , складки AKA ).

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

Чого я хочу - різної товщини лінії з нав'язливими лініями всередині силуету ...

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

Чого я не хочу ...

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


EDIT: Подальші дослідження виявили наступне ...

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

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

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

Це залишає фрагменти шейдерних зображень-простору підходів. Комплексна обчислюваність зводиться до кількості фрагментів, а не до числа вершин (у моєму випадку це на 10-100x менше операцій, ніж мені довелося б робити в шейдері геометрії). Для цього потрібно більше одного пропуску візуалізації, щоб генерувати g-буфер (що складається з звичайного буфера і необов'язково також буфера глибини), до якого ми можемо застосувати фільтри розриву (наприклад, оператор Sobel). Розрив глибини - це те, що дає змогу надати контури та складки. Моя єдина суперечка при такому підході - це неможливість забезпечити більш точний контроль над заглибленими ширинами краю, хоча за допомогою правильного алгоритму в фрагменті шейдера я впевнений, що це було б можливим.

Тож питання тепер стає більш конкретним: як саме я б пішов про отримання змінної ширини краю, особливо на зовнішньому силуеті, у фрагменті шейдера?


Різновидна товщина лінії - особливість геометричного підходу. Неможливо ефективно отримати це іншим способом. Оскільки ви цього хочете, я не вважаю, що піксельні шейдери є "більш ефективним методом": кількість пікселів, які потрібно шукати = (line_thickness * 2 + 1) ^ 2 - 1. Це в основному означає, що ваш шейдер після обробки буде набагато повільніше (угадка: 10x) повільніше, якщо макс. ширина лінії дорівнює 2. Просто відкиньте попереднє судження і спробуйте підхід з геометрії шейдерів.
snake5

@ snake5 Ви чесно пропонуєте мені пройти 150 мільйонів вершин за оновлення візуалізації (приблизно 25 мільйонів з вилученням перегляду), в GS? Я не дуже купую це, але дякую за внесок. Поверніться до того, що я говорив вище про кількість вершин і складність. Навіть з вашою 10-кратною фігурою шейдер фрагмента хоч би намалював рівне і, ймовірно, зробить пекло набагато краще.
Інженер

25 мільйонів вершин (лінійне зчитування / запис) проти 23 мільйонів текстурних зразків (досить погано кешована пам'ять читання + декомпресія даних цільового відображення) @ 1280x720. Обмежити / зменшити кількість вершин, до речі, набагато простіше. Особливо в наші дні, коли великі популярності набувають великі монітори (1920x1080 +) та мультимоніторні установки.
snake5

як щодо використання того ж алгоритму, що і генеруючи червоні контури, а потім витончення / зростаючі лінії на основі їх глибини?
Ali1S232

@Gajoo, Як я вже говорив у питанні, справа не лише в силуеті. На першому зображенні відзначте настирливі лінії за плечима дівчини. Ці функції є підходом перевернутого нормалу і виконують роль сугестивних контурів / складок. Мені ж потрібно.
Інженер

Відповіді:


4

Я вирішив застосувати фрагмент шейдерного підходу через фільтрацію розриву буфера глибини. Причини цього:

  1. Кількість вершин у світі дуже-дуже велика через величезні відстані в огляді, навіть із сіткою LoD;
  2. Я роблю ряд інших операцій з фрагментацією шейдерів, таких як DoF blur, які можуть отримати користь одними й тими ж структурами (коробчаста або гауссова вибірка / фільтрування) за один прохід.

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


Я думаю, що перехід з нормальними нормами дасть кращі результати, якщо ви отримаєте плоскі норми. Ви можете змінити ширину лінії, взявши зразки далі один від одного.
Grieverheart

@Grieverheart Це прийнята відповідь, тому що метод, який я використовую, працює чудово. Спасибі.
Інженер

0

Насправді є дуже легке загальне рішення, якщо ви можете використовувати ефект після. Чудова річ, що не важливо, наскільки високий ваш полі-кількість. Візуалізуйте карту глибини у вигляді сірого масштабу, а потім створіть крапку в потрібному кольорі лінії, коли контраст між двома сусідніми пікселями перевищує порогове значення. Ви можете збільшити крапку відповідно до контрасту та / або рівня світла зображення, яке ви надали.

Я винайшов алгоритм ToonShader ще в 2000/2001 році, ще до того французького чувака, який створив це рішення. Шахта була заснована на фактичній геометрії матеріалів. Тоді в основному є два способи зробити це: 1. Подивіться на нормали, якщо нормалі дві площини, з'єднані з лінією, звернені в бік і до камери, візьміть цю лінію, ви можете використовувати глибину, освітлення тощо як сигнали для ліній. 2. Подивіться на виведені геометрії (тому після перспективного перетворення) Візьміть кожен відрізок рядка, якщо вершини з'єднувальних площин знаходяться на одній стороні цього відрізка рядка, ви виведете лінію .. Ви можете зробити те ж саме для товщини лінії, як у метод 1. 3. Ви могли скласти комбінації цих трьох прийомів, але я згадав перший, тому що ви вказали величезний полі-кількість.

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