Атмосферное рассеяние в ролике The Blacksmith
Еще на стадии планирования The Blacksmith мы отказались от встроенных в Unity режимов тумана в пользу более гибкого и комплексного решения. Чтобы передать глубину и масштаб крупных сценических шотов, нам было нужно максимально реалистичное атмосферное рассеяние.
Приступив к созданию компонента для атмосферного рассеяния, мы изучили модели симуляции, представленные в работах Томоюки Ниситы (Display of The Earth Taking into account Atmospheric Scattering, Display Method of the Sky Color Taking into Account Multiple Scattering, Display of Clouds Taking into Account Multiple Anisotropic Scattering and Sky Light), и попробовали применить их на практике. После нескольких экспериментов с прототипами шотов мы окончательно убедились, что нам нужна модель, которая предоставила бы широкие возможности для настройки художественных эффектов для каждого шота. Другими словами, мы искали решение, которое бы позволило не только реалистично воссоздать физические параметры, но и в случае необходимости пожертвовать физикой ради художественного эффекта. При этом не должна была пострадать производительность ролика в реальном времени, поэтому мы решили делать большую часть расчетов на уровне вертексов, а не на уровне пикселей.
Мы задались целью смоделировать комбинированные эффекты рэлеевского рассеяния и рассеяния Ми на основе физических моделей. Кроме того, мы добавили третий элемент, который назвали «рассеяние по высоте». В отличие от физических моделей, в рамках нашего решения мы использовали обычные HDR-текстуры вместо процедурной генерации неба и облаков. Очевидный минус такого подхода в том, что он весьма усложняет настройку динамической смены времени суток (которая не требовалась нам для ролика). Но, с другой стороны, мы получили возможность полной художественной настройки неба.
Рэлеевское рассеяние
Рэлеевское рассеяние солнечного света в атмосфере придает небу голубой цвет днем и оранжево-красный оттенок на восходе и закате.
В ролике The Blacksmith у нас нет солнца как такового – мы ограничились моделированием цветов и распространения/затухания света в результате рассеяния солнечных лучей. Визуальный аналог солнца можно добавить непосредственно в текстуру неба, представить как элемент рассеяния Ми или как спрайт. По сути, плотность нашего рэлеевского рассеяния сводится к показательной функции на основе фазовой функции Рэлея. Но при этом у нас есть больше возможностей для добавления и извлечения данных из этой формулы. Мы смоделировали рассеяние света без изменения длины волны, поэтому в данном случае плотность являлась скалярной величиной. С помощью HDR Color Ramp мы разнообразили оттенки затухания света на горизонте и в зените, а также использовали функцию расстояния для создания окончательных цветов.
Рэлеевское рассеяние в различных конфигурациях.
Рассеяние Ми
В результате рассеяния Ми мы видим яркий ореол вокруг солнца, серую дымку облаков и смог в промышленных районах. В отличие от рэлеевского рассеяния, которое распределяет свет практически равномерно, рассеяние Ми характеризуется оптической анизотропией.
Мы использовали рассеяние Ми преимущественно для создания гало и дымки вокруг солнца. Учитывая тот факт, что наша симуляция рэлеевского рассеяния игнорировала солнце, мы компенсировали это путем увеличения интенсивности цветов. С технической точки зрения функции Рэлея и Ми в нашей симуляции очень похожи, за исключением фазовой функции, применяемой к выходным величинам. Как и во многих других проектах, для настройки параметра анизотропии мы использовали функцию рассеяния Хеньи–Гринштейна.
Рассеяние Ми в различных конфигурациях.
Читатели, знакомые с научными работами по этой теме, могут не согласиться с нашим выбором названий. В этом смысле мы и правда позволили себе некоторые вольности. Дело в том, что многие специалисты используют термин «рэлеевское рассеяние» для описания атмосферного рассеяния, а термин «рассеяние Ми» для обозначения дымки вокруг солнца. Поэтому мы решили придерживаться этих терминов.
Рассеяние по высоте
Данный элемент включает в себя различные эффекты атмосферного рассеяния, встречающиеся на малых высотах: туман в низинах, приземную дымку и слоистые облака.
В этом случае мы нашли достаточно простое решение: вычислили плотность на основе расстояния от заданного уровня моря, затем масштабировали ее по экспоненциальной плотности и окрасили в нужный цвет.
Преграждение света
Солнечный свет может не только рассеиваться по направлению к зрителю и от него – его также могут поглощать частицы, находящиеся между зрителем и источником света. Для симуляции этого эффекта нам нужно было отдельное решение.
Мы отследили лучи направленного света по каскадной карте теней и рассчитали преграждение в уменьшенном внеэкранном буфере. Чтобы применить рассеяние на пиксели конечного изображения, мы повысили разрешение карты теней с помощью edge-aware фильтра и создали конечный цвет для каждого пикселя. На этом этапе мы столкнулись с определенными трудностями. Учитывая то, то наше решение было рассчитано исключительно на однократное рассеяние, мы не могли просто взять и затенить весь поглощенный свет, ведь тогда изображение получилось бы очень темным и неестественным. С другой стороны, более сложное и дорогое решение для многократного рассеяния нам тоже было ни к чему. В конце концов, мы решили просто добавить фактор непрямого освещения – то есть возможность вручную задавать процентное соотношение прямого и непрямого рассеяния.
Преграждение света в различных конфигурациях.
Совмещение эффектов
Итак, осталось привести все эффекты финального изображения к общему знаменателю. Объединив все три элемента, мы получили реалистичную цветовую композицию.
Комбинированные эффекты рэлеевского рассеяния, рассеяния Ми и рассеяния по высоте.
Затем мы выполнили более детальную настройку значений затухания прямого и непрямого освещения в буфере.
Комбинированные эффекты рассеяния с учетом преграждения света.
И наконец, осталось наложить атмосферное рассеяние на картинку. Для этого мы затемнили передаваемое изображение на сумму затухания и осветили на сумму распространения света. Вот что у нас получилось:
Финальная композиция.
Оригинальный перевод статьи на сайте habrahabr.ru.
Источник!