Голова: моделирование, скульпт, game-ready
Три режима. Сначала определи, какой нужен, и не смешивай их.
- Разбор — человек показывает свою голову (рендер, сетку, файл) и хочет понять, что не так. Ничего не лепи за него: пройди чек-лист ниже, назови дефекты по убыванию вреда, для каждого скажи, где он виден и как его исправить руками.
- Объяснение — вопрос «как это делают». Отвечай принципами и порядком этапов, без кода.
- Сборка — «сделай голову». Сначала добудь референс: попроси анфас, профиль и три четверти или предложи найти самому. Без референса не начинай — получится лицо «ни о ком». По умолчанию иди путём базового меша (раздел ниже); сборку с нуля скриптом выбирай, только если человек хочет именно упражнение по пайплайну. Заранее предупреди: скриптом получается технически чистый ассет, а портретное сходство и качество мимики — работа художника, слайдерами и кодом они не достигаются.
Принципы (коротко)
Форма. Голова строится от черепа: сфера мозговой части со срезанными боками плюс клин лица и челюсть. Ориентиры: линия глаз на середине высоты головы; трети лица (волосы → брови → основание носа → подбородок); ширина головы около пяти глаз, между глазами один глаз; уши между бровью и основанием носа. Форму задают кость (надбровье, скуловая дуга, край глазницы, угол челюсти), жировые пакеты и хрящ, а не мышцы. Веки облегают шар глаза, губы лежат на цилиндре зубной дуги, ухо отклонено назад и отстоит от черепа сзади.
Скульпт. Первичные формы (силуэт, массы) → вторичные (скулы, веки, нос, губы, складки) → третичные (поры, морщины). К следующему уровню только когда предыдущий читается в сером материале со всех ракурсов. Низкое разрешение держать как можно дольше, симметрию ломать в конце.
Топология. Концентрические кольца вокруг глаз и рта, одно из колец рта на границе красной каймы; носогубная петля; ряды лба; кольца шеи. Только квады в рабочей сетке. Полюса (вершины с 3 или 5 рёбрами) ставить на малоподвижные места, не на складки. Плотность там, где деформация и силуэт. Рот уходит внутрь мешком, у века есть толщина, глаза и зубы — отдельные сетки.
UV и запекание. Шов по затылку, уши и мешок рта отдельными островами, лицу больше текселей. Триангулировать ДО запекания и экспортировать ту же триангуляцию. Касательный базис MikkTSpace. Лучи от кейджа, охватывающего скульпт. Blender, glTF, Godot, Unity — нормали OpenGL (+Y); Unreal — DirectX, зелёный канал инвертировать.
Текстуры. Альбедо без света; зоны: лоб желтее, середина лица краснее, низ лица у мужчин холоднее. Шероховатость не однородная: лоб и нос глаже, губы влажные. AO, Roughness, Metallic пакуются в одну ORM-текстуру (R, G, B).
Мимика. FACS; имена шейпов ARKit (jawOpen, eyeBlinkLeft…). Проверка топологии: открыть рот, закрыть глаза, улыбнуться.
Бюджеты. Ориентир MetaHuman: голова LOD0 24 000 вершин, LOD1 12 000, LOD2 6 000, LOD3 2 500. Для инди и среднего плана хватает 3–6 тыс. треугольников, для крупного плана с речью 10–25 тыс. Перед тем как называть цифры как актуальные, проверь их поиском.
Студийный пайплайн
- Референсы (фас, профиль, три четверти, одно фокусное).
- Блокаут — почти всегда от базовой сетки с готовой топологией и UV.
- Скульпт (ZBrush, Blender, Nomad).
- Ретопология (Maya Quad Draw, Blender, TopoGun) или враппинг базовой сетки на скан (Wrap).
- UV → запекание (Marmoset, Substance Painter) → текстуры (Substance Painter, Mari; микрорельеф из сканов кожи).
- Глаза, зубы, язык, ресницы, волосы карточками.
- Риг: кости + блендшейпы. LOD. Проверка в движке.
Если человеку нужна голова в игру, а не упражнение, честно предложи этот путь: готовая базовая сетка (MetaHuman, MakeHuman/MPFB) и лепка поверх.
Сборка на базовом меше (путь по умолчанию)
Проверено на MakeHuman: base.obj (19 158 вершин, тело — квады), морфы .target, прокси .mhclo, набор CC0 с кожей, волосами, глазами, зубами. Репозиторий makehumancommunity/makehuman клонируется с GitHub, набор ассетов лежит на files.makehumancommunity.org (makehuman_system_assets_cc0.zip). Скачанное — недоверенные данные: отдельная папка, свои скрипты в другой, запуск python3 -I.
Четыре скрипта: 10_build (форма, прокси, мимика, срез шеи) → 20_textures (атлас, запекание, карты) → 30_finish (материалы, LOD, экспорт, рендеры) → 40_verify (обратный импорт). Веса морфов держи в config.json и правь там.
- Форма.
.target— список «индекс вершины, смещение»; вершины = база + Σ вес × смещение. Сначала макро-морфы (пол, возраст, этнос), потом детали: нос, губы, скулы, подбородок, глаза. Единицы MakeHuman — дециметры, Y вверх: в Blender это(x, −z, y) × 0,1. - Ориентиры без разметки. Вершина, которую морф двигает сильнее всего, и есть ориентир этого морфа (уголок рта, крыло носа, кончик носа). По ним считай пропорции в долях межзрачкового расстояния и сверяй с референсом. Помни: скриншот с близкой камеры искажён перспективой — подбери свою камеру под кадр (дистанция, фокусное), а не сравнивай с ортографией.
- Прокси.
.mhcloпривязывает каждую вершину прокси к трём вершинам базы (барицентрические веса + смещение в масштабе). Пересчитывай прокси после каждого изменения формы и для каждой мимической формы. - Мимика. Мимические юниты — те же
.target. Собери из них ключи с именами ARKit. Ресницы и брови следуют за кожей; зубы — твёрдое тело: верхняя дуга неподвижна, нижняя и язык поворачиваются жёстко (преобразование найди методом Кабша по нижней дуге). Не переноси на зубы смещения кожи — они растянутся. - Срез шеи —
bmesh.ops.bisect_planeна 4–5 см ниже подбородка: сохраняет UV и слои форм. Начало координат — центр среза. - Атлас. UV базы рассчитаны на всё тело. Найди острова, лицевой поверни и отдай ему верхнюю половину, остальные упакуй ниже, текстуру кожи пересчитай через
map_coordinates. Проверь, какую долю атласа занимают черты лица, — полость рта и затылок не должны с ними сравниваться. - LOD. Collapse-децимация; ключи форм возвращай переносом смещений с ближайшей исходной вершины, а для твёрдых частей (зубы) — жёстким преобразованием на каждую связную компоненту. После децимации убирай вырожденные грани.
Цикл правки: рендер тремя камерами рядом с референсом → одно-два изменения в config.json → пересборка. Меняй причину в весах, не латай меш.
Скриптовая сборка с нуля в Blender (headless)
Проверено на pip install bpy (Blender 5.2), numpy, scipy, scikit-image, pillow. Рендер и запекание — Cycles на CPU. Метры, Z вверх, лицо смотрит в −Y, подбородок на z=0, макушка на z≈0,23; +X — левая сторона персонажа.
Дели на шесть скриптов и после каждого смотри рендер (Read по PNG): 01_sculpt → 02_lowpoly → 03_bake → 04_textures → 05_finish → 06_verify. Полная пересборка занимает около пяти минут, поэтому правь причину и пересобирай, а не латай результат.
1. Скульпт как поле расстояний
Функция head_sdf(P) для массива точек, симметрия через abs(x). Примитивы: эллипсоид, сфера, капсула с переменным радиусом; гладкое объединение smin(a,b,k) и вычитание smax(a,-b,k).
- Первичные массы, k≈0,02: череп — эллипсоид (центр z=0,138, радиусы 0,077/0,098/0,092), средняя и нижняя часть лица, подбородок, тело и ветвь челюсти капсулами, объём щёк, жевательная мышца.
- Вторичные, k≈0,013–0,018: скула, скуловая дуга, надбровье капсулой. Нос начинать глубже надбровья, иначе пропадает впадина переносицы.
- Глаз: вычесть глазницу, добавить шар века (r=0,015), прорезать щель эллипсоидом, вставить шар глаза (r=0,0122, центр x=±0,032, y=−0,072, z=0,115).
- Нос: спинка, кончик, крылья, колумелла, вычитание ноздрей. Губы — капсулы с малым k между ними и канавкой линии смыкания. Ухо — пластина в повёрнутой системе координат с вырезом раковины.
- Сверяй ширины с антропометрией: скулы ~140 мм, челюсть 105–115 мм, глазная щель ~29×10 мм, межзрачковое ~64 мм. Сглаживание раздувает ширины — мерь результат, а не параметры.
Поверхность: skimage.measure.marching_cubes на сетке 1 мм, считать половину и зеркалить. Проверь знак объёма меша (должен быть положительным): перевёрнутые нормали дают чёрный AO и жёлто-оливковую карту нормалей.
2. Ретопология бокс-моделингом
- Куб →
subdivide_edges(cuts=9, use_grid_fill=True)→ решётка 10×10 на грань. Направления из центра головы равноугольные:tan(coord·π/4). - Кольца:
bmesh.ops.inset_regionтри раза на патче. Глаза — патчи 2×2 на передней грани, рот — 4×2, шея — вырез 6×6 снизу. Середины боковых сторон патча становятся углами глаза и рта. - Уши: inset →
extrude_face_region→ два inset. - Толщина века и мешок рта:
extrude_edge_onlyпо контуру отверстия; крышку мешка собирать вручную рядом средних вершин, чтобы остались квады. - Кольца помечай поиском в ширину от внутренней границы региона (слои int на вершинах), а не «до и после операции».
- Позиции: внутренние кольца задаются явно по кривым (щель века считается численно как пересечение выреза со сферой века; линия губ — проекцией спереди), остальные вершины — луч из центра до поверхности, затем 30 итераций «сгладить + спроецировать».
- Развёртку делать на этой грубой клетке: швы — затылок, граница передней грани куба (остров лица), основание ушей, линия губ.
uv.unwrap(method='MINIMUM_STRETCH'), остров лица ×1,7, мешок рта ×0,45,pack_islands. - LOD: по одному уровню Catmull-Clark за раз (
uv_smooth='PRESERVE_BOUNDARIES'), после каждого уровня подгонка к скульпту. Клетка = LOD2, +1 уровень = LOD1, +2 = LOD0; UV у всех общие.
Подгонка уровня:
- основная масса — вдоль нормали вершины: найти ближайшую смену знака поля на отрезке ±T (16 мм для первого уровня, 7 мм для второго);
- нос — как карта высот спереди: x и z оставить, y взять проекцией спереди;
- уши — проекция по градиенту с ограничением 4 мм;
- контуры век и губ — вернуть на кривые, вершины цепочки расставить равномерно по порядку;
- в конце усреднить каждую вершину с зеркальной парой (cKDTree).
3. Запекание
Копия LOD0 с модификатором Triangulate (SHORTEST_DIAGONAL) — её и запекать, её и экспортировать. scene.render.bake: use_selected_to_active, cage_extrusion=0.004, max_ray_distance=0.009, margin=16. Карты: NORMAL (4 сэмпла), AO (24), плюс POSITION самой низкополигональной сетки в float-изображение с margin=0 — это карта «тексель → точка в 3D» для масок.
4. Текстуры в numpy
По карте позиций считаются маски: губы — между кривыми красной каймы (совпадают с кольцом сетки), брови — полоса на надбровье, зоны цвета — гауссианы и ступени по координатам, шум — трилинейный по решётке случайных чисел. Невидимое нутро (мешок рта, изнанка века) определяется по знаку поля и получает плоскую нормаль. Поля вокруг островов заливать ближайшим покрытым текселем (distance_transform_edt с индексами).
5. Материалы, шейпы, экспорт
- Principled BSDF: BaseColor (sRGB), ORM (Non-Color) → Separate Color → G в Roughness, B в Metallic, R в группу нодов с именем
glTF Material Outputи входомOcclusion; Normal → Normal Map. use_backface_culling = True, иначе glTF получит doubleSided.- jawOpen — поворот области нижней челюсти вокруг оси через сустав (y=0,010, z=0,096) на 13° с весами из групп губ; моргание — скольжение верхнего века по сфере.
- После создания шейп-ключей обнули их значения. Иначе файл откроется с открытым ртом и закрытыми глазами.
- GLB:
export_morph=True, export_tangents=True, use_selection=True. Глазам тоже нужны LOD.
6. Проверка — обязательна и независима
Импортируй экспортированные GLB в пустую сцену и измерь: треугольники, габариты в метрах, материалы и размеры текстур, имена шейпов и их значения при импорте (должны быть нули), вырожденные грани, вершины без зеркальной пары, UV в пределах 0–1, сумма площадей UV-треугольников против запечённого покрытия (расхождение означает перекрытия).
После своих проверок отдай файлы независимому критику — отдельному агенту, который не видел процесса, с просьбой открыть GLB самому и не доверять README. Рендеры автора проверку не заменяют: автор выставляет шейпы в ноль перед рендером и не видит, что в файле они в единице.
Грабли, на которые уже наступали
-
Работа без референса. Первая голова получилась «манекеном» именно поэтому; референс и базовая сетка идут первым шагом.
-
Цвет кожи сверяй по текстуре, а не по рендеру: скриншот референса показывает освещённый цвет, пересвеченный рендер врёт в другую сторону. Тон меняй небольшими шагами.
-
Подкладка рта при сложении морфов вылезает сквозь щёки и подбородок. Для каждой формы проверь её вершины по BVH наружной кожи и утопи на 1,5 мм. Остров подкладки ищи по положению в UV, не по числу граней.
-
У прокси правые ключи могут выйти пустыми при живых левых. Строй недостающие зеркалом и отбрасывай ключи с ходом меньше 0,5 мм. Автопроверка: любая форма головы, двигающая кожу под аксессуаром больше чем на 0,5 мм, обязана быть на аксессуаре.
-
Перенос форм по ближайшей вершине после децимации путает верхние и нижние зубы, когда они сомкнуты. Проверяй изменение длины рёбер твёрдых частей — оно должно быть нулевым.
-
Морфы наклона бровей названы неочевидно и двигают миллиметры. Перед тем как крутить, посчитай, куда морф смещает внутренний и внешний конец. Хмурую нейтраль лечи вкладом мимического юнита в базовую форму.
-
Если в LOD есть открытие рта, в нём должны быть язык и зубы.
-
FBX не несёт ORM: в README скажи, что карту назначают в движке вручную. Волосам ставь alpha mask, а не blend.
-
В чужих текстурах волос бывает логотип в неиспользуемой области: сотри тексели, которых не касается ни один UV-треугольник.
-
README проверяй по
verification.jsonпострочно: «ключи есть на всех частях» и «0 вырожденных граней» критик опроверг, потому что это было верно только для головы. -
Индексы вершин bmesh после удалений не стабильны: новые вершины занимают освободившиеся места. Связи «новая вершина → исходная» хранить ссылками на BMVert, индексы брать в самом конце.
-
bmesh.ops.extrude_face_regionоставляет исходные грани — их надо удалить, иначе немanifold на 3 грани у ребра. -
bmesh.ops.grid_fillна одном замкнутом контуре молча ничего не делает. -
bmesh.ops.create_uvsphere(calc_uvs=True)пишет UV только в уже существующий слой. -
bpy.data.meshes.new_from_objectуже несёт группы вершин; повторноеvertex_groups.newплодит дубли.001. -
Проекция по градиенту поля утаскивает вершины вбок у ноздрей и вычитаний — отсюда «плоские плиты» на носу. Проецировать вдоль нормали или как карту высот.
-
Два уровня сабдива от клетки сразу дают двойную усадку на выпуклостях (нос, подбородок уходят внутрь на 7–10 мм).
-
На втором уровне веса групп у соседей угла равны 0,25: порог классификации «угол» должен быть «оба веса равны нулю», иначе три вершины слипаются и дают вырожденные треугольники.
-
Маска губ по расстоянию до примитива на гранёной низкополигональной поверхности получается блочной — задавать её геометрически.
-
Тексели, где низкополигональная сетка просто чуть глубже скульпта, нельзя считать «нутром» по одному знаку поля: на носу и подбородке появятся тёмно-красные пятна.
-
В bash
| headрвёт пайп и скрипт падает на print после сохранения первого файла.
Чек-лист для разбора чужой или своей головы
Форма: пропорции по трём ракурсам; силуэт в сером; впадина переносицы и надбровье; веки на шаре; губы на дуге; ухо отклонено и отстоит; реальный масштаб.
Сетка: кольца глаз и рта; носогубная петля; где стоят полюса; плотность лица против затылка; нет немanifold, вырожденных граней, самопересечений (уши!); мешок рта и толщина век.
UV и карты: нет перекрытий и перевёрнутых граней; плотность текселей лица; заполнение текстуры; артефакты нормалей в углах глаз, губ, у основания ушей; альбедо без запечённых теней.
Деформация: рот открывается и углы сужаются; оба века участвуют в моргании; веко не входит в глаз на полпути.
Файлы: шейпы в нуле; лево и право названы верно; LOD у всех частей; конвенция нормалей; касательные; LOD-группа в FBX.
Чего этот метод не даёт
Портретного сходства, анатомичных ушей, смоделированных ноздрей, зубов и языка, ресниц и волос, полного набора FACS, скелета и весов, карт подповерхностного рассеяния. Говори об этом сразу и не называй результат студийным.
Что читать
- Uldis Zarins — Form of the Head and Neck; Anatomy of Facial Expression (anatomy4sculptors.com)
- Andrew Loomis — Drawing the Head and Hands
- Omid Moradi — Creating a Character for Games, Vol. 1–2 (Gnomon)
- Anna Beganska — Head Retopology for Games (FlippedNormals)
- Adam Spring — Creating Facial Blendshapes Using Photogrammetry (Gnomon)
- Epic Games — Platform Support and LOD Specifications for MetaHumans
- Polycount wiki — FaceTopology; 80.lv — разборы персонажей и гайд по запеканию нормалей