Використання повноекранного згладжування (FSAA) у Managed DirectX.



Ця стаття є фрагментом книги, повещенной
програмування тривимірної графіки з використанням DirectX for NET 2.0
(Остаточна назва книги поки не визначено). Як середовище
програмування використовується Visual Studio 2005 і мову C #.

Приклади коду знаходяться тут


Ця стаття є фрагментом книги, повещенной програмування тривимірної
графіки з використанням DirectX for NET 2.0 (остаточна назва книги поки
не визначено). У якості середовища програмування використовується Visual Studio
2005 і мову C #.
Книга розрахована на починаючого читача, що має базові
навички роботи з Visual Studio 2005. Передбачається, що читач цілком у
змозі самостійно створити додаток, що використовує GDI +, начебто
найпростішого графічного редактора. Ніяких початкових знань в області
тривимірної графіки не потрібна.
Основний акцент зроблений на якомога більш
зрозуміле виклад матеріалу. Інша особливість книги – активне використання
шейдерів (починаючи з другої глави) замість з які
починають задіюватися починаючи олеее потрібно, однакофіксірованного
конвеєра.


Всі приклади книги написані з використанням Visual
C#
2005 Express і DirectX 9 SDK December
2005, який містить Beta-версію DirectX for
. NET 2.0. До моменту відправки книги до друку вже вийдуть
Release-версії цих продуктів. Щоб не переписувати по кілька разів
текст книги, я намагаюся не звертати уваги на різні проблеми бета версій,
які будуть в наступних версіях. Якщо ж у вас виникнуть
непередбачені труднощі, напишете мені на email (gsaf@sura.ru) і я обов'язково постараюся вам допомогти.


В даний час DirectX for. NET 2.0
поставляється без будь-якої документації. Велика частина інформації про
DirectX for. NET 2.0 була отримана шляхом
дизассемблирования збірки Microsoft.DirectX.dll [2.0.0.0] з
використанням ILDASM і. NET Reflector. Тому я не можу
гарантувати відсутність помилок і неточностей в поточному варіанті книги. Заздалегідь
спасибі за будь-які відгуки, коментарі та побажання.


Особливо цікавить думка з наступних питань:

1. Чи потрібна в книзі аналогія
між FSAA і обробкою аудиосигналов? Або її краще прибрати?

2. Чи слід залишити в книзі
опис панелей управління ATI і NVIDIA?

3. Коректність опису
SSAA і MSAA.

4. Зрозумілість опису процесу
створення форми в конструкторі форм Visual Studio.

5. Чи виникають проблеми при
запуску прикладів книги на комп'ютерах різних конфігурацій.

6. Коректність перекладу
різних термінів і т.д.

7. Зрозумілість викладу
матеріалу. Чи має сенс переписати деякі фрагменти книги простішим
мовою?

Примітка

Над цим фрагментом книги ще не працювали редактори та коректори.
Тому в ньому напевно є безліч стилістичних помилок і "очепяток".


Всі приклади до книги тестувалися на комп'ютері наступної конфігурації:
Pentium 4-2.8C, 1GB RAM, Windows XP Eng Service Pack 2.
Використовувалися відеокарти: ATI Radeon 9700 Pro (з
відключеним AGP), ATI Radeon 9800 XT і
NVIDIA GeForce FX 5900 Ultra з
останніми WHQL-версіями драйверів. Частина прикладів тестувалася на
комп'ютерах з відеокартами NVIDIA GeForce2 MX,
NVIDIA GeForce 6600 GT і ATI Radeon x700 Pro.

Примітка

Були виявлені ексцеси при виконанні деяких прикладів
(Ex14, Ex15, Ex25, Ex26, Ex27, Ex28,
Ex29) на комп'ютерах з відеокартою GeForce2 MX. Проблема
полягає у зникненні зображення при збільшенні розмірів вікна. Причини
такої дивної поведінки програм мені поки не зрозумілі.


Автор висловлює подяку:

q     
Корпорації ATI, яка надала відеокарти ATI
Radeon 9700 Pro і ATI Radeon 9800
XT для тестування прикладів від книги.

q     
Корпорації NVIDIA, що надала відеокарту NVIDIA
GeForce 5900 Ultra.

q     
Корпорації Microsoft, яка надала Microsoft Visual
Studio. NET 2003 Professional і Microsoft Visual Studio 2005 Beta2, а так само Microsoft Windows 2003 Server Standard.

q     
Видавництву BHV, що надало англомовну
літературу по 3D графіці.


Так само автор дякує Ігоря Рибінського (BHV), Юрія Уральського
(NVIDIA), Філіпа Герасимова (NVIDIA), Андрія Крючкова
(Microsoft), Олександра Ложечкін (Microsoft) за консультації та
корисні поради. Окрема подяка висловлюється Геннадію Рігер з
ATI Technologies і Олексію Кряжева (Codemasters Software),
які надали неоціненну допомогу при написанні книги.


 


1.4. Повноекранне згладжування (FSAA)


Запустіть на виконання додаток Ex15 з розділу 1.3.1 (візуалізація
візерунка Серпінського) і уважно розгляньте зображення. Думаю, ви швидко
помітите, що воно виглядає якось дивно – одні фрагменти візерунка чомусь яскравіше,
інші – блідіше. Щоб зрозуміти, з чим це пов'язано необхідно уважно
розглянути збільшений фрагмент візерунку (малюнок 1.46). Неважко помітити, що
відеокарта візуалізує зображення попіксельно. Так як пікселі мають
квадратну форму, на краях лінії утворюються яскраво виражені сходинки. Чим
менше лінія, тим помітніше ці сходинки. Коли ж трикутника наближається до
розміром пікселя, відбувається катастрофа – розмір сходинок стає порівнянним
з розміром трикутника, в результаті чого вони починають істотно спотворювати його
форму (з'являються неіснуючі зубці й т.д.). Це явище отримало назву
ступінчастості зображення (aliasing). Для боротьби з ним використовуються
різні технології повноекранного згладжування (FSAA – Full Scene Antialiasing).


 


Малюнок 1.46. Збільшений візерунок Серпінського


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


Малюнок 1.47. Растерізація відрізка шириною близько одного пікселя.
Кожен квадратик відповідає одному пікселю екрану. Круглі точки в центрі
квадратиків – вибірки, на основі яких визначається колір пікселя.


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


Малюнок 1.61. Растерізація трикутника (на тлі великого білого
полігону) з використанням NVIDIA Quincunx MSSA [15].
Показані тільки вибірки для визначення прозорості пікселя.


Малюнок 1.62. Растерізація трикутника з використанням гібридного
режиму 8xS (SSAA 2x + MSAA 4x) [16]


Спробуйте поекспериментувати з налаштуваннями MSAA на прикладі вищезазначеного додатка
Ex15. Як і на відеокартах ATI, якість зображення
буде помітно поліпшуватися поки кількість субпікселів на піксель не досягне
4-х. Подальше збільшення числа вибірок практично не матиме впливу на
якість зображення.


Для виключення примусового форсування MSAA досить зняти
прапорець Let the application
decide.


1.4.2. Включення MSAA з програми


У попередньому розділі (1.4.1) ви навчилися включати
повноекранне згладжування засобами драйвера. Це дозволило нам значно
підвищити якість візуалізації візерунка Серпінського (приклад Ex15). Тим не
Проте, у цього способу є три істотних недоліки:

1. Далеко не
всі користувачі вміють користуватися панеллю управління драйвера. Не виключена
ймовірність того, що багато частина користувачів будуть використовувати ваше
додаток без FSAA, списуючи ступінчастість країв об'єктів на "Глючность"
вашої програми.

2. Багато
додатки вимагають індивідуальних налаштувань FSAA. Приміром, на відеокарті Radeon
9800XT при використанні MSAA 6x наш додаток
Ex15 демонструє цілком нормальну продуктивність. Проте, запустивши
на цьому ж режимі (MSAA 6x) знаменитий
Doom3, ми отримаємо справжнісіньке слайд-шоу – частота кадрів впаде нижче
10 FPS. Тому якщо користувач захоче використовувати наш додаток
для дослідження візерунка Серпінського, періодично граючи в перервах в
Doom3, то йому доведеться постійно коригувати налаштування в панелі
управління драйвером, від чого він навряд чи буде в захваті.

3. Драйвер
не завжди може коректно включити FSAA, особливо якщо в
додатку використовуються різні просунуті технології візуалізації. Ви
напевно не раз стикалися з іграми, не реагують на зміну настройок
FSAA в панелі управління
драйвера.


 

Примітка

Драйвера NVIDIA ForceWare дозволяють
зіставляти кожному додатку індивідуальні настройки. Однак далеко не всі
користувачі знають про цю можливість. Крім того, при перестановці драйверів
інформація про індивідуальні налаштуваннях втрачається, що дуже незручно [17].


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


Microsoft
DirectX підтримує тільки повноекранне згладжування з
використанням мультісемплінга – корпорація Microsoft, як і ATI,
вважає, що суперсемплінг значно поступається мультісемплінгу в якості при
тієї ж продуктивності, і тому його немає сенсу підтримувати.

Примітка

Драйвера NVIDIA надають
програмісту лазівку, яка дає додатком використовувати SSAA. На відеокартах ATI теж можна
програмно реалізувати SSAA з використанням шейдерів.
Використання SSAA виправдано тільки при візуалізації
текстурованих об'єктів, тому реалізація SSAA в наших поточних
додатках призведе тільки до втрати продуктивності та ускладнення коду
програми. Тому ми розглянемо цю тему в наступних розділах.


Включення MSAA здійснюється шляхом
присвоювання необхідного значення полю MultiSampleType структури Direct3D.PresentParameters:

 public MultiSampleType MultiSampleType {get; set;}
Тип MultiSampleType оголошений наступним чином:
public enum MultiSampleType
{
/ / Мультісемплінг відключений
None = 0,
/ / Немаскируемого режим MSAA. Параметри MSAA задаються з використанням властивості
// PresentParams.MultiSampleQuality
NonMaskable = 1,
/ / Далі йдуть Масковані режими MSAA. Назва констант однозначно визначають режим MSAA.
/ / Зверніть увагу – значення констант збігаються числом вибірок (субпікселів) на піксель.
// MSAA 2x
TwoSamples = 2,
// MSAA 3x
ThreeSamples = 3,
// MSAA 4x
FourSamples = 4,
FiveSamples = 5,
SixSamples = 6,
SevenSamples = 7,
EightSamples = 8,
NineSamples = 9,
TenSamples = 10,
ElevenSamples = 11,
TwelveSamples = 12,
ThirteenSamples = 13,
FourteenSamples = 14,
FifteenSamples = 15,
SixteenSamples = 16,
}

 


За замовчуванням полю PresentParameters.MultiSampleType
присвоєно значення MultiSampleType.None, тобто
мультісемплінг відключений. У DirectX існує
дві великі групи режимів MSAA:

1.       
Масковані [18]
(Maskable) режими MSAA, задающиеся
кількістю вибірок (субпікселів) на піксель.

2.       
Немаскируемого (Non Maskable) режими MSAA,
які нумеруються цілими числами, починаючи з 2.


Кожен спосіб має свої переваги і недоліки. Перевагою першого
способу є прозорість завдання якості MSAA, яке добре
корелює з кількістю вибірок на піксель. Для включення, наприклад,
MSAA 4x нам необхідно просто присвоїти полю PresentParameters.MultiSampleType
значення MultiSampleType.FourSamples:

Лістинг
1.24

presentParams = new PresentParameters();
presentParams.IsWindowed = true;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
presentParams.SwapEffect = SwapEffect.Discard;
/ / Включаємо MSAA 4x
presentParams.MultiSampleType = MultiSampleType.FourSamples;

device = new Device(0, DeviceType.Hardware, this.Handle,
CreateFlags.HardwareVertexProcessing, presentParams);


 

Примітка

Установки параметрів MSAA в панелі управління драйвера мають
пріоритет перед установками програми. Наприклад, якщо в драйвері включений режим
MSAA 2x, а додаток намагається створити пристрій,
використовує MSAA 4x, то в підсумку буде створено пристрій,
використовує режим MSAA 2x.


Як видно все дуже просто, за винятком одного нюансу: якщо відеокарта не
підтримує MSAA 4x, то при створенні пристрою командою
new Device додаток аварійно завершить роботу з
винятком Direct3D.InvalidCallException. Для вирішення цієї проблеми можна
помістити оператор створення пристрою в блок try … catch,
передбачивши обробник виключення Direct3D.InvalidCallException, що створює
пристрій з відключеним MSAA:

Лістинг
1.25


presentParams.MultiSampleType = MultiSampleType.FourSamples;

try
{
device = new Device(0, DeviceType.Hardware, this.Handle,
CreateFlags.HardwareVertexProcessing, presentParams);
}
catch (InvalidCallException)
{
/ / Якщо не вдалося створити пристрій з MSAA 4x, відключаємо MSAA
presentParams.MultiSampleType = MultiSampleType.None;
device = new Device(0, DeviceType.Hardware, this.Handle,
CreateFlags.HardwareVertexProcessing, presentParams);
}


 


Щоправда, таке рішення важко назвати задовільним, оскільки даний код
завжди буде відключати MSAA на будь-який відеокарті, що не підтримує
MSAA 4x. Іншими словами, програма буде працювати за принципом або
відразу все, або нічого. Адже цілком може виявитися, що відеокарта, не
підтримуюча режим MSAA 4x, підтримує MSAA 2x
або MSAA 6x, або взагалі який-небудь екзотичний режим
зразок MSAA 3x.


Так як наша програма не вимоглива до ресурсів відеопідсистеми, ми можемо
обрати таку просту стратегію вибору режиму MSAA – програма
планомірно перебирає всі режими MSAA від MSAA 16x до
MSAA 2x, намагаючись створити пристрій. Якщо ж усі спроби створення
пристрою зазнають краху, програма створить пристрій, що не використовує
MSAA. Таким чином, програма завжди буде використовувати самий
високоякісний режим MSAA. Цей підхід демонструється у прикладі
Ex25 (лістинг 1.26).

Лістинг
1.26

 private void MainForm_Load (object sender, EventArgs e)
{
SetStyle (ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
MinimumSize = new System.Drawing.Size (Width – ClientSize.Width + 1,
Height – ClientSize.Height + 1);

presentParams = new PresentParameters();
presentParams.IsWindowed = true;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Heig

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*