3d-cloth-material について
Three.js で制作する人向けの 3D 布地マテリアルスキルです。接線角度から伸びない折り目を作り、糸単位の織り、縫い目、裾、光の透過を表現します。
主な機能
- 01伸びない折り目形状の構築
- 02平織り・綾織り・朱子織りの生成
- 03麻・絹・羊毛の特性設定
- 04ステッチ・裾・ほつれの追加
- 05折り目の遮蔽と逆光の表現
活用シーン
- 01垂れ布やカーテンの素材制作
- 02布地の接写に織り目を追加
- 03布の折り目や縁の見え方を調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mengto/ skills --skill 3d-cloth-materialインストール後、Claude Code で/3d-cloth-materialを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
demo.htmlPROMPT.mdagents/openai.yaml詳細
3D 布素材
仕組み: 布を列状に吊るし、接線角度を折り目の信号として使います。これにより弧長はレスト座標 s と等しくなり、織り目が伸びることはありません。そのうえで、糸単位の織り、光沢、裾の厚み、隙間からの透過光によって「布らしさ」を表現します。
近接するスキル:3d-high-resolution-textures は、あらゆる素材のテクセル密度、ミップマップ、配信方法を選定します。予算の検討にはこちらを使い、織り交ぜ、折り目、光沢、裾といった布特有の要素については、このスキルを参照してください。3d-wood-material、3d-paper-material、3d-metal-material はそれぞれの表面を扱い、このスキルが対象とするのは織物と縫製された布だけです。これは布のシミュレーションではありません。キャラクターのなびくケープや衝突する旗を作る場合は、シミュレーション(Verlet または Blender のクロス)を行ってベイクし、その後で以下の素材のルールを適用してください。
KIBORI 木彫から抽出したものです。暗い WebGL 工房で、藍色の帆布(道具巻)が暖色のキーライトの下に置かれ、マクロ撮影にも耐える必要がありました。そこから移植したもの:織りのベイク、ステッチシェーダー、半円状の裾の折り返し、糸の上面の摩耗、光沢の定数。このスキル用に新たに構築したもの(Kibori には藍色の帆布が1種類しかなく、3種類の素材はありません):接線角度による折り目カーブ、サテンと綾織りの織り、シルク・ウール・リネンのテーブル、竿のタブ、切りっぱなしのほつれ、折り目の AO、逆光透過、風。リファレンスは demo.html です。
デモ:Three.js r169 · WebGL · GLSL(MeshPhysicalMaterial + onBeforeCompile)、バニラ JavaScript、ポスト処理なし。
各ルールと、それによって防ぐ問題
- 折り目は高さではなく角度から積分します。
α(s) = a·(sinθ + 0.16 sin(2θ+0.8)) + …とし、その後x += ds·cos α、z += ds·sin αとします。失敗例:高さ場z = A·sin(kx)では、弧長が 1 + slope² となるため、折り目のたびに織り目が揺れ、30~80%伸びてしまいます。角度形式なら、メートル単位のuv = (s, v)が正確に保たれます。|α| < 1.45rad を維持してください。それを超えると平坦な部分にクランプされ、折り目が黒い継ぎ目のある筒状になります。 - Uv は素材上のメートル単位であり、フレームごとに再フィットしません。 動く表面から uv を再計算しないでください。失敗例:風で織り目がちらつき、這うように動きます。
texture.repeat = 1/(threads × pitch)を設定し、1 つのテクセルタイルがNT本の糸になるようにします。リネンはピッチ 1.6 mm、シルクは 0.7 mm、ウールは 2.6 mm です。 - ノイズではなく、織り組織をベイクします。 各糸にはそれぞれ幅(0.80~0.97)、色調、スラブ(最大 0.34 のガウス状の太さの変化)があります。経糸の高さは、セル境界をまたいで
0.5·smoothstep(0.05, 0.5, |t|)により上下がブレンドされます。平織りは(A+B)&1、2/1 の綾織りは(A+B)%3 < 2、5 枚朱子織りは(2A+B)%5 != 0が経糸の上側です。タイルに継ぎ目が出ないよう、NTは繰り返し数(32、24、40)の倍数にする必要があります。失敗例:タイル状のノイズ法線マップは、漆喰や革のように見えます。 - 紡績糸には撚りを加えます。 各糸の高さに
0.22·twist·sin(2π(5·along + 1.3·across))を加えます(リネンとウールの撚りは 0.10~0.14、シルクは 0)。失敗例:リネンが金網のように見えます。 - 2 種類の染料と、糸ごとの色調を使います。 色は
mix(warpDye, weftDye, weftOnTop·shot)とします。シルクでは shot を 1.0(経糸は茜色、緯糸は金色)にし、それ以外は 0 にします。色調はmix(0.86, 1.14, threadTone)、陰影はmix(0.5, 1, smoothstep(0.05, 0.85, height))、斑点と経糸方向の筋は1 + var·((blot−0.5)·0.62 + (streak−0.5)·0.22)とします。失敗例:織物マップに単色のアルベドを使うと、プリントのように見えます。 - 光沢は布地そのものであり、小さく保つ必要があります。
sheen 0.5–1.0、sheenRoughness 0.28 (silk) – 0.82 (wool)、sheenColor = dye lightened × 0.62とします。失敗例:sheenColorが白に近すぎると、暖色のキーライトで縁が乳白色に飛びます。実行時にsheenをちょうど 0 に設定してはいけません(0.0001 にします)。0 をまたぐとプログラムが再コンパイルされ、200 ms 以上カクつきます。 - シルクには異方性、ウールには毛羽立ちを加えます。 シルクは
anisotropy 0.85, roughness 0.36、リネンは粗さ0.90、sheen 0.55、ウールは粗さ0.96、sheen 1.0 とします。定義が切り替わらないよう、作成時にanisotropyを 0 より大きく保ちます(0.0001)。 - 折り目の遮蔽は必須です。 キーライトのシャドウマップをキャストし、受け取るようにします(
normalBias 0.012、bias −0.0004、DoubleSideシャドウ)。さらに、間接光に折り目の深さから求めた頂点 AO0.62 + 0.38·smoothstep(−0.075, 0.035, zFold)を加えます。失敗例:どちらかが欠けると、谷が山頂のように明るくなり、折り目が描いたように見えます。 - 縁に厚みを持たせます。 半円に沿って、すべての自由端を裏側に折り返します。
P = edge + out·r·sinφ − N·r(1−cosφ)、φ ∈ [0, 0.94π]、rはシルクで 1.1 mm、リネンで 2.2 mm、ウールで 4.6 mm です。裏側に返し、法線を反転させた裾を2r + 0.2 mm分戻します。失敗例:厚みのない裁ち端は、クローズアップで CG の布地だと最も目立つ要因です。 - ステッチは布地のメートル単位でシェーダー内に描きます。 穴と穴の間に糸のアーチを作ります(ピッチの 74% にわたり
4·x(1−x))。針溝と縫い縮みは有限差分で法線に反映し、fwidthでフェードさせます。裾は端から 3 cm、脇は内側に 2.2 cm、縫い目は±7 mmとし、4 ピッチごとに縫い縮む盛り上がった畝を付けます。失敗例:ジオメトリのステッチは Z ファイティングやエイリアシングが発生し、テクスチャに描いたステッチは折り目に追従しません。 - ほつれた端では、緯糸を引き出します。 裁ち端の外側では、経糸(
|fract(u/pitch)−0.5| < 0.36)以外のフラグメントを破棄し、それぞれにランダムな長さF·(0.3+0.7·hash)を与えます。失敗例:アルファフリンジのテクスチャには糸の構造がありません。 - 薄い布地は光を通します。
emissive += trans · lightColour · dye·(1.7,1.2,0.85) · pow(max(0, −N·L), 1.15) · gap · thinとし、gap = mix(1, 0.42, height)によって糸は光を遮り、隙間は光を通します。シルクは 1.05、リネンは 0.6、ウールは 0.06 です。失敗例:これがないと、カーテンの後ろの明るい窓から光が差しません。 - 布地が触れる部分に摩耗を加えます。
wear = clamp(aWear·(0.25+height) + (fbm−0.5)·0.3, 0, 1)により、wear·threadTopに応じて染料を淡い色にブレンドします。裾は +0.4、山頂は +0.3 です。失敗例:染めにムラがないと、新品のように見えます。
定数
| linen | silk | wool | |
|---|---|---|---|
| 織り方 / NT / ピッチ | plain / 32 / 1.6 mm | 5-harness satin / 40 / 0.7 mm | twill / 24 / 2.6 mm |
| 法線強度 S · normalScale | 2.6 · 1.15 | 1.5 · 0.6 | 2.9 · 1.45 |
| 粗さ · 光沢 · sheenR | 0.90 · 0.55 · 0.55 | 0.36 · 0.5 · 0.28 | 0.96 · 1.0 · 0.82 |
| ひだ λ · amax · 風のゲイン | 0.34 m · 0.98 · 1.0 | 0.40 m · 1.02 · 1.9 | 0.32 m · 0.86 · 0.55 |
| 端 | 切りっぱなし、ほつれ 3 cm | 3.5 cm の裾 | 5 cm の裾 |
布は 2.0 × 1.95 m、グリッドは 160 × 120(約 21k 頂点、45k 三角形)です。キー SpotLight は 0xffd0a0 × 3.0、角度 0.44、減衰 0。寒色の補助光 1.0、窓からの逆光 0.2–1.8、環境光の強度 0.42、ACES、露出 1.0 です。
注意点、症状から説明
- 動かすと織り目が流れたり、ちらついたりする → uv を弧長から再構築したり、スクロールさせたりしています。静止時のメートル単位の値をそのまま使ってください。
- 広角表示で水平方向のモアレ縞が出る → バンプ/しわの項で高周波ノイズの
dFdxを使っています。しわのオクターブは 17 サイクル/m 未満にし、0.016 を掛けてください。ミップマップと 16× の異方性フィルタリングで、織り目自体には対応できます。 - ひだが黒い隙間のある平らなパネル状になる →
|α|がクランプされています。amaxを下げてa·env·1.28 < 1.45とし、暗さを増やさないでください。 - 逆光で全体がオレンジ色に光る → 透過色が暖色系の光と暖色系の染料の両方で乗算されています。
(2.1,1.35,0.72)ではなく、(1.7,1.2,0.85)で色を調整してください。 - envMapIntensity が何も変えない → r163 以降では、
material.envMapがある場合にのみ適用されます。scene.environmentを使う場合はscene.environmentIntensityを使ってください。 - 異なるユニフォームを持つ 2 つのメッシュ間で
onBeforeCompileのシェーダーが共有される →customProgramCacheKeyを設定し、ユニフォームはメッシュではなくマテリアルに置いてください。 - 裾の帯の巻き方向が間違っている(裏返しに照らされる) → 最初の更新後に一度だけ、各帯のインデックス順を、最初の三角形の法線と属性法線の符号に基づいて決めてください。
- 折り返し部分に暗い隙間ができる → 戻りの帯は
rではなく、2r + 0.2 mmの位置に置く必要があります。 - 両面シートでシャドウアクネが発生する →
biasを大きくするのではなく、normalBiasを使ってください。biasを大きくすると、ひだの影が浮いてしまいます。
ライフサイクル
prefers-reduced-motion の場合は、t = 7.3(突風の膨らみの中間)の演出された静止画を 1 枚描画し、ループを停止します。すべてのコントロールは有効なままにし、変更時に再描画します。document.hidden の間は一時停止し、再開時に last をリセットします。dt は 1/30 s にクランプし、DPR は 2 を上限として、60 フレームの平均が 26 ms を超えた場合は 0.25 ずつ下げます。サイズは ResizeObserver から取得します。布のループでフレームごとの割り当てが発生しないようにします。型付き配列を再利用し、position/normal のみを更新してください。
コスト(ヘッドレス Chrome for Testing、Apple GPU、DPR 2 の 1440×900 で測定)
- 布の CPU 処理(ひだ + 法線 + 裾 + タブ + フリンジ):160×120 で 3.7–4.9 ms です。行数を半分(190 → 120)にすると −40% になり、ひだは失われませんでした。垂れ下がる方向にはひだの変化が緩やかなためです。
- フレーム全体:広角で 10–11 ms、マクロで 15 ms です。マクロで増える 4 ms はジオメトリではなく、画面全体に対するフラグメントシェーダー(織り目 + ステッチ + fbm)によるものです。
- 起動:3 つの 512² の織り目ベイクを含め、最初のフレームまで 0.8 s です。生地の切り替えは 25 ms、レイヤーの切り替えは 14 ms です。
- ボトルネックではないもの:三角形の数、2048 シャドウマップ、タブ、フリンジ(520 本)。
評価基準に照らしたスコア(0 = 平坦な単色の面、5 = 腕を伸ばした距離で見て納得できる、10 = 写真のようなマクロ表示)
織り目の構造 7 · 光沢と染料 6.5 · ひだの形とドレープ 6(吊るしたカーテンであり、自己接触する自由な布ではありません)· 端、ステッチ、縫い目 7.5 · 光の透過 6 · 使用感 5.5 · 動き 5.5(風は解析的に表現し、衝突はありません)· パフォーマンス 8。総合 6.5。改善するには、自己衝突を伴うリアルなひだ(シミュレーションしてベイク)、ウールの繊維のハロー形状、しわ用の 2 つ目の法線スケールが必要です。