Ад візуалізації 1.1 - Книга 1: Огляд



Недолік знань іноді може виявитися перевагою, тому що ви наївно говорите собі: «Пфф… хіба це складно?» і просто занурюєтеся в проблему з головою. Я почав цю статтю з міркування: «Хм… Що ж таке Draw Call?». За час «5-ти хвилинного» дослідження я так і не знайшов задовольняє мене пояснення. Я перевірив годинник і, так як до сну залишалося ще 30 хвилин, сказав…
Пфф… Хіба це складно самостійно написати?
… і просто почав. Це було два місяці тому і з тих пір я безперервно читав, писав і ставив багато питань.

Це було найскладніше і низькорівневе дослідження, яке я коли-небудь робив, і для мене непрограммиста це був кошмар складається з «так, але в цьому особливому випадку...» і «залежить від реалізації API...». Це був мій особистий пекло візуалізації, але я пройшов через нього і приніс щось з собою: Чотири книги, кожна з яких являє собою спробу пояснити одну з частин візуалізації з точки зору художника. Я сподіваюся, що вам сподобається.



Сьогодні художники повинні бути добре обізнаними: З точки зору комп'ютера ваші ігрові ресурси — це всього лише набори вершин і даних текстур. Перетворення цих сирих даних в зображення «наступного покоління» переважно робиться вашим центральним процесором (CPU) і графічним процесором (GPU).

1. Копіювання даних в оперативну пам'ять для швидкого доступу

Спершу всі необхідні дані завантажуються з жорсткого диска (HDD) в оперативну пам'ять (RAM) для швидкого доступу. Після цього потрібні полігональні сітки і текстури завантажуються в пам'ять графічної карти (VRAM). Це робиться тому, що графічна карта має значно більш швидкий доступ до VRAM і в більшості випадків не має доступу до ПАМ'ЯТІ.



До того як сторона візуалізації може приступити до роботи, CPU задає деякі глобальні значення, які описують те, що полігональна сітка повинна бути відображена. Цей набір значень називається Render State.

2. Установка Render State значень

Render State — це деякий глобальне визначення того, полігональна сітка повинна бути візуалізована. Вона містить в собі інформацію про:
«вершинних і піксельних шейдери, текстурах, матеріалах, освітленні, прозорості ітп. [...]» [Real-Time Rendering: стор. 711]
Важливо, кожна полігональна сітка, яку CPU передає в GPU для малювання, буде відображена з цими умовами! Ви можете малювати камінь, стілець або меч — всі вони будуть використовувати однакові параметри візуалізації (такі як матеріал), якщо ви не зміните Render State до відображення наступної сітки.



Після того, як підготовка буде закінчена, CPU нарешті може звернутися до GPU і сказати, що треба малювати. Ця команда відома як Draw Call.

3. Draw Call

Draw Call — це команда відображення однією полігональної сітки. Вона надається центральним процесором. Її отримує графічний процесор. Команда вказує тільки на полігональну сітку, яку треба відобразити, і не містить ніякої інформації про матеріал, так як вона вже визначена через установку Render State. У цей момент полігональна сітка знаходиться в пам'яті графічної карти (VRAM).



Після того, як команда віддана, GPU бере параметри Render State'а (матеріал, текстуру, шейдер, ...) і всі дані про вершинах і перетворює цю інформацію з допомогою деякою магії в прекрасні (сподіваюся) пікселі на вашому екрані. Цей процес перетворення називається Pipeline'ом.

4. Pipeline

Як я говорив вище, ігрові ресурси — це, в деякому роді, просто набори вершин і даних текстур. Щоб перетворити їх у карколомну картинку, графічній карті треба створити трикутники з вершин, обчислити їх освітленість, відобразити на них пікселі текстури і багато чого ще. Ці дії називаються станами. Станами Pipeline'а.

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


Даний приклад Pipeline'а вкрай спрощено і повинен трактуватися лише як дає загальне уявлення. Я спробував зобразити його настільки добре, наскільки зміг, але, як у непрограммиста, у мене є проблеми з розумінням, коли приклад стає таким простим, що веде вас у неправильному напрямку. Тому, будь ласка, не приймайте всерйоз і подивіться всі інші чудові джерела, які я навів у кінці статті. Чи не соромтеся написати мені листа, твіт або повідомлення у фейсбуці, щоб поліпшити анімацію/пояснення. :)


Ось приклад з єдиним ядром GPU:


Візуалізація — це просто виконання величезного числа маленьких завдань, таких як обчислення чого-небудь для тисяч вершин або малювання мільйонів пікселів на екрані. Як мінімум (добре б) у 30 кадрах в секунду.

Важливо мати можливість обчислювати ці речі одночасно, а не кожну вершину/піксель одну за одною. У старі добрі часи, процесори мали тільки одне ядро і не було графічного прискорення — вони могли робити тільки одну річ в один момент часу. Гри виглядали як… ретро. Сучасні CPU мають 6-8 ядер, тоді як GPU містять кілька тисяч (вони не настільки складні, як CPU-ядра, але вони ідеальні для пропускання через себе величезного кол-ва вершинних і піксельних даних).

Коли дані (наприклад купа вершин) потрапляють на етап Pipeline'а, робота з трансформації точок/пікселів розділяється між декількома ядрами так, щоб більшість цих маленьких елементів формувалася паралельно у велику картину:



Тепер ми знаємо про те, що GPU може обробляти всі паралельно. Але як щодо комунікації між CPU і GPU? Чекає CPU того моменту, коли GPU закінчить свою роботу і зможе отримувати нові команди?



— Ні!
На щастя, ні! Причина полягає в тому, що така комунікація буде утворювати «пляшкові горлечка» (наприклад, коли CPU не може доставляти команди досить швидко) і зробить паралельну роботу неможливою. Рішення — це список, у який команди можуть додаватися CPU і читатися GPU незалежно один від одного! Такий список зветься буфером команд.

5. Буфер команд

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



Тим не менш команди можуть бути різними. Один з прикладів — Draw Call, іншим може бути зміна Render State'а.

На цьому перша книга закінчується. Тепер ви повинні мати загальне уявлення про даних ігрових ресурсів, Draw Call'ах, Render State'ах і взаємодії між CPU і GPU.

Кінець

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.