Steps3D - Tutorials - Soft Particles

Однією з добре розпиарених можливостей DX10 є так звані м'які частинки (soft particles ). Однак насправді для реалізації цього ефекту цілком достатньо підтримки SM3 і вони чудово робляться на OpenGL (не вимагаючи при цьому дрібном'якої і убогої ві$ти).

Розглянемо що саме розуміється під " м'якими " частинками й у чому полягає їхню відмінність від традиційних частинок.

Для представлення звичайних частинок використовуються так звані bilboard 'и - грані, завжди повернені до камери. Наbillboardзазвичай натягується текстура. OpenGL надає хорошу підтримку таких частинок через розширення ARB_point_sprite та ARB_point_parameters.

Поки що ми працюємо з великою кількістю маленьких частинок особливих проблем не помітно. Але при використанні невеликого числа великих частинок стає помітно, що частинки представленіbillboard'ами - при перетиніbillboardі грані відбувається її часткове відсікання (див. рис 1).

Рис 1. Артефакти, що виникають під час використання традиційних частинок.

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

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

М'які частинки якраз і спираються на уявлення частинок як деяких обсягів з туманом - у цьому випадку враховується яка саме частина цього обсягу видно і подібних різких стрибків невідбувається.

Рис 2. Сцена із рис. 1 але з використанням м'яких частинок.

Рис 3. Відмінність м'якої частки від звичайної.

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

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

При цьому можливі два випадки.

1. Промінь "протикає" об'ємну частинку наскрізь і просто беремо прозорість із текстури (рис 4.a).

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

Таким чином, у тих місцях, деbillboadйде за об'єкти сцени відбувається плавне "зникнення" частинки (замість різкого стрибка).

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

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

Нижче наводиться відповідний фрагментний шейдер та скріншот, отриманий під час його використання.

Мал. 5. Скріншоти.

Нижче наводиться повний вихідний код С++, використаний для рендерингу сцени з рис. 2 та 5.

зацією посиланням можна завантажити весь вихідний код до цієї статті. Також доступні для завантаження відкомпільовані версії для Windows і Linux.