Беспристрастный Рендеринг Directx На Графическом Процессоре, Процессоре И В Облаке

Как создать рендерер, который бы работал даже на компьютере вашей бабушки? Изначально перед нами стояла немного другая задача — создать объективный рендер для всех моделей графических процессоров: NVidia, ATI, Intel. Хотя идея такого рендеринга для всех видеокарт витала в воздухе уже давно, до качественной реализации, особенно на Direct3D, так и не дошло.

В своей работе мы придумали очень дикую комбинацию и далее расскажем, что нас к ней привело и как это работает.

Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Я очень хорошо объяснил, что такое объективный рендеринг, или рендеринг без предположений.

Марчевский в серии статей «Трассировка пути на графическом процессоре» часть 1 , часть 2 И " Беспристрастный рендеринг (рендеринг без предположений) ".

Если коротко: это рендеринг, который не вносит систематических ошибок в расчет и воспроизводит физически точные эффекты.

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


Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Из-за физической достоверности и качества картинки такой подход явно очень ресурсозатратен.

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



Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

1200х600 (кликабельно), AMD Radeon HD 6870, время рендеринга: 9 минут

Почему Direct3D

Существует множество платформ GPGPU (OpenCL, CUDA, FireStream, DirectCompute, C++ AMP, Shaders и т. д.), но споры об оптимальном выборе все еще продолжаются, и четкого ответа на то, что лучше использовать, нет. Давайте рассмотрим основные аргументы в пользу Direct3D, которые убедили нас выбрать именно этот API:
  • Работает на всем спектре видеокарт, эмулируется на всех моделях процессоров: везде работает один и тот же шейдер.

  • Именно спецификации Direct3D задают направление развития потребительского оборудования.

  • Всегда первыми получайте самые последние и самые стабильные драйверы.

  • Другие технологии разных поставщиков нестабильны или плохо поддерживаются.

Из OpenCL и Direct3D мы выбрали то зло, которое хотя бы имеет стабильные драйверы, отточенные десятилетиями игровой индустрии, и имеет лучшую производительность в ряде бенчмарков.

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

C++ AMP на тот момент еще не был анонсирован, но поскольку.

Его реализация построена поверх DirectX, поэтому перенос рендеринга на него не составит особых проблем.

Комбинация OpenGL/GLSL также рассматривалась, но от нее быстро отказались из-за ограничений, которые DirectX решает с помощью DirectCompute (проблемы двунаправленной трассировки пути и т. д.).

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

Таким образом, с выходом линейки NVIDIA Kepler 600 геймеры сразу получили качественные драйверы Direct3D и более мощные машины для игр, но большинство GPGPU-приложений утратили совместимость или стали менее производительными.

Например, Octane Render и Arion Render, построенные на CUDA, буквально на днях начали поддерживать линейку Kepler. Кроме того, профессиональное оборудование GPGPU не всегда намного лучше справляется с рядом задач, о чем описано в статье « NVIDIA для профессиональных 3D-приложений «Это дает повод построить рабочую станцию на потребительском игровом оборудовании.



Почему не Direct3D?

Во всех анонсах DirectX 10–11 пишут, что новые модели шейдеров идеально подходят для трассировки лучей и многих других задач GPGPU. Но никто по-настоящему не воспользовался этой возможностью.

Почему?

  • Никаких инструментов и поддержки
  • Исследования сместились в сторону NVIDIA CUDA из-за сильного маркетинга
  • Привязка к одной платформе
Вернемся на год назад. Последнее обновление DX SDK было в июле 2010 года.

Интеграции с VisualStudio нет, сообщества разработчиков GPGPU и качественных примеров нормальных вычислительных задач практически нет. Да ведь нет подсветки синтаксиса шейдеров! Вменяемых средств отладки тоже нет. PIX не может обрабатывать несколько вложенных циклов или более 400 строк кода шейдера.

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

Большинство научных статей и публикаций написаны с использованием CUDA и предназначены для оборудования NVIDIA. Команда NVIDIA OptiX также не особо заинтересована в исследованиях для других вендоров.

Немецкая компания Mentalimages, накопившая десятилетия опыта и патентов в этой области, теперь также принадлежит NVIDIA. Все это создает нездоровый уклон в сторону одного вендора, но рынок есть рынок.

Для нас все это означало, что все новые методы трассировки и рендеринга GPGPU нужно было изучать заново, но только на DirectX и на оборудовании ATI и Intel, что часто приводило к совершенно другим результатам, например на архитектуре VLIW5.

Выполнение

Мы устраняем проблемы Прежде чем описывать реализацию, дам несколько полезных советов, которые помогли нам в разработке:
  • Если возможно, переключитесь на VisualStudio2012. Долгожданная интеграция с DirectX, встроенная отладка шейдеров и, о чудо, подсветка синтаксиса HLSL сэкономят вам массу времени.

  • Если VS2012 не является вариантом, вы можете использовать такие инструменты, как NVidia Parallel Nsight, но вы опять же привязаны к одному типу графического процессора.

  • Используйте Windows 8.0 SDK, это ваше дело.

    Даже если вы разрабатываете на Windows Vista/7 и более старых версиях VisualStudio, в вашем распоряжении будут новейшие библиотеки D3D, включая новейший D3DCompiler, который сокращает время компиляции шейдеров в 2-4 раза и работает стабильно.

    Для настройки DirectX из Windows 8.0 SDK есть подробная инструкция.

    руководство .

  • Если вы все еще используете D3DX, подумайте о том, чтобы отказаться от него, это не так, братан.

    Windows 8.0 SDK прекратил его поддержку по вполне очевидным причинам.

Растеризация против трассировки Несмотря на то, что используется DirectX, о растеризации речи не идет. Стандартный конвейер вершинных, Hull, Domain, геометрических и пиксельных шейдеров не используется.

Речь идет о трассировке световых путей с помощью пиксельных и вычислительных шейдеров.

Идея совместить растеризацию+трассировку, конечно, возникла, но реализовать ее оказалось очень сложно.

Пересечение первого луча можно заменить растеризацией, но после этого генерировать вторичные лучи очень сложно.

Часто оказывалось, что лучи находились под поверхностью, и результат оказывался неверным.

К такому же выводу пришли ребята из Sony Pictures Imageworks, разработавшие Arnold Renderer. Рендеринг Существует два основных подхода к организации рендеринга:

  1. Все вычисления происходят в мегаядре программы GPU, которое отвечает как за трассировку, так и за шейдинг.

    Это самый быстрый метод рендеринга.

    Но если сцена не поместится в память GPU, то либо сцена будет заменена, либо приложение сломается.

  2. Внеядерный рендеринг: в графический процессор передается только геометрия сцены или ее часть вместе с буфером лучей для трассировки, при этом выполняется многопроходная трассировка лучей.

    Затенение выполняется либо на процессоре, либо с помощью другого прохода на графическом процессоре.

    Эти подходы не отличаются потрясающей производительностью, но они позволяют визуализировать сцены промышленного размера.



Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Мы остановились на первом варианте с использованием шейдеров для GPGPU, но прежде чем что-либо рендерить, нам необходимо подготовить геометрию и данные сцены, правильно разместив их в памяти GPU. Данные сцены включают в себя:
  • геометрия (вершины, треугольники, нормали, текстурные координаты)
  • ускоряющая структура (Kd-дерево или узлы BVH)
  • материалы поверхности (тип, цвета, показатели текстуры, светоотражающие элементы и многое другое)
  • текстуры материалов, карты нормалей и т. д.
  • источники освещения (одиночные и протяженные)
  • положение и параметры камеры, такие как DOF, FOV и т. д.
Во время рендеринга не используются буферы вершин или индексов.

В Direct3D11 данные унифицированы, все хранится в одном формате, но вы можете указать устройству, как это смотреть: как Buffer, Texture1D/2D/3D/Array/CUBE, RenderTarget и т. д. Данные, к которым осуществляется доступ более или менее линейно лучше всего хранить в виде буферов.

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

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

Изменения геометрии происходят несколько реже, но постоянной памяти для их размещения все равно не хватает. Т.

к.

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

Мы размещаем текстуры материалов в многослойном атласе текстур, потому что.

Количество текстурных слотов графического процессора ограничено.

Также в графическом процессоре имеются встроенные форматы сжатия текстур — DXT, которые используются для атласов текстур и позволяют уменьшать размер текстур до 8 раз.

Упаковка текстур в атлас:

Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

В результате расположение данных в памяти выглядит так:

Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

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



Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

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



Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Далее для каждого пикселя в шейдере рассчитывается алгоритм трассировки лучей.

Вот как вычисления GPGPU выполняются в пиксельных шейдерах.

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

Но многочисленные тесты показали, что DirectCompute медленнее на 10-15%.

В задаче трассировки пути любые преимущества использования SharedMemory или использования лучей быстро сводятся на нет из-за случайного характера алгоритма.

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

Отбор проб методом Metropolis Light Transport пока не применяется, поскольку его эффективность еще не обоснована, о чем говорит один из разработчиков V-Ray на закрытом форуме ChaosGroup: Владо написал:

«.

Я пришел к выводу, что MLT сильно переоценена.

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

Это связано с тем, что MLT не может использовать преимущества какого-либо порядка выборки (например, выборки квази-Монте-Карло или последовательности Шлика, которую мы используем, или выборки N-ладей и т. д.).

Рендерер MLT должен использовать чистые случайные числа, что значительно увеличивает шум во многих простых сценах (например, в сцене с открытым окном в крыше)».



Многоядерный.

Мульти-устройство.

Облако.

Отметим, чем очень хорош несмещенный рендеринг — он основан на методе Монте-Карло, а это означает, что в общем случае каждая итерация рендеринга не зависит от предыдущей.

Именно это делает этот алгоритм привлекательным для вычислений на графических процессорах, многоядерных системах и кластерах.

Чтобы поддерживать оборудование класса DX10 и DX11 и не переписывать все заново для каждой версии, следует использовать DirectX11, который имеет небольшие ограничения.

работает на оборудовании DX10 .

Имея поддержку широкого класса железа и предрасположенность алгоритма к распространению, мы сделали Multi‒Device рендеринг, принцип которого очень прост: нужно заложить в каждый GPU одни и те же данные и шейдеры и просто собрать результат с каждого GPU. по мере готовности, перезапуская рендеринг при изменении сцены.

Алгоритм позволяет распределить рендеринг на очень большое количество устройств.

Эта концепция отлично подходит для облачных вычислений.

Но поставщиков облачных графических процессоров не так много, а компьютерное время тоже стоит не очень дешево.

С появлением DirectX11 на помощь пришла замечательная технология — ДЕФОРМАЦИЯ (Платформа расширенной растеризации Windows).

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

Причём абсолютно любой процессор: x86, x64 и даже ARM! С точки зрения программирования такое устройство ничем не отличается от устройства с графическим процессором.

Именно на основе WARP реализованы гетерогенные вычисления в C++ AMP. Устройство WARP — это тоже твой брат, используй устройство WARP.

Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Благодаря этой технологии мы смогли запустить рендеринг на GPU в облаке CPU. Мы получили некоторый бесплатный доступ к Windows Azure через программу BizSpark. Для хранения данных использовалось Azure Storage, данные с геометрией сцены и текстурами хранились в «блобах», данные о заданиях рендеринга, скачивании и скачивании сцен находились в очередях (Queues).

Для обеспечения стабильной работы использовались три процесса: распределитель задач (Work Scheduler), наблюдатель процессов (Process Monitor) и процесс загрузки отрендеренных изображений (Image Downloader).

Планировщик работ отвечает за загрузку данных в BLOB-объекты и постановку задач.

Process Monitor отвечает за поддержание всех рабочих процессов (Worker — вычислительного узла Azure) в рабочем состоянии.

Если один из воркеров перестает отвечать, то инициализируется новый экземпляр, обеспечивая тем самым максимальную производительность системы.

Image Downloader собирает отрендеренные фрагменты изображения со всех воркеров и передает клиенту готовое или промежуточное изображение.

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



Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Эта схема работает хорошо, и это, как нам кажется, будущее рендеринга — Pixar уже выполняет рендеринг в облаке .

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

Если вам нужно отрендерить анимацию с размером ресурсов в несколько десятков или сотен ГБ, то у вас проблемы.



Результат

Результатом всей этой работы стал плагин RenderBro для Autodesk 3DS Max, который по задумке должен рендерить даже на бабушкином компьютере и может использовать любые вычислительные ресурсы.



Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

В настоящее время он находится на стадии закрытого альфа-тестирования.

Если вы энтузиаст графических процессоров, 3D-художник, планируете создать кластер ATI/NVIDIA, имеете несколько различных графических процессоров и процессоров или любую другую интересную конфигурацию, дайте мне знать , будет интересно поработать вместе.

Мне бы очень хотелось протестировать рендер на чем-то вроде этого:

Беспристрастный рендеринг DirectX на графическом процессоре, процессоре и в облаке

Также впереди C++ AMP-версия рендеринга, более серьезные облачные тесты и разработка плагинов для других редакторов.

Присоединяйтесь к нам! Теги: #рендеринг #рендеринг #трассировка лучей #трассировка лучей #трассировка лучей #трассировка пути #трассировка пути #рендеринг без предположений #непредвзятый рендеринг #nvidia #Intel #x64 #x86 #arm #cloud Computing #Cloud Computing #windows azure #GPGPU # gpu #DirectX #direct3d #hlsl #hlsl #hlsl #DirectCompute #3d #3d графика #шейдеры #шейдеры #C++ AMP #cuda #opencl #GPGPU

Вместе с данным постом часто просматривают: