Превью статьи
3D графика
Искусственный интеллект
Машинное обучение
7 апреля
18 минут

Как мы научили нейросети воспроизводить физически достоверные текстуры

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

Антон Тимошенко avatar

Антон Тимошенко

Ведущий разработчик в области ML и GPGPU вычислений

Когда физика встречается с искусственным интеллектом: как мы научили нейросети воспроизводить физически достоверные текстуры

История компьютерной графики — это история компромиссов. С одной стороны, стремление к фотореализму, которое привело индустрию к созданию сложнейших математических моделей освещения. С другой — жесткие ограничения по времени, в течение которого должен быть просчитан каждый кадр. Этот конфликт особенно остро ощущается при создании материалов — того, как поверхность объекта взаимодействует со светом.

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

В играх и интерактивных приложениях такой подход невозможен. Здесь каждый кадр должен быть готов за 16 миллисекунд (для 60 FPS) или даже быстрее. Поэтому художники и разработчики вынуждены упрощать фотореализм, искать обходные пути, использовать предварительно рассчитанное освещение (lightmaps) и менее требовательные модели материалов. До недавнего времени считалось, что пропасть между этими двумя мирами - рендерингом в реальном времени и фотореализмом - непреодолима.

Наша команда ставила перед собой амбициозную цель: сделать шаг к преодолению этой пропасти. Мы задались вопросом: а что, если мы сможем взять сложнейший материал, созданный для кино, и «сжать» его в компактную нейронную сеть, которая будет работать так быстро, что её можно будет использовать в реальном времени? В итоге мы получили впечатляющие результаты, которые превзошли наши ожидания.

От многослойного пирога к нейронному ядру: концепция запекания материалов

Концепция запекания материалов

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

В индустрии визуальных эффектов и в современных игровых движках (хотя в играх их используют ограниченно) стандартом де-факто являются layered materials - многослойные материалы.

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

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

Каждый из этих слоев описывается своей математической моделью (BSDF — Bidirectional Scattering Distribution Function), а для управления их смешиванием используются маски, карты высот и процедурные шумы. Визуально это выглядит как сложный граф, где десятки узлов соединены сотнями связей. Просчет такого графа в реальном времени — задача непосильная даже для самых мощных GPU.

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

  1. Художник создает эталонный материал в привычном для него инструменте (например, в Autodesk Maya с использованием MaterialX или в Houdini).
  2. Мы запускаем процесс генерации обучающих данных. Для этого мы многократно сэмплируем материал: берем случайную точку на поверхности (с координатами UV), случайное направление на источник света и случайное направление на камеру.
  3. Для каждой такой комбинации мы просчитываем сложный граф материала, получая эталонное значение цвета и, что важно, правильное распределение отраженного света.
  4. Полученный датасет (миллионы таких семплов) используется для обучения нашей нейронной модели.
  5. После обучения сложный, «тяжелый» граф материала больше не нужен. В игру или приложение идет только компактная нейросеть и непосредственно нейронные текстуры — neural representation.

Результат — не просто сжатие, а трансформация способа представления материала. Вместо описания физических процессов («как свет проходит сквозь слои») мы получаем поведенческую модель («как поверхность выглядит при таком освещении»), которая занимает в сотни раз меньше места и просчитывается на порядок быстрее.

Анатомия нейронного материала: от входа к выходу

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

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

Этап 1: Входные данные В момент, когда при рендеринге луч попадает в объект с нейронным материалом, шейдер собирает все необходимые данные о точке попадания и передает их сети. Входной вектор включает в себя:

  • Координаты текстуры (UV): Позиция точки на поверхности объекта. По этим координатам мы делаем выборку из запеченной карты признаков.
  • Направления: Вектор направления на источник света (откуда светит источник, ωi\omega_{i}) и вектор направления взгляда (куда смотрит камера, ωo\omega_{o}).
  • Дополнительные атрибуты: Сюда могут добавляться карты нормалей для коррекции геометрии, хотя сеть и сама может научиться их эффектам.

Этап 2: Карта латентных признаков — память материала Мы отказались от идеи подавать «сырые» UV-координаты напрямую в большую сеть. Такой подход потребовал бы от сети колоссальной емкости, чтобы запомнить все вариации материала в разных частях объекта. Вместо этого мы используем текстуру специального формата, которую называем картой признаков (feature map).

В отличие от классических текстур, хранящих цвета RGB или параметры материалов (шероховатость, металличность), наша карта признаков хранит латентные векторы (latent features) — компактные многомерные векторы (скажем, 8 чисел), которые кодируют все сложные свойства материала в данной конкретной точке. Это результат работы энкодера, который был обучен вместе с декодером. Энкодер научился сжимать всю сложность исходного материала в компактное представление.

Этап 3: Нейронный декодер — интерпретация признаков Из карты признаков мы извлекаем латентный вектор для данной точки. Но сам по себе он бесполезен — это просто набор чисел. Чтобы превратить его в цвет и физические свойства, нужен интерпретатор. Эту роль выполняет нейронный декодер (Neural Decoder) — небольшая, но мощная полносвязная нейронная сеть (многослойный перцептрон).

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

Техническая революция: Cooperative Vectors и доступ к тензорным ядрам

Создать архитектуру сети — это только половина дела. Самый сложный вызов проекта заключался в том, чтобы заставить эту сеть работать внутри шейдера на видеокарте, выполняясь сотни тысяч раз в кадр и укладываясь в бюджет работы необходимого для реального времени. Именно здесь на помощь приходит технология Cooperative Vectors (кооперативные векторы), ставшая фундаментом для всей нашей реализации.

Проблема: два разных мира

Обычно нейросети выполняются на тензорных ядрах GPU с использованием специализированных библиотек (типа cuDNN) и фреймворков (TensorFlow, PyTorch). Они работают с большими пакетами данных (батчами) и оптимизированы для максимальной пропускной способности. Шейдеры же — это маленькие программы, которые выполняются для каждого пикселя или луча индивидуально. Они работают в совершенно другом режиме, и доступ к тензорным ядрам из шейдерного кода исторически был невозможен.

Кроме того, традиционная модель программирования SIMT требует полного варпа активных потоков для эффективной работы с тензорными ядрами. Варп (warp) — это базовый блок выполнения на GPU, как правило группа из 32 потоков, которые выполняют одну и ту же инструкцию одновременно. Однако модель трассировки лучей обрабатывает потоки независимо, и собрать их в полные группы по 32 практически невозможно.

Тензорные ядра также оптимизированы для матрично-матричного умножения, в то время как каждому потоку луча нужно только векторно-матричное умножение. Эти факторы приводят к неполной загрузке вычислительных ресурсов.

Решение: Cooperative Vectors API

Мы преодолели этот барьер благодаря новой технологии — Cooperative Vectors, разрабатываемой AMD в тесном сотрудничестве с Microsoft и активно внедряемой в DirectX.

Cooperative vectors — это специализированный API для вычисления матрично-векторных произведений в графических задачах. Он разработан для случаев, когда каждому потоку параллельной программы нужно умножить вектор на относительно небольшую матрицу (например, 128×128, 64×64 или меньше). Работая совместно, потоки могут выполнять эти умножения гораздо эффективнее — отсюда и название «кооперативные» .

Оптимизация памяти и выполнения

Важным аспектом реализации является оптимальная упаковка весов и смещений нейросети. Все веса обученных сетей и данные карт признаков упаковываются в специальные буферы в памяти GPU с использованием оптимизированного расположения (packing) для максимальной эффективности доступа .

Борьба с дивергенцией

При рендеринге методом трассировки лучей (raytracing) лучи могут расходиться очень хаотично — один луч попадает на металлическую поверхность, а соседний — на ткань. Это называется дивергентным выполнением и является "врагом" производительности GPU. Cooperative Vectors могут обрабатывать дивергенцию данных и выполнения в варпе, хотя и с некоторым снижением производительности .

Для достижения максимальной производительности мы используем технику Shader Execution Reordering (SER), которая перегруппировывает лучи по типу обрабатываемого материала. Это обеспечивает два ключевых условия для оптимальной работы Cooperative Vectors:

  1. Веса нейронной сети одинаковы для всех потоков в варпе
  2. В варпе присутствует полный комплект активных потоков

Результат оптимизации

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

Результат оптимизации

Масштабирование и применение в реальных проектах

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

Мы проанализировали эту проблему и предложили несколько стратегий:

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

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

Изображение видеокарты

Разработка в области 3D-графики

Нужны нейронные материалы в реальном времени или продвинутый 3D-рендеринг? У нас команда профессионалов, которая качественно выполнит ваши задачи.

Заключение: новая эра интерактивной графики

Мы верим, что эта работа открывает новую главу в интерактивной графике.

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

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

Частые вопросы и ответы

Обсудить проект

Опишите вашу задачу, мы проведём исследование и ответим вам как можно скорее.

С радостью проконсультируем вас любым из доступных способов.

Оставляя заявку, вы соглашаетесь с политикой обработки данных