scenario-blender-hair について
Blender 5.2でヘアカーブや毛皮を作るアーティストやエージェント向けのスキルです。ガイドによる形作り、マスク付きのプロシージャルレイヤー、品質確認を組み合わせます。
主な機能
- 01ヘアガイドの計画と配置
- 02マスク付きプロシージャルレイヤーの構築
- 03UV、根元、間隔、密度の確認
- 04高密度レンダーとポーズのレビュー
- 05グルームのゲーム用カード化
活用シーン
- 01毛束や浮き毛のある動物の毛皮作成
- 02分け目に沿った人間の髪型作成
- 03変形時のグルームの確認
- 04ゲーム書き出し用ヘアカードの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-blender-hairインストール後、Claude Code で/scenario-blender-hairを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdprocedures.mdsources.mdscripts/bx_hair.py詳細
毛髪と毛皮のグルーミング(ヘアカーブ、Blender 5.2)
エキスパートによるグルーミングでは、方向とシルエットを決めるガイドを少数、均等に配置します。マスクを適用したプロシージャルレイヤーを重ねて、密度、束化、縮れ、長さのばらつき、飛び出した毛を加え、ポーズを付けた状態で、ライティング済みのレンダーを最大密度で確認します。ガイドはデータとして作成してください(5.2.1ではカーブブラシのストロークをスクリプト化できません)。見た目に関する判断はすべて、Essentials のヘアノードグループアセットを通じて行います。ここで名前が挙がっている関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください
(npx skills add scenario-labs/skills --skill <name>)。無人で作業を進める場合は、ツールスキーマに従って作業を続け、スキルがないことを明記してください。
必須の前提知識: scenario-blender-expert(実行チャネル、レビューループ、5.2 API の変更)。
方針(エキスパートが重視する点)
- すべての方向が正しくなるまでは、ガイドを2点にします(Schmidbauer)。点を増やすと、コーミングが絡まり、クリップしやすくなります。短い毛皮では3点、長い毛髪でのみ8点を使用します。Bystedt は、長い人間の髪を成形する前に15点へリサンプルします。
- ガイドを均等に配置し、必ず Interpolate にマスクを適用します(Schmidbauer)。子毛は表面全体に生成されるため、ガイドから遠い子毛は「好き勝手な方向に伸びます」。隙間は、変形時に広がる薄毛部分になります。
- 密度は平方メートルあたりで数えられるため、非常に大きな値にする必要があります(Thommes)。長い毛皮では、半径を約0.2 mmにして、1,000,000/m²を使用します。Viewport Amount は4%に設定して作業します。
- ランダム化は点ごとではなく、カーブごとに行います(Thommes)。毛束の80%には縮れを加えないようにします。飛び出した毛は、カーブの10%に強いノイズを加えて作ります。
- Replace Length をオフにし、Random Offset を加えてトリミングします(Schmidbauer、Thommes)。これは最小限の作業でリアリティを高める方法です。短い毛の領域でガイドが失われて禿げないよう、マスクを適用してください。
- 人間の髪型は、生え際に沿って分割した別個のヘアキャップ上で作ります(Bystedt)。これにより、ボディのトポロジーを気にする必要がなくなり、補間が分け目をまたがなくなります。ただし、分け目には密度を追加し、毛を立ち上げる必要があります。
- Shape はどのアセットでも同じように機能します:1では先端だけ、0では毛束全体、負の値では根元に作用します。カールや毛束の先端を保つため、Frizz Shape には負の値を設定します(Thommes、Bystedt)。
- 最大密度で、ポーズを付けた状態のレンダーを確認します(Thommes、Schmidbauer)。メッシュが激しく変形すると、毛髪では「10倍ひどく見えます」。
最初に確認すること
| 入力 | 変更点 | 指示がない場合のデフォルト |
|---|---|---|
| 対象 | Cycles の毛束と EEVEE またはゲーム用カードのどちらを使うか | Cycles の毛束(Principled Hair BSDF) |
| 対象物 | 人間の髪型(ヘアキャップ、分け目)と動物の毛皮(ボディメッシュ、目印)のどちらか | 参考資料に従う |
| 長さの種類 | ガイドあたりの点数、毛束化とカールのレイヤー | 短い毛皮:3点、長い毛皮:8点、長い人間の髪:15点 |
| 変形 | アニメーションがある場合は Hair Dynamics(Animation)を最後に配置し、ポーズを付けて確認 | アニメーションあり |
| 予算 | レンダリング用カーブ、カードの三角形数 | 最大密度で評価されるカーブ数を指定 |
| 参考資料 | 同じ亜種、季節、できれば同じ個体(Schmidbauer) | 依頼し、まず目印と毛の流れを描く |
毛のグルーミングを始める前に、トポロジーを仕上げ、重ならない UV を作成してください(毛髪は UV 空間に固定されます)。また、スケールを適用してください。密度はメッシュのローカルな面積に基づいて計算されます(確認済み)。
ワークフロー
| タスク | ヘッドレス | ライブセッション |
|---|---|---|
| カーブオブジェクト、サーフェスへのバインド、データとしてのガイド、スナップ、細分化または再サンプリング、アセットモディファイアー、入力、マスク、カウント、レンダー、カード | はい(scripts/bx_hair.py) | はい。オブジェクトモードで同じコードを使用します |
スカルプトカーブに入り、11 種類のカーブブラシを有効化し、ブラシ設定を行い、sculpt_curves.select_randomを実行する | 該当なし | はい(bx_gui.activate_brush("SCULPT_CURVES", "Comb")) |
| コーム、追加、密度、成長/縮小、先端を引っ張るストローク | いいえ | いいえ。sculpt_curves.brush_strokeにはexecがないため、bx_gui.stroke("SCULPT_CURVES", ...)はPASS_THROUGHを返し、何も変更しません。ブラシを設定してユーザーにストロークしてもらうか、以下の代替手段を使用してください。 |
- サーフェスを準備します。
H.uv_report(surface):UVが重なっているとカーブがリグを無視します。UDIMは問題ありません。ミラーの継ぎ目がマージされていない場合は、「距離でマージ」を使用します(Schmidbauer)。人間の場合:分け目に沿ってアイランドに分割したヘアキャップを用意します。動物の場合:口の内側を分離します。マスクには頂点グループ(高速)またはテクスチャ(ローポリメッシュで細部を表現)を使用します。ゲート:overlap_faces == 0、スケールが適用済み、領域ごとにマスクが1つ。 - 流れとオブジェクトを計画します。 描き込みを領域(頂点グループ)に分け、それぞれに1つの流れの方向を設定します。Schmidbauer:パフォーマンスを高めるため、ランドマーク(顔、頬、耳、首、胴体、尾、足)ごとにカーブオブジェクトを1つ用意します。Thommes:マスクを使用してオブジェクトを1つにまとめます。Bystedt:一方をコーミングするともう一方が乱れる箇所では、前面と背面に分けます。ゲート: 領域、流れ、オブジェクトの一覧を書き出します。
- ガイドを設定します。
hair = H.new_groom(surface)、P, N = H.sample_roots(surface, spacing, mask=...)、H.add_guides(hair, P, N, length, points=2, flow=..., flow_blend=...)(スナップし、surface_uv_coordinateを書き込みます)。後から、H.subdivide_guidesまたはH.resample_guides(hair, 15)を使います。ブラシの代替手段:コームには方向フィールド、重力にはdroop、密度と追加にはガイドを削除して再追加します。Bystedtの「長く伸ばして、コーミングし、元の長さに戻す」手法では、長いガイドとトリムを使います。ゲート:H.groom_reportで、roots_off_surfaceとspacing_gaps_2xが0、length_outliersも0であること。ガイドのみのレンダーで、すべての方向が正しく見えること。 - 密度を設定します。 まず「ヘアカーブプロファイルを設定」を追加し、次に密度マスクを指定して「ヘアカーブを補間」を追加します。Bystedtは50%グレーで塗り、分け目を100%にしてから再マッピングします。5.2の「補間」ではマスクテクスチャ画像も指定できます。ゲート:
H.count(hair)(最大密度)が予算内で、root_area_fractionが0.5を大きく下回り、レンダーに毛のない箇所がないこと。 - プロシージャルレイヤーを設定し、それぞれにマスクを適用して、
show_viewportを切り替えながらレンダーし、A/Bテストします。- 長い毛皮(Thommes、プリセット
H.FUR_STACK_LONGをH.build_stackで適用):ノイズ、カール、はね毛、負のシェイプを使った縮れ、束、束2、最後に縮れ(累積をオフ)、トリム、回転。 - 動物(Schmidbauer):トリム、束(頬、先端の広がり、束のオフセット)、弱い縮れを設定し、それぞれに専用の頂点グループを割り当てます。
- 人間(Bystedt):ガイドにノイズを適用(累積をオフ、カーブごとのオフセットをオン)、先端のみにロールを適用し、その後、グルーミングしたガイドに対して、個体群ごとに補間、プロファイル、束を設定します。幅の広いレイヤーと細いレイヤーには異なるシードが必要です。
- カーブごとのランダム性:
H.random_curve_mask(hair, "frizz_mask", 0.8)の後に入力として"attr:frizz_mask"を指定します。根元から先端へのランプにはH.along_curve_attrを使います。ゲート: 各レイヤーがA/Bレンダーで採用に値すること。
- 長い毛皮(Thommes、プリセット
- 分け目と生え際(人間の場合)を設定します。 「分け目をメッシュアイランド単位で処理」はオンのままにします(デフォルト)。テストでは、アイランド単位の処理がオフの場合、分け目付近の子毛の21%が分け目を越えましたが、オンの場合は0%でした。持ち上げには、
H.distance_weights(cap, "part_lift", "part", radius, "bump")を「ヘアカーブを変位」に渡します(サーフェス法線をオン、距離を小さく、シェイプを0付近にし、係数にattr:part_liftを指定)。ゲート: 上面図で分け目に頭皮の隙間がなく、頭頂部が平らでないこと。 - シェーディングとレンダーを設定します。
H.hair_material(name, "CYCLES", melanin=(root, tip))または明示的な色を指定した"EEVEE"を使い、その後H.setup_render(scene, engine, close_up)を実行します。ゲート:H.review([surface, hair], out, engine)がreferences/critique.mdを満たすこと。 - 変形を設定します。 極端なポーズを2つか3つキー設定し、同じカメラから各フレームをレンダーします。ゲート: どのポーズでも毛のない箇所やクリッピングがないこと。
- ゲーム用:カードを作成します。
H.add_cards(hair, width, material=H.card_material(...))を実行し、続いてコピーをobject.convert(target='MESH')で変換してglTFをエクスポートします。カードの下にはテクスチャ付きのヘアキャップを配置します。ゲート: 三角形の数が予算内で、カードのUVが半タイル内に収まり、根元が頭皮上にあること。
数値
| 項目 | 値 | 比較対象、出典 |
|---|---|---|
| ガイドポイント | 配置中は2、短い毛は3、長い毛は8 | Schmidbauer [00:20:24], [00:21:34] |
| 人間の長い髪 | 15ポイントに再サンプリング | Bystedt [00:08:38] |
| ブラシの長さを追加 | 毛皮では約0.01 m(デフォルトは0.3 m) | Schmidbauer [00:17:59] |
| 密度、人間のレイヤー | 1 m²あたり、房の数は5,000 | Bystedt [00:17:28] |
| 密度、長い毛皮 | 1,000,000/m²、半径0.2 mm、ビューポート4% | Thommes [00:09:02], [00:16:44] |
| 密度マップ | 分け目1.0、ベース0.5、毛のない部分0;ランプの黒い停止点は0.5より少し上 | Bystedt [00:22:04], [00:23:46] |
| 幅広の房 | Shapeは約0.3、Factorを下げ、ガイドをグルーミング | Bystedt [00:19:47] |
| カール | Radius 2 cm、Curl Start 1、Random Offset 0.5、Guide Distance 1 cm、Guide Mask 0.2 | Thommes [00:12:04], [00:14:18] |
| 小房 | Guide Distance 1 mm、Mask 0.1;レイヤー2:4 mm、0.25、Clump Offset 5 mm | Thommes [00:16:12], [00:31:01] |
| 縮れ | 2 mm、Shapeは負の値;最終値:-0.2、Cumulativeはオフ、カーブの20%に適用 | Thommes [00:15:04], [00:32:08], [00:26:03] |
| 乱れ毛 | カーブの10%、Noise distance 5 mm | Thommes [00:30:28] |
| トリム、回転 | Replace Lengthはオフ、Random Offset 5 mm;Rotateはランダムに5° | Thommes [00:22:20] |
| カードの細分化 | カードの長さ20 cmごとに1 | Bystedt g_ZIOafq4QU [00:05:08] |
| カードとチューブの断面 | 円弧:1セグメントは平坦、推奨は3;チューブ:平坦な螺旋、解像度6、1回転、高さ0 | Matsumoto [00:19:54], [00:22:40] |
| カードのUV幅 | カードはチューブのタイルの半分を使用 | Matsumoto [00:31:27] |
| カバレッジの妥当性確認 | 密度 × π × 半径²:Thommesの毛皮では0.13 | [added] check |
品質ゲート
コード内:
import sys; sys.path.append("<skills>/scenario-blender-hair/scripts"); import bx_hair as H
print(H.uv_report(surface)) # overlap_faces == 0
rep = H.groom_report(hair); print(H.verdict(rep)) # [] or a list of fixes
print(H.count(hair)) # full-density curves and points vs budget
print(H.card_stats(hair)) # cards: tris, UV range
groom_report は、アタッチメントUV、表面上のルート、間隔の隙間、長さのへこみ(近隣より50%超短いもの)、Hair Dynamicsが最後にあること、Trim Replace Length、マスクされていないFrizzまたはNoise、Density Maskの欠落、半径と密度の関係、Strandの表示、EEVEEでのCycles用ヘアシェーダーをチェックします。
見た目の確認:H.review(objs, out, engine, views=("front", "threequarter", "top")) は、Thommesのリグ(暖色のトップフィル、サイドキー、寒色のリム、暗い青みがかったワールド)を使い、密度を最大にした照明付きのシートをレンダリングします。references/critique.md に従って、毛のない部分、分け目のカバレッジ、房、乱れ毛、長さのばらつき、毛先、根元から毛先への色、ハイライトを評価します。
よくある間違い
| 間違い | どのように見えるか | 修正 |
|---|---|---|
| ブロッキング中にブラシのデフォルトである 8 ポイントを使用する | もつれ、クリッピング、コーミング時の引っかかり | 2 ポイントにして、後から増やします(Schmidbauer) |
| Density Mask を使わずに補間する | 口や目に毛が生えたり、子ガイドがガイドから大きく離れてずれたりする | 頂点グループマスクを使用し、口の内側を分離します |
| ガイドの間隔が不均一 | 地肌が見える部分ができ、ポーズ時に悪化する | sample_roots の間隔を調整し、spacing_gaps_2x を確認します |
| デフォルトの半径で密度を高くする | 塊状になる、または「ひどい状態」になる | まずプロファイルを調整します。1M/m² では約 0.2 mm です(Thommes) |
| デフォルト設定のままトリミングする | すべての毛束が 1 m の長さになる | Replace Length をオフにします(Thommes) |
| カールや毛束に正の Frizz を適用する | カールの先端が損なわれ、毛束の先端がふわふわになる | Shape を負にし、最後の Frizz では Cumulative Offset をオフにします |
| 同じシードでレイヤーを複製する | 幅の広い毛束と細い毛束が同じ位置に重なる | シードと頻度を変更します(Bystedt) |
| 毛先がまっすぐ | 「ひどい CG の髪」 | 毛先だけに Roll Hair Curves を適用します(Bystedt) |
| グルーミング後にサーフェスを編集する | 毛根が浮いたり、沈み込んだりする | snap_to_surface(hair, "DEFORM") を使うか、トポロジー変更後に NEAREST を使います |
| ビューポート密度 4% で判断する | 均一な毛束や長さのそろい具合を見落とす | 密度を最大にしてレンダリングします |
| EEVEE で Principled Hair BSDF を使う | 暗く平坦になる(中心輝度の測定値は 0.09 対 0.26) | 色を明示的に指定した Principled BSDF を使います |
| Comb ストロークをスクリプトで実行する | 何も起きず、PASS_THROUGH になる | 位置を書き込むか、ストロークをユーザーに任せます |
Blender 5.2 の注意事項
- Empty Hair と Quick Fur は、ピン留めされた Hair Dynamics モディファイアー(Mode
AnimationまたはPhysics (Experimental))を追加します。これは以前の Surface Deform を置き換え、変形するサーフェスに合わせてルートを移動します(シェイプキーとアーマチュアで確認済み)。最後に配置してください。 - Interpolate には Surface や UV Map の入力はなく、カーブオブジェクトのサーフェスを読み取ります。新しい入力は Part by Mesh Islands、Follow Surface Normal、Mask Texture、Resting Surface(オン)です。 Resting Surface がオンの場合、Thommes の「Mask modifier on the surface」パッチプレビューは効果がありません。代わりにパッチの頂点グループを Density Mask として使うか、プレビュー中は Resting Surface をオフにしてください。
- モディファイアーの入力は
md.properties.inputs.<id>.valueまたは.type = 'ATTRIBUTE'で設定します。ヘッドレスでは、obj.update_tag()を呼び出すまで評価結果が古いままです。H.set_inputsは UI 名を解決し、タグ付けも行います。 バックグラウンド評価では Viewport Amount が適用されるため、H.count(full=True)を使ってください。 - ブラシはアセットです。Snake Hook は Pull Tips、Selection Paint は Select です。Add のデフォルトは 8
ポイント、0.3 m で、設定は
brush.curves_sculpt_settingsにあります。 - ファクトリー設定の
render.hair_typeはSTRANDです。hair_subdiv >= 1の状態でSTRIPを使ってください。Cycles の形状はRIBBONS、THICK、THICK_LINEARです。「Curves Info」はShaderNodeHairInfoです。Principled Hair では Chiang と Huang を選べます。Hair Curves Noise はresolution12 を書き込みます。5.0 以降、カーブはこの値でレンダリングされます。 - カード:Curve to Mesh には Scale 入力(4.5)があり、Arc Resolution はポイント数を指定します。EEVEE のアルファには
surface_render_method = 'DITHERED'を使います。obj.evaluated_geometry().meshを読み取るときは GeometrySet を存続させてください。 - Quick Fur の密度はオブジェクトのサイズに応じて変わります(10 cm の球体で MEDIUM の場合:80,220/m²、ガイドあたり 12 ポイント)。
参考資料
references/expert-notes.md:判断に迷ったときに読み込んでください。人間のヘアスタイル、動物の毛皮、プロシージャルな毛皮、カード、メッシュヘアについて、専門家ごとのタイムスタンプが記載されています。references/procedures.md:コードを書く前に読み込んでください。bx_hairの呼び出しを bpy で直接記述したものを含む、テスト済みの手順 P1〜P8 が記載されています。references/critique.md:レンダーまたはレポートをレビューするときに読み込んでください。採点基準として使います。references/sources.md:引用やソースの再確認に使ってください。最適なタイムスタンプが記載されています。scripts/bx_hair.py:ツールキットです(5.2.1 でテスト済み)。テストはtests/code/blender-hair/にあります。