вторник, 26 апреля 2011 г.

Depth of Field: First Experiments

Начал экспериментировать с различными реализациями depth of field. Тема эта очень сложная, поэтому для начала решил попробовать несколько brute-force методов для получения референсного изображения, отталкиваясь от которого, можно было бы подгонять real-time технику до нужного качества.

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



Используется 48 сэмплов, для каждого кадра инстансингом рисуется 1024 кубика, расстояние до фокальной плоскости учитывается при построении look-at матрицы. 48 "выборок" явно недостаточно для сглаженного изображения, очень виден бандинг. Нужно как минимум 128, и хорошо посчитанный kernel. Можно получить очень хороший depth of field, качеством напоминающий ray-tracing.

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


Немного о реализации: с помощью инстансинга рисуются всё те же 1024 кубика, в depth буфер выводится view space z. Затем рисуется w * h вершин, по одной вершине в каждом пикселе окна. Чтобы снизить нагрузку, вершинный буфер не используется, вызовы вершинного шейдера генерируются вызовом DrawInstanced(), в шейдере используется семантика SV_InstanceID для расчёта экранных координат. Вершинный шейдер сэмплирует цвет и глубину и передаёт данные в геометрический шейдер. Последний рассчитывает диаметр circle of confusion и раздувает вершину в спрайт нужного размера. Ну а дальше блендинг в PS. Техника упирается, как ни странно, не в геометрический pipeline, а в блендинг в FP-render target.

Следующий шаг - разбор уравнений, по которым рассчитывается правильный CoC (как оказалось, у всех - по-разному).

Update

Сегодня построил график изменения радиуса circle of confusion в зависимости от параметров оптической системы: диаметра линзы, фокального расстояния и фокальной плоскости. Для построения была взята формула из пейпра Dynamic Light Field Generation and Filtering:


По характеру кривой график совпал с тем, что приведён в другом пейпре по DoF: Pyramidal Image Processing. Естественно, что на кривую влияют выбранные параметры и характер масштабирования по оси Y, т. к. размеры CoC меняются далеко нелинейно. Но вот например в слайдах Advanced Real-Time Depth of Field Techniques приводится другой график:


и не совсем ясно, по какой формуле он считался. Будем думать :)

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

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