Чому піксельні шейдери не дозволяють нам читати безпосередньо з фреймбуфера або глибини буфера?


18

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

Чому і OpenGL, і DirectX не дозволяють мені це робити? Я очікував, що буде якесь апаратне обмеження, але альфа-змішування використовує колір у кадрі буфера для обчислення сумішей, а Z-тест відбирає буфер глибини в поточному місці. Чому б просто не викрити ці значення нам безпосередньо? Чи можна сподіватися побачити це в майбутньому?

Відповіді:


20

Це є апаратним обмеженням. Шейдер фрагмента є частиною програмованого конвеєра, але остаточне поєднання кольорів із цільовим буфером на даний момент не програмується у широкодоступному / товарному обладнання (це налаштовується за допомогою станів змішування, але ви не можете писати довільно код, який замінює вбудовані операції суміші GPU.

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

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

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

Але, можливо, також може відбуватися річ із витратами та вигодами. Якщо зробити цей аспект програмованого GPU трубопровідним, дещо ускладнить конструкцію мікросхеми, і потреба / попит у читанні буфера призначення є порівняно низькою порівняно з іншими функціями.


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

4

Хоча це дратує, це дозволяє виробникам апаратних засобів гнучкість оптимізувати процес візуалізації численними та прозорими способами.

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


4

Піксельний шейдер не може читати з буферів кольорів та глибин, оскільки:

Пікселі A і B можуть бути затінені точно в той самий момент в апаратному забезпеченні, хоча B в кінцевому підсумку відображається поверх ("після") пікселя A.

Якщо ви зробили це таким чином, щоб обладнання гарантувало відтінок A перед B, то частини апаратних засобів сиділи б навколо, нічого не роблячи, поки A заштриховано, а тоді частини апаратури сиділи б, не роблячи нічого, тоді як B - затіненим.

У гіршому випадку можна уявити, що всі пікселі, які ви затінюєте, відображаються один на одного, а тисячі і тисячі потоків GPU - усі, крім одного, сидять у режимі очікування. Цей один потік терпляче відтіняє піксель А, потім В, потім С ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.