Steps3d - tutorials - моделювання глибини різкості

Одним з простих і досить красивих спецефектів, які можна легко додати до своєї програми є так звана глибина резкозть (depth-of-field).

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

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

За законами оптики існує співвідношення між відстанню від лінзи до "премніка" і відстанню від лінзи до об'єкту, при котрому об'єкт буде у фокусі.

Рис 1. Робота найпростішого об'єктиву.

Це відношення задається наступній формулою, тут через u і v позначені відстані від лінзи до "приймача" і об'єкта, а через f - т.зв. фокусноео відстань об'єктива.

Якщо ми розташуємо поверхню на відстані d від об'єктива, то точок на "приймачі" буде відповідати коло на цій площині - так низваемий Circle Of Confusion (COC).

Існує формула для отримання діаметра COC за параметрами об'єктива f. a і фокусної відстані dfocus.

Однак для застосування на практиці ця формула досить складна і ми длаее будемо спиратися на набагато більш простий підхід, розглянутий в книгах ShaderX 2 і ShaderX 3.

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

Це дозволяє прямо під фрагментного шейдера по z -коордінате (в системі координат спостерігача) обчислити ступінь розмитості для даного фрагмента (blur) і записати її в альфа-канал виходить зображення.

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

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

Рис 2. Використання билинейной інтерполяції.

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

Найпростіший варіант полягає в ступені розмиття (blur) з альфа-каналу вихідного зображення для управління розміром Адра фільтра - радіус фільтра задається як blur * radiusScale.

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

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

Нижче наводиться відповідна прогрммная реалізація.

Нижче наводиться повний вихідний код на С ++ для прикладу, який демонструє використання даного ефекту.

Схожі статті