Коротко: Мы строим систему воды для Unreal Engine с двумя обещаниями: вода, что выглядит правильно, потому что свет, цвет и пена рассчитываются физически, а не подстраиваются вручную под сцену, и вода, что ведёт себя правильно: бросьте любой меш на поверхность, и он плавает, кренится или тонет корректно, без всякой настройки. Она в активной разработке. Этот пост объясняет, что она охватывает, как мы держим себя в узде референсными фотографиями, почему плавучесть остаётся той трудной частью, которую все пропускают, и где она встаёт рядом с остальным набором инструментов.
Планка, которую нужно взять. Заметьте, что делает это реальным: пена, рождённая из разбивающихся волн, дымка, поедающая утёсы, статистика барашков по всему зыбу: ничего не расставлено вручную, всё физика. Вот планка, что мы поставили.
Зачем ещё одна система воды?
Большинство игровой воды выглядит великолепно ровно в одном условии освещения: в том, что на скриншоте в магазине. Сдвиньте солнце, переключитесь на пасмурно, опустите камеру наполовину под линию воды, и она разваливается.
Есть второй, тихий провал, что важен не меньше: почти каждая система воды относится к плавающим объектам как к запоздалой мысли. Вы получаете шаблон лодки, страницу инструкций по такелажу понтонов и негласное допущение, что никто никогда не бросит случайный ящик в море. Игроки бросают ящики в море постоянно.
Мы хотели двух вещей, что сейчас не сосуществуют в одном пакете: облик кинематографического качества, что переживает любое освещение, и физическое поведение, что не требует никакой настройки. Ни того ни другого не достичь, подкручивая параметры, пока скриншот не станет красивым, ведь скриншот это один кадр под одним солнцем, и как только что-то меняется, вода, подстроенная под вкус, показывает свои швы. Так что фундамент проекта — не список фич. Это приёмочный тест, с которым человек не может спорить: фотография.
Оценивается по фото, а не по вкусу
Разработка гейтится референсными фотографиями с фиксированными контрактами камеры и освещения: физические единицы света, зафиксированный тонемаппер и перцептивная метрика различия, решающая «прошло/не прошло», а не настроение арт-директора в тот день.
Две референсные фотографии каноничны, и их выбрали как противоположности:
- Прозрачное озеро, камера в линии воды. Наполовину воздух, наполовину вода, волнистая граница без полосы артефактов; зеленоватая прибрежная вода, чей цвет углубляется с расстоянием; каустики на камнях, что совпадают с поверхностью над ними; затонувшие брёвна, что корректно преломляются на границе. Эта проверяет преломление, переход линии воды и подводное поглощение цвета, всё разом.
- Штормовой берег под полной облачностью. Ни солнца, ни блёсткой полосы: море должно читаться через мягкое отражение неба, обесцвеченную серо-зелень, статистику барашков и дымку над утёсами. Буй качается на зыбу с правдоподобным периодом и наклоном; поведение — часть приёмки, а не только неподвижный кадр.
Пасмурная референсная фотография намеренно одна из двух. Освещённая солнцем вода льстит любому рендереру на Земле, потому что спекулярный блеск скрывает множество грехов. Уберите солнце, и вода должна нести кадр одной лишь шероховатостью отражений, цветом и движением. Это честный тест, и именно его большинство систем тихо избегают. Океан, что хорош только на солнце, не выходит в продажу.
Сторона камеры специфицирована столь же строго, как и сторона воды, ведь фото-сравнение честно лишь тогда, когда камера не может жульничать. Это значит настоящие физические интенсивности света (полуденное солнце около 100 000 люкс, а не произвольный ползунок яркости), фиксированную экспозицию и фиксированную конфигурацию тонемаппинга и bloom для каждой референсной фотографии. Смените тонемаппер, и любую воду можно подогнать под любое фото. Именно поэтому тонемаппер прибивают первым.
Drop-a-Mesh: плавать без домашки
Перетащите любой меш на водоём Numivo, и он сразу ведёт себя корректно: система автоматически строит физ-прокси, считает вытесненный объём за кадр из реальной высоты волны и выводит «плавает-или-тонет» из реальной плотности.
Под водой Numivo ведёт себя как настоящее место, а не как пост-процесс. Цвет поглощается с глубиной, свет фильтруется вниз лучами, а граница над головой должна пересекаться чисто, потому что озёрная референсная фотография существует, чтобы держать все три честными разом.
Бревно плавает и перекатывается на длинный бок. Ящик покачивается. Каменная статуя тонет. Никакого такелажа, никакой расстановки понтонов, никаких скриптов. Под капотом:
- форма коллизии автоматически вокселизируется, асинхронно и кэшируется по ассету, так что происходит лишь раз, чтобы измерить реальный объём объекта;
- плавучесть считается физически каждый кадр из вытесненного объёма против плотности воды, и пресная и солёная вода реально различаются (солёная плотнее, так что тот же ящик сидит в море выше, чем в озере);
- «плавает-или-тонет» идёт из плотности, масса делённая на объём прокси; нет галочки «должно ли это плавать?» по умолчанию, потому что по умолчанию это и есть физика;
- устойчивость возникает из того, как распределён объём прокси: ящики с тяжёлым верхом опрокидываются, корпуса с балластом в киле сами выпрямляются, доска лежит плашмя;
- плавающие объекты сцепляются обратно с поверхностью: рябь, кильватер, кольцо пены на линии воды и эффекты всплеска при ударе.
Есть маленькая панель на акторе для override'ов: заставить плавать, заставить тонуть, ползунок демпфирования, переключатели кильватера и всплеска. Но override масштабирует физику, а не заменяет её. Заставьте валун плавать, и он всё равно покачивается с правильным периодом и оставляет правильный кильватер; он просто ведёт себя, будто легче. Это различие важно: принудительные результаты, что игнорируют солвер, выглядят как пропы, приклеенные к плоскости, и игроки замечают это мгновенно.
Цель дизайна прямолинейна, и это демо, что мы хотим уметь показывать вживую: кто-то перетаскивает двадцать случайных пропов на море, и всё просто ведёт себя, не открыв прежде ни единого окна настроек. Если этому демо нужен туториал, фича провалилась.
Что она охватывает
Прибрежная вода, открытый океан, под водой и пещерные водоёмы (все первого класса): волны на основе спектров с раздельными зыбом и перекрёстной волной, пена от реально разбивающихся волн, каустики, что питают подводные лучи света, и устойчивость под кинематографическими эффектами.
Детали, что важны, если вам важна вода:
- Волны идут из океанографических спектров (тех же статистических моделей, что описывают реальные моря), с направленным разбросом и независимо управляемым зыбом. Состояние моря становится погодным решением (например, «нарастающий шторм, длинный зыб с запада») вместо тридцати несвязанных ползунков, что вы крутите, пока не станет штормово.
- Пена — не нарисованная маска. Она рождается там, где волны реально разбиваются, стареет со временем и тянет полосы по ветру. Нарисованная пена выдаёт фальшивую воду быстрее всего, потому что не движется с той физикой, что должна изображать.
- Под водой ведёт себя как настоящее место. Корректное поглощение цвета по глубине (красный уходит первым, затем зелёный, оставляя глубокий синий, знакомый всем по видео погружений), лучи света, выведенные из того же каустического поля, что освещает дно, и переход на линии воды без классической жёсткой полосы артефакта.
- Пещерные водоёмы получают собственную обработку: стоячая или едва движущаяся вода, возмущения от капель, отражения в полутьме, потому что спокойный внутренний водоём обнажает иные ошибки, чем открытый океан.
- Синематики — критерии приёмки, а не запоздалая мысль. Поверхность должна оставаться устойчивой под глубиной резкости, motion blur и зерном плёнки: никаких спекулярных fireflies, что появляются лишь с зерном, никакого мерцания, что медленная камера превращает в стробоскоп.
Почему плавучесть — та часть, что все пропускают
Облик можно подделать хорошим шейдером, а поведение — нет; убедительное «плавает-и-тонет» требует оценки объёма в реальном времени и устойчивого солвера, что по-настоящему трудно, поэтому большинство систем выдают префаб лодки и останавливаются.
Неудобная инженерная правда в том, что красивый шейдер воды давно решён, а вот общий солвер плавучести — нет. Подделать облик волны можно текстурой и нормалями, а корректная посадка произвольного, никогда прежде не виданного меша в этой волне требует физики, что должна работать на частоте кадров, переживать быстрые шаги времени и не взрываться, когда камень из тысячи треугольников встречает штормовой зыб. Именно из-за этого разрыва «вода» в большинстве движков означает «красивую плоскость, с которой нельзя взаимодействовать», а интерактивная часть, когда она есть, оказывается сделанной вручную лодкой.
Закрыть этот разрыв, то есть сделать поведение таким же автоматическим, как облик, — вот причина, по которой существует проект, и причина, по которой ему нужна дисциплина референсных фото плюс настоящий солвер, а не выходные за шейдером.
Когда вы сможете это использовать?
Она в разработке как расширение Unreal Engine, со ступенчатым выкатом: кинематическое превью плавания приходит до полного физ-солвера, чтобы сцены можно было населять рано. Мы не объявляем дату; референсные изображения решают, когда готово.
Ступенчатость намеренна. Кинематическое превью (объекты следуют поверхности волны без полной симуляции сил) приходит первым, чтобы художники могли бросать меши и населять море, пока тяжёлый солвер ещё закаляется, так что вы чувствуете результат задолго до финализации физики. Полный солвер, авто-прокси и полная панель следуют. Прогресс и вехи появляются на публичной дорожной карте, а не в сюрпризе дня запуска.
Набор инструментов, рядом с которым она выйдет (скаттер, mesh blending, гриды, измерение), бесплатен для пробы сегодня. Если хотите, чтобы вас уведомили в момент появления публичного билда воды, Discord, ссылка на который есть на сайте, — место, где это объявят первым, и где сравнения «прошло/не прошло» референсных изображений будут публиковаться по мере появления.
Мини-FAQ
Потребует ли она другие инструменты Numivo? Нет — это расширение той же семьи, спроектированное стоять самостоятельно. Оно, впрочем, разделяет тот же принцип: результаты запекаются в нативные данные движка везде, где физически возможно, так что вам принадлежит то, что вы создаёте.
Какие версии движка? Актуальные релизы Unreal Engine 5. Детали лягут на дорожную карту по мере приближения расширения к публичному билду, а не будут обещаны сейчас и пересмотрены позже.
Чем это отличается от встроенной воды движка? Встроенные системы воды сильны обликом и слабы общей интерактивностью: плавучесть обычно отдельный, вручную настроенный компонент. Весь смысл здесь в том, что облик и поведение идут из одной физически обоснованной системы, а гейт референсного фото держит облик честным сквозь освещения.
Зачем объявлять до релиза? Потому что метод референсной фотографии сам по себе и есть суть. Мы предпочитаем показать планку публично и быть измеренными по ней, чем раскрыть готовую вещь, которую никто не смог бы изучить. Этот пост и есть та планка, письменно. Спрашивайте с нас.