Communitygithub.com

Bloodrabbid/head-modeling

Моделирование и разбор 3D-головы/лица: принципы формы и топологии, студийный пайплайн, сборка game-ready головы в Blender по референсу на базовом меше MakeHuman (или с нуля скриптом), LOD, экспорт и проверка чужой модели.

What is head-modeling?

head-modeling is a Claude Code agent skill that моделирование и разбор 3D-головы/лица: принципы формы и топологии, студийный пайплайн, сборка game-ready головы в Blender по референсу на базовом меше MakeHuman (или с нуля скриптом), LOD, экспорт и проверка чужой модели.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Bloodrabbid/head-modeling/tree/HEAD

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Голова: моделирование, скульпт, 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 тыс. Перед тем как называть цифры как актуальные, проверь их поиском.

Студийный пайплайн

  1. Референсы (фас, профиль, три четверти, одно фокусное).
  2. Блокаут — почти всегда от базовой сетки с готовой топологией и UV.
  3. Скульпт (ZBrush, Blender, Nomad).
  4. Ретопология (Maya Quad Draw, Blender, TopoGun) или враппинг базовой сетки на скан (Wrap).
  5. UV → запекание (Marmoset, Substance Painter) → текстуры (Substance Painter, Mari; микрорельеф из сканов кожи).
  6. Глаза, зубы, язык, ресницы, волосы карточками.
  7. Риг: кости + блендшейпы. 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 и правь там.

  1. Форма. .target — список «индекс вершины, смещение»; вершины = база + Σ вес × смещение. Сначала макро-морфы (пол, возраст, этнос), потом детали: нос, губы, скулы, подбородок, глаза. Единицы MakeHuman — дециметры, Y вверх: в Blender это (x, −z, y) × 0,1.
  2. Ориентиры без разметки. Вершина, которую морф двигает сильнее всего, и есть ориентир этого морфа (уголок рта, крыло носа, кончик носа). По ним считай пропорции в долях межзрачкового расстояния и сверяй с референсом. Помни: скриншот с близкой камеры искажён перспективой — подбери свою камеру под кадр (дистанция, фокусное), а не сравнивай с ортографией.
  3. Прокси. .mhclo привязывает каждую вершину прокси к трём вершинам базы (барицентрические веса + смещение в масштабе). Пересчитывай прокси после каждого изменения формы и для каждой мимической формы.
  4. Мимика. Мимические юниты — те же .target. Собери из них ключи с именами ARKit. Ресницы и брови следуют за кожей; зубы — твёрдое тело: верхняя дуга неподвижна, нижняя и язык поворачиваются жёстко (преобразование найди методом Кабша по нижней дуге). Не переноси на зубы смещения кожи — они растянутся.
  5. Срез шеи — bmesh.ops.bisect_plane на 4–5 см ниже подбородка: сохраняет UV и слои форм. Начало координат — центр среза.
  6. Атлас. UV базы рассчитаны на всё тело. Найди острова, лицевой поверни и отдай ему верхнюю половину, остальные упакуй ниже, текстуру кожи пересчитай через map_coordinates. Проверь, какую долю атласа занимают черты лица, — полость рта и затылок не должны с ними сравниваться.
  7. 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 — разборы персонажей и гайд по запеканию нормалей

Related Skills