ヘッド:モデリング、スカルプト、ゲームレディ
3つのモードがあります。まず、どれが必要かを判断し、それらを混在させないでください。
- 分析 — ユーザーが自分のヘッド(レンダリング、メッシュ、ファイル)を提示し、何が問題かを理解したいと考えています。代わりに作成者は何も作成しないでください。以下のチェックリストを実行し、害の大きい順に欠陥を挙げ、それぞれについてどこに見えるか、手動で修正する方法を説明してください。
- 説明 — 「どのように行うのか」という質問。コードなしで、原理と手順の順序で答えてください。
- 組み立て — 「ヘッドを作成する」というリクエスト。まず、参照画像を入手してください。正面、横顔、斜めからのショットを依頼するか、自分で見つけることを提案してください。参照なしでは開始しないでください — 「誰でもない」顔になります。デフォルトでは、ベースメッシュのパス(以下のセクション)を進めてください。スクリプトを使用したゼロからの組み立ては、ユーザーが特にパイプラインの練習をしたい場合にのみ選択してください。事前に警告してください。スクリプトを使用すると技術的にクリーンなアセットが得られますが、ポートレートの類似性や表情の品質はアーティストの作業であり、スライダーやコードでは達成できません。
原理(簡潔)
形状。 ヘッドは頭蓋骨から構築されます。側面がカットされた脳頭蓋の球体に、顔のくさび部分と顎を加えたものです。ランドマーク:目のラインは頭の高さの中央。顔の3分割(髪の生え際 → 眉 → 鼻の付け根 → あご)。頭の幅は約5眼分、両目の間は1眼分。耳は眉と鼻の付け根の間。形状は、骨(眉弓、頬骨弓、眼窩縁、下顎角)、脂肪パッド、軟骨によって決まり、筋肉ではありません。まぶたは眼球にフィットし、唇は歯のアーチの円筒上にあり、耳は後方に傾き、頭蓋骨の後方から離れています。
スカルプト。 一次形状(シルエット、マス)→ 二次形状(頬骨、まぶた、鼻、唇、しわ)→ 三次形状(毛穴、しわ)。前のレベルがすべての角度からグレーマテリアルで読み取れるようになるまで、次のレベルに進まないでください。できるだけ長く低解像度を維持し、対称性は最後に崩してください。
トポロジ。 目と口の周りの同心リング。口のリングの1つはレッドリップの境界上にあります。鼻唇ループ。額の列。首のリング。ワーキングメッシュにはクアッドのみ。ポール(3つまたは5つのエッジを持つ頂点)は、可動性の低い場所(しわの上ではない)に配置してください。密度は、変形とシルエットが必要な場所に。口はメッシュ内部にバッグ状に沈み込み、まぶたには厚みがあり、目と歯は別個のメッシュです。
UVとベイク。 後頭部のシーム。耳と口のバッグは別々のアイランドに。顔により多くのテクセルを割り当てます。ベイク前とエクスポート前に同じ三角形分割を使用してください。タンジェント基底はMikkTSpace。ケージからのレイを使用し、スカルプトを包み込みます。Blender、glTF、Godot、Unity — ノーマルはOpenGL (+Y)。Unreal — DirectX。緑チャンネルを反転します。
テクスチャ。 光のないアルベド。ゾーン:額は黄色味が強く、顔の中央は赤みが強く、男性の顔の下部は寒色。粗さは均一ではありません:額と鼻はより滑らかで、唇は湿っています。AO、Roughness、Metallicは1つのORMテクスチャ(R、G、B)にパックされます。
表情。 FACS。ARKitシェイプ名(jawOpen、eyeBlinkLeft…)。トポロジの確認:口を開け、目を閉じ、笑顔を作ります。
バジェット。 MetaHumanの目安:ヘッドLOD0:24,000頂点、LOD1:12,000、LOD2:6,000、LOD3:2,500。インディーズやミディアムショットには3〜6,000トライアングルで十分。クローズアップや会話シーンには10〜25,000トライアングル。数値を実際のものとして提示する前に、検索で確認してください。
スタジオパイプライン
- リファレンス(正面、横顔、斜め、同じ焦点距離)。
- ブロックアウト — ほとんどの場合、既製のトポロジと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 で実行します。
4つのスクリプト:10_build(形状、プロキシ、表情、首のカット)→ 20_textures(アトラス、ベイク、マップ)→ 30_finish(マテリアル、LOD、エクスポート、レンダリング)→ 40_verify(逆インポート)。モーフのウェイトは config.json に保持し、そこで編集します。
- 形状。
.targetは「頂点インデックス、オフセット」のリスト。頂点 = ベース + Σ ウェイト × オフセット。最初にマクロモーフ(性別、年齢、民族)、次に詳細:鼻、唇、頬骨、あご、目。MakeHumanの単位はデシメートル、Yが上:Blenderでは(x, −z, y) × 0,1。 - ランドマークなしのランドマーク。 モーフが最も動かす頂点が、そのモーフのランドマークです(口角、鼻翼、鼻先)。これらを使用して、瞳孔間距離の割合でプロポーションを計算し、リファレンスと照合します。覚えておいてください:近距離カメラのスクリーンショットは遠近法で歪んでいます — オルソグラフィと比較するのではなく、フレームに合わせてカメラ(距離、焦点距離)を調整してください。
- プロキシ。
.mhcloは、プロキシの各頂点をベースの3つの頂点にバインドします(重心ウェイト+スケーリングされたオフセット)。形状変更のたび、および表情シェイプごとにプロキシを再計算してください。 - 表情。 表情ユニットも同じ
.targetです。これらからARKit名のキーを組み立てます。まつげと眉は皮膚に追従します。歯は剛体:上顎アーチは固定、下顎と舌は剛体回転します(下顎アーチからKabsch法で変換を見つけます)。皮膚のオフセットを歯に転送しないでください — 伸びてしまいます。 - 首のカット — あごの約4〜5cm下で
bmesh.ops.bisect_plane:UVとシェイプレイヤーを保持します。原点はカットの中心。 - アトラス。 ベースのUVは全身用に設計されています。アイランドを見つけ、顔のアイランドを回転させて上半分に配置し、残りを下にパックし、
map_coordinatesを使用して肌テクスチャを再計算します。顔の特徴がアトラスのどの割合を占めているかを確認してください — 口腔と後頭部はそれらと競合してはいけません。 - LOD。 Collapseデシメーション。シェイプキーは、最も近い元の頂点からのオフセットを転送することで戻します。剛体パーツ(歯など)の場合は、接続された各コンポーネントに剛体変換を適用します。デシメーション後、縮退した面を削除します。
編集サイクル:リファレンスと並べて3台のカメラでレンダリング → config.json の1つまたは2つの変更 → 再構築。メッシュをパッチするのではなく、ウェイトの原因を変更してください。
Blenderでのゼロからのスクリプト組み立て(ヘッドレス)
pip install bpy(Blender 5.2)、numpy、scipy、scikit-image、pillow でテスト済み。レンダリングとベイクはCPUのCycles。単位はメートル、Zが上、顔は−Y方向、あごはz=0、頭頂はz≈0,23。+Xはキャラクターの左側。
6つのスクリプトに分割し、各スクリプトの後にレンダリングを確認してください(PNGを読む):01_sculpt → 02_lowpoly → 03_bake → 04_textures → 05_finish → 06_verify。完全な再構築には約5分かかるため、結果をパッチするのではなく、原因を編集して再構築してください。
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 mm、下顎 105–115 mm、眼裂 ~29×10 mm、瞳孔間距離 ~64 mm。スムージングは幅を膨張させます — パラメータではなく結果を測定してください。
サーフェス:1mmグリッドで skimage.measure.marching_cubes、半分を計算してミラーリング。メッシュのボリューム符号を確認してください(正である必要があります):反転したノーマルは黒いAOと黄緑のノーマルマップを生成します。
2. ボックスモデリングによるリトポロジ
- 立方体 →
subdivide_edges(cuts=9, use_grid_fill=True)→ 面あたり10×10のグリッド。頭部中心からの方向は等角:tan(coord·π/4)。 - リング:パッチで
bmesh.ops.inset_regionを3回。目 — 前面の2×2パッチ、口 — 4×2、首 — 下部の6×6カットアウト。パッチの側面の中間ポイントが目と口の角になります。 - 耳:inset →
extrude_face_region→ 2回のinset。 - まぶたの厚みと口のバッグ:開口部の輪郭に沿って
extrude_edge_only。バッグの蓋は、クアッドを維持するために、中央の頂点を手動で収集して組み立てます。 - リングは、領域の内側の境界からの幅優先探索でマークします(頂点のintレイヤー)(「操作の前後」ではありません)。
- ポジション:内側のリングはカーブによって明示的に設定されます(まぶたのスリットは、カットアウトとまぶたの球の交点として数値的に計算されます。唇のラインは正面からの投影)。残りの頂点は、中心からサーフェスへのレイ、次に30回の反復「スムーズ+投影」。
- 展開はこの粗いケージ上で行います:シーム — 後頭部、立方体の前面の境界(顔のアイランド)、耳の基部、唇のライン。
uv.unwrap(method='MINIMUM_STRETCH')、顔のアイランド ×1,7、口のバッグ ×0,45、pack_islands。 - LOD:一度に1レベルのCatmull-Clark(
uv_smooth='PRESERVE_BOUNDARIES')。各レベルの後、スカルプトにフィットさせます。ケージ = LOD2、+1レベル = LOD1、+2 = LOD0。UVはすべて共通。
フィッティングレベル:
- メインマス — 頂点法線に沿って:セグメント±T(最初のレベルは16mm、2番目のレベルは7mm)で最も近い符号変化を見つけます。
- 鼻 — 正面からの標高マップとして:xとzはそのまま、yは正面からの投影を使用。
- 耳 — 勾配による投影、制限4mm。
- まぶたと唇の輪郭 — カーブ上に戻し、チェーンの頂点を順に均等に配置。
- 最後に、各頂点をミラーペアで平均化(cKDTree)。
3. ベイク
Triangulateモディファイア(SHORTEST_DIAGONAL)を適用したLOD0のコピー — これをベイクしてエクスポートします。scene.render.bake:use_selected_to_active、cage_extrusion=0.004、max_ray_distance=0.009、margin=16。マップ:NORMAL(4サンプル)、AO(24)、さらに最低ポリゴンメッシュの POSITION を margin=0 のfloat画像として — これはマスク用の「テクセル → 3Dポイント」マップです。
4. numpyでのテクスチャ
ポジションマップからマスクが計算されます:唇 — レッドリップカーブの間(メッシュのリングと一致)、眉 — 眉弓上のストライプ、カラーゾーン — 座標によるガウシアンとステップ、ノイズ — ランダム数値のグリッドによる3線形補間。見えない内部(口のバッグ、まぶたの裏側)はフィールドの符号で決定され、平坦なノーマルを取得します。アイランド周辺の領域は、最も近いカバーされたテクセルで埋められます(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を空のシーンにインポートし、測定:トライアングル数、寸法(メートル単位)、マテリアルとテクスチャサイズ、シェイプ名とインポート時の値(ゼロである必要があります)、縮退した面、ミラーペアのない頂点、0〜1の範囲内のUV、ベイクされたカバレッジに対するUVトライアングル面積の合計(不一致はオーバーラップを意味します)。
自身のチェック後、ファイルを独立したレビュアー(プロセスを見ておらず、READMEを信頼しないように依頼された別のエージェント)に渡し、自分でGLBを開くように依頼します。作成者のレンダリングは検証に代わりません。作成者はレンダリング前にシェイプをゼロに設定するため、ファイル内でシェイプが1になっていることに気づきません。
既に踏まれたレーキ
-
リファレンスなしでの作業。最初のヘッドが「マネキン」になったのはまさにこのためです。リファレンスとベースメッシュが最初のステップです。
-
肌の色は、レンダリングではなくテクスチャで確認してください。リファレンスのスクリーンショットは照明された色を示し、露出オーバーのレンダリングは別の方向に嘘をつきます。トーンは小さなステップで変更してください。
-
モーフを追加するときに、口の裏地が頬やあごからはみ出します。各シェイプについて、アウタースキンのBVHに対する頂点を確認し、1.5 mm押し込みます。裏地のアイランドは、面の数ではなくUV内の位置で見つけてください。
-
プロキシでは、左のキーが生きているのに右のキーが空になることがあります。欠落しているキーはミラーリングして構築し、移動量が0.5 mm未満のキーは破棄します。自動チェック:アクセサリの下の肌を0.5 mm以上動かすヘッドシェイプは、アクセサリにも存在する必要があります。
-
デシメーション後の最も近い頂点によるシェイプ転送は、上下の歯が閉じているときにそれらを混同します。剛体パーツのエッジ長の変化を確認してください — ゼロである必要があります。
-
眉の傾きモーフは名前が分かりにくく、ミリメートル単位で動かします。調整する前に、モーフが内側と外側の端をどこに移動させるかを計算してください。不機嫌なニュートラルは、ベースシェイプへの表情ユニットの寄与で治療します。
-
LODに口を開ける動作が含まれている場合は、舌と歯も含まれている必要があります。
-
FBXはORMを運びません:READMEで、マップはエンジンで手動で割り当てる必要があることを伝えてください。髪にはアルファマスクを設定し、ブレンドは設定しないでください。
-
他人の髪のテクスチャでは、未使用領域にロゴがある場合があります:UVトライアングルが触れていないテクセルを消去してください。
-
READMEは
verification.jsonに従って行ごとに確認してください。「すべてのパーツにキーが存在する」と「縮退した面が0」は、レビュアーによって反証されました。なぜなら、それはヘッドについてのみ真実だったからです。 -
削除後のbmeshの頂点インデックスは安定していません:新しい頂点が解放されたスロットを占有します。「新しい頂点 → 元の頂点」の関係はBMVertへの参照として保存し、インデックスは最後に取得してください。
-
bmesh.ops.extrude_face_regionは元の面を残します — それらは削除する必要があります。そうしないと、3で非多様体になります…