Назад
29

NeRV: Neural Reflectance and Visibility Fields for Relighting and View Synthesis

29

Перед прочтением статьи рекомендуем к просмотру наше видео с разбором NeRF и Instant NeRF.

Давайте вспомним для чего нужен и что делает классический NeRF. Это нейросеть, обученная с целью создания одной 3D сцены по нескольким её 2D фото с разных ракурсов. Для этого мы учим сеть предсказывать цвет и прозрачность точки в трёхмерном пространстве. На вход подаются координаты точки начала луча из камеры и углы, определяющие его поворот в трёхмерном пространстве (см. Рисунок 1).

Рисунок 1.1. NeRF принимает на вход координаты точки и углы, под которыми точку видит камера. Сеть предсказывает цвет и прозрачность этой точки. Источник

Рисунок 1.2. Рендеринг двух 2D картинок по 3D сцене. Красная стрелка — луч камеры, для черных точек вычисляем цвет и плотность

Рендеринг — получение 2D картинки из 3D сцены. Для получения 2D изображения из NeRF мы пустим из каждого пикселя изображения луч (назовём его лучом камеры), получим для точек на лучах значения цвета \( (r, g, b) \) и плотность, или прозрачность ( \( \sigma \)), а затем просуммируем цвета с учётом их прозрачности вдоль этих лучей.

По архитектуре сеть представляет собой multilayer perceptron (MLP).

Зачем менять освещение?

Вы модный молодёжный 3D художник и хотите максимально упростить себе жизнь с помощью нейронок. Вы узнаёте про NeRF, очень радуетесь, бегом получаете через него рендеры для пары объектов из дома и… Не можете их особо нигде использовать. Потому что освещение в них фиксированное.

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

Как обучить сеть, которая будет принимать источники освещения как часть входных данных и выдавать рендер для сцены с таким освещением?

Рисунок 2.1. Для обучения NeRV делаем несколько фото с разными источниками освещения (a), после чего получаем сцену с освещением в любых точках (b). Если гифка не грузится, перезагрузите страницу.

Рисунок 2.2. После обучения получаем рендер для сцены с динамическим освещением

Освещение

Для качественного предсказания освещения нужно научиться работать с двумя его типами — прямым (direct) и отражённым (indirect). Их различия показаны на Рисунке 3:

Рисунок 3. Разные виды освещения. Источник

Можно предсказать direct illumination методом NeRF. Выпускаем из источника света несколько лучей (назовём их лучи освещения), проверяем прозрачность всех точек между точкой на луче из камеры и источником света. Можно на каждом луче освещения брать столько точек, сколько их на луче из камеры. Если возьмем меньше точек — потеряем часть информации о освещении. Следовательно, для качественного рендера нам понадобится вычислить плотность в \( O(n^2) \) точках.

Теперь рассмотрим indirect освещение для одной точки на луче из камеры. Сначала мы берём \( d \) лучей освещения (это выделено синим на Рисунке 4), каждый из которых требует вычисления в \( n \) точках. Для этого нам придётся посчитать плотность в этих \( n \) точках и на \( (n — 1) \) лучах освещения между этими точками и источником освещения.

Итого: в indirect освещении для одной точки мы имеем \( d \cdot n \cdot (n — 1) + 1 = O(n^2d) \) вычислений. Теперь мы вспоминаем, что считали только для одной точки на луче из камеры. Значит, для всех точек при единственном источнике освещения имеем \( O(n^3d) \), а при \( l \) источниках освещения будет уже \( O(n^3dl) \).

Рисунок 4. Освещение в варианте обработки от NeRF (слева) и NeRV (справа). Чёрная стрелка — луч камеры, для которого мы делаем предсказание, красные линии — direct illuminataion, синие — indirect illuminataion, n —число предсказываемых точек для каждого луча из камеры, l — число источников света, d — число предсказаний indirect лучей

Как освещение просчитывают в графике?

Рисунок 5. Отражение света от поверхности

BRDF — функция, связывающая угол падения между вектором \( \omega_i \) и нормалью к поверхности \( n \) и угол отражения между \( \omega_0 \) и \( n \) с яркостью луча до падения и после (см. Рисунок 5). Эту функцию можно получить на основе теоретической модели и за счёт других физических свойств материала. Для использования microfacet BRDF (как в Unreal Engine) нам, кроме нормали \( n \), нужно знать albedo (характеристика отражения света) и roughness (шероховатость поверхности).

Как улучшить сетками?

Для каждой точки MLP в NeRF предсказывает цвет \( (r, g, b) \) и плотность \( \sigma \). В NeRV мы разбиваем задачу между несколькими MLP.

Shape

Мы получим для каждого луча плотность \( \sigma \) (для понимания пройденного через точку количества света) и нормаль к поверхности в этой точке \( n \) (для углов падения и отражения). Пусть их вычисляет отдельная \( MLP_{shape} \).

Пусть \( t \) — параметр, отвечающий за положение точки на луче из камеры, \( x(t) \) — координаты точки для предсказания, тогда \( MLP_{shape}(x(t))= \sigma \). При этом мы считаем карту нормалей \( n = \nabla_x \sigma = \nabla_x MLP_{shape}(x(t)) \).

BRDF

Еще нам нужна \( MLP_{BRDF} \) для вычисления параметров albedo (\( a \)) и roughness (\( \gamma \)).

В нотации из формул выше имеем: \( MLP_{BRDF}(x(t)) = (a, \gamma) \). BRDF позволяет получать цвет пикселя с учётом падающего на него освещения.

Rendering

Для получения итогового результата мы используем уравнение рендеринга. Для решения задачи с прошлых этапов нам уже достаточно информации, но нужно будет еще учитывать положения всех предсказанных точек (см. Рисунок 4) и считать два интеграла по объему — это дорого. Эти два интеграла нам нужны для определения V — видимости освещения в точке (попадает ли вообще в неё луч света?) и D — расстояния, с которого в точку отразится луч из источника света. D помогает нам найти точку — на нее указывает синяя стрелка на Рисунке 6.

Дешевле получить приближенный результат отдельной сетью \(MLP_{V, D}\). Параметры вычисляются для конкретного луча \( \omega_i \) (см. Рисунок 5): \( MLP_{V, D}(x(t), \omega_i) = (V, D) \) .

Рисунок 6. Indirect освещение в NeRV

Дальше в дело вступает магия физики и обычного рендеринга. Мы берём переменные в уравнении рендеринга и заполняем их сетками выше. Одно из заметных отличий этой статьи от NeRF — количество формул с интегралами 🙂

Рисунок 7. Рендеринг сцены (a), за один forward считаем все значения только в одной точке, например, в \( x \) (выделено голубым). Все параметры b-e получаются из выходов трёх наших MLP по формулам классического рендеринга. Далее f — карта нормалей \( sigma \); g, h соответствуют \( a, \gamma \); i, j, k — визуализации полученного освещения

Итоги

Вот что у нас происходит в NeRV:

  • для каждого луча сэмплируем набор точек, для каждой точки прогоняем MLP с целью получения \( \sigma \), карты нормалей и параметров BRDF;
  • применяем direct освещение для каждой точки на луче: для вычислений используем V и BRDF;
  • применяем indirect освещение для каждой точки на луче: с помощью D находим точку, из которой пойдёт отражение луча, вычисляем ее влияние с BRDF;
  • объединяем полученные лучи и точки как в NeRF.

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

Ссылки

  1. Страница с примерами работы, ссылкой на arxiv и обещанием кода на JAX. Но кода нет…
  2. На NeRV ссылаются во многих более поздних статьях — тут, вот тут, там. Идея жива, идея развивается.

Телеграм-канал

DeepSchool

Короткие посты по теории ML/DL, полезные
библиотеки и фреймворки, вопросы с собеседований
и советы, которые помогут в работе

Открыть Телеграм

Увидели ошибку?

Напишите нам в Telegram!