Пекло рендера v.2.0. Книга перша. Огляд

Відсебятина

Натрапив рік тому на ряд дуже цікавих статтею пана Simon. Саймон дуже любить розбирати те, як створюються ігри, а саме графічні рішення того чи іншого елементу в грі. Починаючи від колів на гранях плит, закінчуючи тим, як реалізовано відрізання шматків від об'єктів. Але особливо цікавим видається його ряд статей під загальною назвою «Пекло рендера» (Render Hell), в якому він детально розбирає, як на рівні заліза (та й програмно теж) відбувається рендер 3D-об'єктів.

Переклад вільний. Його я робив для себе, щоб в якийсь момент я міг повернутися і прочитати те, що міг не вловити з першого разу або просто забути.

Ну що, почнемо?

Книга перша. Огляд

(оригінал книги тут)

Хлопці, тримайтеся: з точки зору ПК, ваші роботи в 3D - ніщо інше, як просто список вертексів і текстур. Всі ці дані конвертуються в картинку Некст-гена, і в основному це робиться за допомогою процесора системи (CPU) і графічного процесора (GPU).

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

Your browser does not support HTML5 video.

Якщо текстура більше не потрібна (після вивантаження у VRAM), вона може бути вилучена з оперативної пам'яті RAM (Але ви повинні бути впевнені, що вона вам більше не знадобиться найближчим часом, тому що вивантаження з HDD займає дуже великий час).

Міші повинні залишатися в RAM, тому що швидше за все процесор захоче мати доступ до них, наприклад, для визначення зіткнення.

Your browser does not support HTML5 video.

Доповнено другою редакцією

Тепер вся інформація на відеокарті (в оперативці відеокарти - VRAM). Але швидкість перекладу з VRAM до GPU все ще низька. GPU може обробити набагато більше інформації, ніж до нього надходить.

Отже, інженери помістили маленький об'єм пам'яті прямо в сам відеопроцесор (GPU) і назвали цю пам'ять кеш (Cache). Це невеликий обсяг пам'яті, тому що це неймовірно дорого - поміщати великий обсяг пам'яті безпосередньо в процесор. GPU копіює в кеш тільки те, що йому зараз необхідно і малими порціями.

Your browser does not support HTML5 video.

Наша скопійована інформація тепер лежить у кеш 2-го рівня (L2 Cache). В основному, це маленький обсяг пам'яті (наприклад, на NVDIA GM204 обсяг становить 2048 кбайт), який встановлений в GPU і доступний для читання набагато швидше, ніж VRAM.

Але навіть цього не вистачає, щоб працювати ефективно! Тому є ще маленький кеш 1-го рівня (L1 Cache). На NVIDIA GM204 Він становить 384Кбайт, який доступний не тільки для GPU, а й найближчих співпроцесорів.

Your browser does not support HTML5 video.

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

Після чого ці результати поміщаються назад у L1/L2/VRAM, щоб звільнити місце для нових розрахунків. Ви, як програміст, зазвичай не повинні турбуватися на рахунок їх розрахунків.

Чому це все працює без проблем? Як сказано вище, це все про час доступу. І якщо ми будемо порівнювати час доступу, наприклад, HDD і L1 Cache, то між ними чорна діра - така ось різниця. Можна так само почитати про точні цифри затримки за цим посиланням: gist.github.com/hellerbarde/2843375

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

Render State

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

І ВАЖЛИВО РОЗУМІТИ: Кожен , який CPU надсилає до GPU для малювання, буде впорядковано під тими параметрами (Render State), які були вказані до нього. Тобто, ви можете відрендерити меч, камінь, стілець і машину - всі вони будуть рендеритися під однією текстурою, якщо перед кожним з цих об'єктів не вказувати параметри відмальовки RenderState.

Your browser does not support HTML5 video.

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

DrawCall

Це команда CPU для GPU відкинути один . Команда вказує конкретний  для рендера і не містить жодної інформації про матеріали та іншого - це все вказується в Render State.

Your browser does not support HTML5 video.

 вже завантажений в пам'ять VRAM.

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

Pipeline

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

Ці дії називаються Pipeline States. Найчастіше велика частина цієї роботи здійснюється за допомогою GPU відеокарти. Але іноді, наприклад, створення трикутників здійснюється за допомогою інших со-процесорів відеокарти.

Доповнено другою редакцією

Цей приклад надзвичайно спрощений і повинен розглядатися тільки як приблизний огляд або «логічний» конвеєр: кожен трикутник/піксель проходить логічні кроки, але те, що насправді відбувається, трохи відрізняється від описаного.

Ось приклад кроків, які залізо робить для одного трикутника:

Your browser does not support HTML5 video.

Рендер картинки відбувається шляхом вирішення десятків, сотень тисяч подібних завдань, відмальовування мільйонів пікселів на екрані. І все це повинно (я сподіваюся) вкладатися як мінімум в 30 кадрів в секунду.

Сучасні процесори мають по 6-8 ядер, коли як відеопроцесори мають кілька тисяч ядер (нехай і не таких потужних, як CPU, але досить потужних. щоб обробляти купку вертексів та інших даних).

Книга № 2 присвячена деталям організації високого і низького рівня в графічному процесорі.

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

Your browser does not support HTML5 video.

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

NO!

На щастя, ні! Причиною тому є слабка ланка, яка утворюється, як горлечко в пляшці, коли CPU не здатний відправити наступні завдання досить швидко. Рішенням є аркуш команд, в якій CPU додає команди для GPU, поки той обробляє попередню команду. Цей аркуш називається Command Buffer.

Command Buffer

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

Your browser does not support HTML5 video.

До речі, є різні команди. Наприклад, одна команда може бути DrawCall, друга - зміна RenderState на нові параметри.

Ну, загалом, це перша книга. Тепер у вас є уявлення про те, як інформація рендериться, викликаються Draw Calls, Render State, і взаємодіють між собою CPU і GPU.

The End.

Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.

Продовжувати переклади книжок?

93.99% Так 219

6.01% Немає 14

Проголосували 233 користувачі. Утрималися 19 користувачів.

COM_SPPAGEBUILDER_NO_ITEMS_FOUND