Расширение процесса рендеринга Unity 5: Командные буферы

ARAS PRANCKEVIČIUS Anonymous
Feb 6, 2015|3 Мин
Расширение процесса рендеринга Unity 5: Командные буферы
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.

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

Внутри компании и в группе бета-тестирования мы обсуждали различные подходы. Разбрасывались множеством идей: больше обратных вызовов скриптов, сборка небольших буферов типа «список задач», возможность создавать полноценные конвейеры рендеринга с нуля, какие-то инструменты для строительства конвейеров визуального рендеринга деревьев и графов и так далее. Для Unity 5 мы остановились на возможности создавать буферы «список задач», которые назвали «Command Buffers».

Командный буфер в графике — это низкоуровневый список выполняемых команд. Например, API 3D-рендеринга вроде Direct3D или OpenGL обычно приводят к созданию командного буфера, который затем выполняется графическим процессором. Многопоточный рендерер Unity также строит буфер команд между вызывающим потоком и "рабочим потоком", который подает команды в API рендеринга.



В нашем случае идея очень похожа, но "команды" несколько более высокого уровня. Вместо того, чтобы содержать такие значения, как «установить значение Y для внутреннего регистра графического процессора», мы используем команды «Рисуйте эту меш из этого материала» и так далее.

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

Например, можно отрисовать некоторые дополнительные объекты в G-буфер с отложенным шейдингом после завершения работы над всеми обычными объектами. Или отрисовывайте облака сразу же после отрисовки скайбокса, но до чего угодно. Или отрисовывайте пользовательские источники света (светильники громкости, отрицательные источники света и т. д.) в буфер с отложенным затенением после завершения работы над обычными источниками света. И так далее; мы считаем, что их можно использовать самыми разными способами.

Взгляните на страницы CommandBuffer и CameraEvent в документации к скриптовому API.

Фотографии или их не было!

Хорошо, хорошо.

Например, мы можем создавать размытые преломления:

RenderingCommandBufferBlurryRefraction

После рендеринга непрозрачных объектов и неба текущее изображение копируется во временную цель рендеринга, размывается и настраивается как глобальное свойство шейдера. Шейдеры на стеклянном объекте, затем образцы с размытым изображением со смещением координат UV-развертки на основе карты нормалей для имитации преломления. Это аналогично тому, как это делает шейдер GrabPass, кроме того, вы можете делать больше собственных действий (в данном случае размытия).

Другой пример использования: пользовательские отложенные огни. Вот сферы и трубы:

RenderingCommandBufferCustomLights

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

Еще один пример: отложенные декали.

РендерингCommandBufferDecals

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

Изображение

Каждый декаль здесь реализован в виде коробки и влияет на любую геометрию объема коробки.

Вообще-то, вот небольшая папка проекта Unity (5.0 beta 22), в которой демонстрируется все вышесказанное: RenderingCommandBuffers50b22.zip.

Видно, что все приведенные выше случаи даже несложны в реализации - скрипты составляют около сотни строк кода.

Я думаю, это здорово. Не терпится увидеть, что вы с ним сделаете!