Процедурный подход к обработке фотосканов
Прежде чем говорить об обработке фотосканов, давай разберёмся, что это вообще такое.
Если говорить очень упрощённо, фотоскан — это результат генерации полей глубины на основе множества фотографий одного объекта или сцены, снятых с разных ракурсов.
На первом этапе алгоритмы анализируют изображения, находят совпадающие точки и по разнице их положения между кадрами восстанавливают примерную глубину этих точек в пространстве.
В результате формируется облако точек, каждая из них имеет позицию в 3D-пространстве и соответствует определённой глубине относительно камеры.
Далее эти точки, находящиеся на схожей глубине и принадлежащие одним и тем же поверхностям, группируются и связываются между собой. С помощью специальных алгоритмов реконструкции поверхность восстанавливается уже не как набор отдельных точек, а как непрерывная геометрия — чаще всего в виде плотной треугольной сетки.
Именно на этом этапе облако точек превращается в привычную нам 3D-модель, пусть и крайне тяжёлую
И здесь важно понимать чем фотоскан не является, особенно это касается геймдева:
- Это не оптимизированный ассет;
- Это не production-ready модель;
- Это не «кинул в движок и работает».
Практический PBR-пайплайн под Unreal Engine и Unity
Цель этого пайплайна — получить чистый, воспроизводимый и проверяемый ассет, полностью готовый к использованию в Unreal Engine и Unity, без «перерисовывания» всего вручную или со сведением такого вмешательства к минимуму.
Прежде чем переходить к конкретным шагам обработки, важно чётко определить требования к финальной модели, которую мы хотим получить на выходе.
Требования к ассету
Финальная модель должна соответствовать базовым игровым конвенциям:- pivot расположен внизу модели;
- центр координат в (0, 0, 0);
- ориентация: +X — вперёд;
- масштаб сцены — сантиметры;
- ассет представлен единым объектом.
- движок не должен «догадываться», где у ассета низ и как он должен устанавливаться в сцене;
- ассеты должны быть взаимозаменяемыми, корректно снапиться и масштабироваться;
- физика, коллизии и LOD-система начинают работать предсказуемо;
- модель сохраняет реалистичный масштаб, независимо от проекта и движка.
Практическая обработка фотоскана
В качестве основного инструмента в этом пайплайне я буду использовать Houdini.
Этап 1. Приведение к реалистичному масштабу и корректному положению в сцене
Первый этап обработки фотоскана — нормализация трансформаций: приведение модели к реалистичному масштабу, корректное размещение в мировом пространстве и правильная центровка.
Нормализация трансформаций на старте пайплайна критична, потому что:- все последующие процедурные операции зависят от масштаба сцены;
- алгоритмы ремеша и UV чувствительны к размерам объекта;
- неправильный pivot усложняет экспорт, инстансинг и сборку сцен в движке;
- единый стандарт позволяет без правок переиспользовать ассеты между проектами.
Это принципиальный момент пайплайна:
- именно эта версия содержит максимально точную форму, полученную из фотограмметрии;
- она используется как источник деталей при запекании normal и AO;
- дальнейшая оптимизация, ремеш и упрощение выполняются поверх уже корректно отмасштабированной и отцентрированной геометрии.
Этап 2. Очистка и стабилизация геометрии фотоскана
На этом этапе на основе highpoly-модели формируется низкополигональная сетка, соответствующая требованиям к финальному ассету и его реальному масштабу.Ключевая задача здесь — получить управляемую, стабильную геометрию, сохранив при этом характер формы и основные силуэтные особенности фотоскана. Создание lowpoly-версии выполняется за счёт алгоритмов полигонального упрощения (poly reduction), которые позволяют:- существенно снизить количество полигонов;
- сохранить общий силуэт объекта;
- минимизировать искажения формы на уровне игровых дистанций;
- подготовить геометрию к дальнейшему ремешу, UV и запеканию.
Важно подчеркнуть, что уменьшение количества полигонов выполняется в контексте масштаба объекта: одинаковый процент уменьшения полигонов для объектов разного размера приводит к принципиально разному визуальному результату. Поэтому количество полигонов должно определяться не абстрактными значениями, а реальными габаритами ассета.
Дополнительно на этапе полиредуцирования можно создать маску плотности, которая позволит управлять тем, в каких зонах сетка должна сохранять большее количество полигонов.
Маска плотности может формироваться процедурно на основе:- кривизны поверхности (curvature);
- нормалей и углов между полигонами;
- высоты или положения в пространстве;
- локального масштаба деталей;
- пользовательских атрибутов или ручной подправки.
- отказаться от равномерного и «слепого» упрощения;
- получить более эффективное распределение полигонов;
- сохранить визуальное качество при меньшем общем поликаунте (polycount);
- сделать результат воспроизводимым и масштабируемым для всей библиотеки ассетов.
Этап 3. UV-развёртка
На этом этапе мы переходим к работе с UV, так как развёртка, полученная на стороне программ фотограмметрии, не подходит для production-использования по ряду причин:- неравномерная плотность;
- сильные искажения;
- неконтролируемые швы;
- отсутствие единого стандарта texel density.
Поэтому UV создаётся заново, уже в контексте требований игрового пайплайна.
Для построения корректной UV-развёртки в Houdini используется набор из четырёх базовых инструментов:- AutoUV. Используется для первичного разрезания геометрии и генерации базовой развёртки с минимальным ручным вмешательством.
- Remove UV Distortion. Применяется для устранения растяжений и сжатий, неизбежно возникающих при автоматической развёртке, и для выравнивания распределения UV по поверхности.
- Texel Density. Позволяет привести всю модель к заданной плотности — в нашем случае 1024 px/м, с возможностью локальных отклонений в рамках заданных правил.
- UV Layout. Финальный этап упаковки UV-островов с учётом:
- ориентации;
- отступов (padding);
- возможных оверлапов;
- тайлинга и trim-подходов.
- объект не использует всю доступную UV-площадь;
- оставшееся пространство не даёт прироста качества;
- плотность текстур уже соответствует заданному стандарту.
- объединить несколько ассетов в один UV-атлас;
- сохранить целевую texel density для каждого из них;
- сократить количество вызовов отрисовки (draw calls);
- более эффективно использовать разрешение текстур.
Особенно это актуально для небольших сканов, пропсов одного набора и модульных элементов окружения.
Этап 3,5. Про texel density
Texel density определяется двумя ключевыми параметрами:- разрешением текстуры;
- реальными размерами объекта в мире.
Важно понимать, что texel density не существует в вакууме. Он всегда привязан к условиям использования ассета.
Выбор плотности текстур имеет смысл только в контексте:
- реального размера объекта;
- его расположения в сцене;
- дистанции, с которой игрок будет его видеть;
- частоты появления в кадре.
- может требовать высокой плотности, если он находится рядом с камерой;
- и может обходиться значительно меньшей, если он всегда расположен на фоне.
Поэтому универсальные значения без учёта контекста быстро приводят либо к перерасходу памяти, либо к потере качества.
Практический подход к выбору плотности
Чтобы не выбирать texel density интуитивно, я использую кастомную mip-map систему, которую разработал специально для этой задачи.
Суть подхода следующая:- текстура заранее разбивается на контролируемые уровни детализации;
- каждый уровень соответствует определённому расстоянию и размеру объекта в кадре;
- визуально можно определить, какое разрешение реально используется движком при заданных условиях.
- понять, какой mip-уровень будет доминирующим в реальном геймплее;
- определить, имеет ли смысл использовать 4K, 2K или 1K текстуры;
- выбрать texel density, исходя из фактического отображаемого качества, а не теоретических максимумов.
В результате texel density становится расчётным параметром пайплайна, а не субъективной настройкой конкретного художника.
Этап 4. Запекание текстур
Прежде чем запускать сам процесс запечки, необходимо корректно подготовить геометрию. Именно на этом шаге закладывается стабильность и воспроизводимость результата.
На этом этапе выполняются следующие действия:
- формирование корректных нормалей для lowpoly-модели;
- проверка и, при необходимости, пересчёт сглаживания и hard edges;
- удаление всех неиспользуемых и вспомогательных атрибутов, оставшихся после процедурной обработки;
- приведение структуры геометрии к финальному виду без временных нод и служебных данных;
- задание корректного и однозначного имени ассета в соответствии с пайплайном;
- сохранение модели в финальном виде для дальнейшего использования.
- ошибки в нормалях напрямую приводят к артефактам на normal map;
- лишние атрибуты могут вызывать некорректный экспорт или увеличивать вес данных;
- неправильные имена усложняют автоматизацию и пакетную обработку;
- чистая и зафиксированная версия модели позволяет повторять запекание без расхождений в результате.
Процесс запекания
Сам процесс запекания текстур я намеренно опущу, так как в данном случае он не отличается от стандартного production-подхода и не содержит специфических нюансов, связанных именно с фотосканами или Houdini-пайплайном.Вместо этого я приведу базовые настройки, которые использую в Marmoset Toolbag как отправную точку. Эти параметры можно рассматривать как надёжный дефолт, от которого удобно отталкиваться и адаптировать под конкретные задачи и типы ассетов.
Roughness
Roughness не бейкается из геометрии и не должна восприниматься как производная от normal или AO.
В данном подходе roughness генерируется отдельно и процедурно, как самостоятельное физическое свойство материала.
Базовый инструмент — Substance Sampler
Для генерации roughness используется Substance Sampler, в частности следующие подходы:- B2M (Base Color → Roughness). Позволяет получить первичную roughness-карту на основе цветовой информации, сохраняя связь с реальными материалами.
- AI Powered Surface Analysis. Используется для автоматического анализа поверхности и восстановления вероятных физических характеристик материала.
- Микс нескольких вариантов. Итоговая roughness-карта формируется как комбинация алгоритмического результата, AI-анализа и дополнительных корректирующих слоёв.
Дополнительная ручная доработка
Для финальной стабилизации и контроля roughness применяются классические инструменты в Photoshop:- ручные маски для локальных зон;
- Camera Raw Filter для общей тональной балансировки;
- High Pass для возврата микро-контраста;
- работа с уровнями по отдельным каналам для точной настройки диапазонов.
Важно, что эти правки не носят «рисовательный» характер — они используются для коррекции физических диапазонов, а не для декоративных эффектов.
Этап 5. Сборка материала в Substance Painter
В данном пайплайне Substance Painter не используется как инструмент рисования. Его роль — узел сборки и финальной стабилизации PBR-материала.
Импорт карт
В Painter импортируется уже сформированный набор текстур:- Base Color;
- Normal;
- Ambient Occlusion;
- Roughness;
- Metallic (при необходимости).
Финальный корректирующий слой
Для финальной стабилизации материала используется smart material типа Polishing Improvements. Его задача:
- выровнять микроконтраст;
- убрать эффект «пластиковости»;
- стабилизировать поведение roughness под разным освещением.
Микрорельеф и вариативность
При необходимости добавляется контролируемый микрорельеф:
- микро-normal карты;
- дополнительная roughness-variation;
- процедурный noise из Substance Sampler.
Микродетали должны:
- работать на читаемость материала;
- проявляться только при нужных углах и освещении;
- не конфликтовать с основной формой и roughness-логикой.
Этап 6. Импорт в движок
Финальный этап пайплайна — импорт ассета в игровой движок и проверка того, что все предыдущие решения действительно работают в реальном рендере, а не только в DCC-инструментах.
Импорт геометрии
При импорте модели в Unreal Engine или Unity проверяются следующие моменты:корректный масштаб (сантиметры);
- правильная ориентация осей (+X вперёд);
- pivot расположен внизу модели;
- отсутствие лишних трансформаций;
- единый объект без служебной геометрии.
Импорт текстур и материала
Текстуры подключаются в соответствии с PBR-моделью движка:
- Base Color — без коррекции гаммы;
- Normal — в корректном формате для конкретного движка;
- Roughness, Metallic, AO — с правильными цветовыми пространствами;
- проверка диапазонов значений и отсутствия клиппинга.
Материал собирается строго функционально, без художественных компенсаторов ошибок предыдущих этапов.
Проверка в сцене
На этом цикл обработки фотоскана можно считать завершённым.
Вместо заключения — немного о Nanite
Сегодня в Unreal Engine у нас есть Nanite, и он действительно сильно упрощает работу с геометрией, позволяя использовать значительно более плотные сетки, чем это было возможно раньше. Однако важно понимать: Nanite — не панацея и не замена полноценному пайплайну обработки фотосканов.Даже при использовании Nanite:
- ассет всё равно должен иметь корректный масштаб, pivot и ориентацию;
- UV и texel density по-прежнему критичны для работы материалов;
- качество normal, roughness и base color напрямую влияет на финальный результат;
- фотоскан без очистки и стабилизации остаётся тяжёлым, шумным и плохо управляемым.
Поэтому правильная обработка фотосканов была, есть и будет необходимой.