Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Вибракування оклюзії

У системі 3D-рендерінгу відсічення оклюзії — це процес видалення прихованої геометрії.

На цій сторінці ви дізнаєтеся:

  • Які переваги та підводні камені вибракування оклюзії.

  • Як налаштувати відбір оклюзії в Godot.

  • Усунення поширених проблем з оклюзійним відбором.

Дивись також

Ви можете побачити, як працює відбір оклюзії в дії, використовуючи демонстраційний проект LOD Occlusion Culling and Mesh <https://github.com/godotengine/godot-demo-projects/tree/master/3d/occlusion_culling_mesh_lod>`__.

Навіщо використовувати оклюзію

У цьому прикладі сцени з сотнями кімнат, розташованих одна біля одної, динамічний об’єкт (червона сфера) приховано за стіною в освітленій кімнаті (ліворуч від дверей):

Приклад сцени з макетом, зручним для вибракування оклюзії

Приклад сцени з макетом, зручним для вибракування оклюзії

Якщо вибракування оклюзії вимкнено, усі кімнати за освітленою кімнатою мають бути візуалізовані. Динамічний об’єкт також потрібно відобразити:

Приклад сцени з вимкненим блокуванням оклюзії (каркас)

Приклад сцени з вибракуванням оклюзії вимкнено (каркас)

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

Приклад сцени з увімкненим блокуванням оклюзії (каркас)

Приклад сцени з увімкненим блокуванням оклюзії (каркас)

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

Примітка

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

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

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

Як працює вибракування оклюзії в Godot

Примітка

"окклюдер" відноситься до форми, яка блокує огляд, тоді як "окклюдер" стосується прихованого об'єкта.

У Godot відбір оклюзії працює шляхом растеризації геометрії оклюдера сцени до буфера низької роздільної здатності на ЦП. Це робиться за допомогою програмної бібліотеки трасування променів Embree.

Далі механізм використовує цей буфер із низькою роздільною здатністю, щоб перевірити AABB оклюдера щодо форм оклюдера. AABB оклюдії має бути повністю закрита формою оклюдера, яку потрібно вилучити.

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

Налаштування вибракування оклюзії

Першим кроком до використання відсіку оклюзії є ввімкнення параметра проекту Відтворення > **Відсікання перегородок > Використовувати відсіювання перекриття. (Переконайтеся, що перемикач Додатково увімкнено в діалоговому вікні налаштувань проекту, щоб мати змогу його побачити.)

Цей параметр проекту застосовується негайно, тому вам не потрібно перезапускати редактор.

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

Існує два способи налаштування оклюдерів у сцені:

Встановлення оклюдерів вручну

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

Увімкнувши згадане вище налаштування проекту відбору оклюзії, додайте вузол OccluderInstance3D до сцени, що містить ваш 3D-рівень. Виберіть вузол OccluderInstance3D, а потім виберіть тип блокувальника, який потрібно додати у властивості Occluder:

  • QuadOccluder3D (одна площина)

  • BoxOccluder3D (кубоподібний)

  • SphereOccluder3D (оклюдер у формі сфери)

  • PolygonOccluder3D (2D-багатокутник із скільки завгодно точок)

Існує також ArrayOccluder3D, точки якого не можна змінити в редакторі, але можуть бути корисними для процедурної генерації зі сценарію.

Попередній перегляд оклюзії

Ви можете ввімкнути режим малювання налагодження, щоб переглянути, що насправді «бачить» оклюзія. У верхньому лівому куті вікна перегляду 3D-редактора клацніть кнопку Перспектива (або Ортогональна залежно від поточного режиму камери), а потім виберіть Відображення розширеного… > Буфер відсікання загородження. Це відобразить буфер із низькою роздільною здатністю, який використовується механізмом для відсічення оклюзії.

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

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

Щоб увімкнути відсічення оклюзії під час виконання, встановіть use_occlusion_culling на кореневому вікні перегляду таким чином:

get_tree().root.use_occlusion_culling = true

Перемикання відсіку оклюзії під час виконання корисно для порівняння продуктивності запущеного проекту.

Міркування продуктивності

Створюйте рівні, щоб скористатися перевагами оклюзійного відбору

Це найважливіша вказівка. Хороший дизайн рівнів — це не лише вимоги ігрового процесу; його також слід будувати з урахуванням оклюзії.

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

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

Уникайте переміщення вузлів OccluderInstance3D під час гри

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

Перемикання видимості OccluderInstance3D (або видимості одного з батьків) не таке дороге, оскільки оновлення має відбуватися лише один раз (а не постійно).

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

Якщо вам обов’язково потрібно перемістити вузол OccluderInstance3D під час гри, використовуйте для нього примітивну форму Occluder3D замість складної запеченої форми.

Використовуйте найпростіші можливі форми оклюдерів

Якщо ви помітили низьку продуктивність або заїкання в складних 3D-сценах, це може означати, що ЦП перевантажено в результаті візуалізації детальних окклюдерів. Виберіть вузол OccluderInstance3D, збільште властивість Bake > Simplification, а потім знову запікайте оклюдери.

Пам’ятайте, що значення спрощення має бути розумним. Значення, які є занадто високими для геометрії рівня, можуть спричинити неправильне відсічення оклюзії, як у Мій окклюд вибраковується, коли цього не повинно бути.

Якщо це все ще не призводить до достатньо низького використання ЦП, ви можете спробувати відкоригувати параметр проекту Відображення > Відсічення перекриття > Якість збірки BVH і/або зменшити значення Візуалізація > Відсікання перекриття > Промені перекриття на потік. Вам потрібно буде ввімкнути перемикач Додатково у діалоговому вікні налаштувань проекту, щоб побачити ці налаштування.

Вирішення проблем

Мій оклюд не вибраковується, коли це повинно бути

З боку оклюдера:

По-перше, ще раз переконайтеся, що властивість Bake > Cull Mask в OccluderInstance3D налаштовано на дозвіл запікання сіток, які ви хочете. Рівень видимості вузлів MeshInstance3D має бути присутнім у масці відбракування, щоб сітка була включена до запікання.

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

Нарешті, пам’ятайте, що вузли MultiMeshInstance3D, GPUParticles3D, CPUParticles3D і CSG не враховуються під час запікання оклюдерів. Як обхідний шлях ви можете додати для них вузли OccluderInstance3D вручну.

З боку оклюдії:

Переконайтеся, що Extra Cull Margin установлено якомога менше (зазвичай воно має бути 0.0), а Ignore Occlusion Culling вимкнено в розділі GeometryInstance3D об’єкта.

Також перевірте розмір AABB (який позначається помаранчевою рамкою під час вибору вузла). Ця обмежувальна рамка, вирівняна за віссю, має бути повністю перекрита формами оклюдера, щоб оклюдію було приховано.

Мій окклюд вибраковується, коли цього не повинно бути

Найімовірнішою причиною цього є те, що об’єкти, які були включені до запікання оклюдера, були переміщені після запікання оклюдерів. Наприклад, це може статися під час переміщення геометрії рівня або зміни його макета. Щоб виправити це, виберіть вузол OccluderInstance3D і знову запікайте оклюдери.

Це також може статися через те, що динамічні об’єкти були включені в пакет, хоча це не повинно бути. Використовуйте occlusion culling debug draw mode, щоб шукати форми окклюдерів, яких не повинно бути, а потім adjust the bake cull mask accordingly.

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

В крайньому випадку, ви можете ввімкнути властивість Ignore Occlusion Culling для occludee. Це зведе нанівець покращення продуктивності відсіювання оклюзії для цього об’єкта, але має сенс робити це для об’єктів, які ніколи не будуть відбраковані (наприклад, модель перегляду від першої особи).