суббота, 2 января 2010 г.

A-buffer

Добил проблему ошибок в A-буфере. Всё дело в том, что правильная индексация в алгоритме возможна при размерностях буфера, кратного степени двойки. Например, 515x256, 1024x1024. Если это не так, получается выход за пределы массива (я проверял "на бумажке"). Хотя в современных GPU можно читать/писать за пределами ресурса (returns 0 on reads, writes are no-ops), prefix sum считается неправильно, и часть изображения портится. При размерностях, кратных степени двойки, всё Ok.

Теперь вот задумался. Простой метод решения проблемы - создавать буфер, кратный степени двойки, не эффективно в случае мониторов 16:9 - лишняя память впустую, а A-buffer и так немаленький. Вычисления, вероятно, можно оптимизировать, чтобы правильный prefix sum строился только в видимой части буфера. Но всё равно, интересно, можно ли написать алгоритм для параллельного сканирования буфера произвольных размеров?

Теперь думаю написать с нуля собственное демо по использованию A-буфера, т. к. смотреть на коды SDK уже тошно.

Update

Пока фарширую демку кодом и подумываю, какую модель использовать для прозрачности. Что-то простенькое или поэффектнее?

Оптимизируя по ходу OIT11, я решил убрать копирование RWTexture2D в RWBuffer. Но получилось медленнее, главным образом из-за того, что ClearUnorderedAccessViewUint() RWBuffer-а с Catalyst 9.12 очень медленный. Вместо очистки я решил использовать Compute Shader. Выбираем оптимальный размер блока, подключаем UAV, вызываем Dispatch() и пишем в шейдере 0. Получается быстрее очистки, что говорит о проблеме в драйвере, а не железе. Одна беда - всё равно получается медленнее, чем копирование! Не то, чтобы сильно медленнее, но всё же. По-видимому, тут проблема с паттерном доступа к памяти. При копировании блоками получается последовательное чтение/записть, RWBuffer это любит. А вот при unordered записи из пиксельного шейдера выгоднее, получается, использовать RWTexture2D. А может быть, доступ к RWBuffer не кэшируется, в отличие от RWTexture*, поэтому конструкция ++buffer[pos.xy] при overdraw для RW-текстуры получается быстрее.

Ещё надо посмотреть, как ведёт себя RWTexture1D.

Комментариев нет:

Отправить комментарий