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

18

Позволить мне сэмплировать кадровый буфер или буфер глубины в пиксельном шейдере было бы чрезвычайно полезной функцией. Даже возможность узнать глубину или цвет того, что находится за текущим пикселем, была бы полезна.

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

Hannesh
источник

Ответы:

20

Это является аппаратным ограничением. Фрагментный шейдер является частью программируемого конвейера, но окончательное смешение цветов с целевым буфером (ами) на данный момент не программируется в широко доступном / стандартном оборудовании (его можно настроить с помощью состояний смешивания, но вы не можете писать произвольно код, который заменяет встроенные операции смешивания графических процессоров).

Причина, по которой аппаратное обеспечение не создано для этого, вероятно, связана с тем, что графические процессоры в основном параллельны; они обрабатывают много фрагментов одновременно. Некоторые из этих фрагментов могут в конечном итоге взаимодействовать друг с другом в целевых буферах, но из-за асинхронного характера обработки фрагментов невозможно узнать, как до тех пор, пока фрагмент не будет обработан и не будет получен окончательный цвет ... который выиграл не всегда бывает детерминированным.

Тот факт, что пиксель A будет отставать от пикселя B в последнем кадре, не означает, что пиксель A всегда будет завершать обработку фрагмента и записываться в место назначения до B, особенно в нескольких кадрах рендеринга. Таким образом, значение, считываемое из буфера назначения во время обработки пикселя B, не всегда будет пикселем A - иногда это будут чистые значения.

Поэтому я подозреваю, что запрет на прямое чтение целевого буфера на этапе фрагмента имеет гораздо большее отношение к тому, чтобы не дать программисту шейдера выстрелить себе в ногу, получив потенциально недетерминированные результаты при этом чтении, чем из-за каких-либо фактических технических ограничений в создании стадии смешивания полностью. программируемый. Благодаря строгому контролю за операциями чтения (например, тестом глубины), графический процессор гарантирует, что операции, выполняемые со значением чтения, имеют какой-то смысл.

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


источник
Просто, чтобы расширить это, историческая причина, почему доступ кадрового буфера был медленным, состоит в том, что инструкции очень сильно конвейерны. Получение доступа к данному пикселю кадрового буфера будет включать в себя остановку текущего конвейера до тех пор, пока все другие конвейеры не будут сброшены для завершения любого рендеринга, относящегося к запрашиваемому пикселю. Даже в нечетном случае полностью непараллельного графического процессора вы все равно будете очищать весь конвейер для каждого запроса, что является плохой идеей. Без сомнения, сейчас все немного по-другому в мире программируемого оборудования, но я ожидаю, что аналогичный принцип применим.
Kylotan,
4

Это раздражает, но позволяет производителям оборудования гибко оптимизировать процесс рендеринга многочисленными и прозрачными способами.

Например, аппаратное обеспечение PowerVR (определенно использовавшееся в прошлом, долгое время не использовавшее) ждет, пока будет представлена ​​вся воспроизводимая сцена, затем выполняет автоматическую сортировку по глубине с использованием алгоритма рисования и на самом деле не нужно генерировать буфер глубины. Это делит экран на плитки и рендерит каждую по очереди.

Роджер Перкинс
источник
4

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

Пиксели A и B могут быть закрашены в один и тот же момент аппаратно, хотя B, в конечном счете, визуализируется поверх (после) пикселя A.

Если вы сделали так, чтобы аппаратное обеспечение гарантированно затенило А перед B, то части аппаратного обеспечения бездействовали бы, пока А заштрихована, и затем части аппаратного обеспечения бездействовали бы, пока В заштриховано.

В худшем случае все пиксели, которые вы рисуете, накладываются друг на друга, а тысячи и тысячи потоков GPU - все, кроме одного - простаивают. Этот один поток терпеливо затеняет пиксель A, затем B, затем C ...

bmcnett
источник