MMDの輪郭線(エッジ)の太さと色はどこで決まるか|材質の指定と頂点ごとの倍率
髪の毛先や顔の一部だけ輪郭線を消す、という指定がPMXにはあります。材質ではなく頂点ごとに書くもので、three.jsの描画はこれを読んでいませんでした。
このサイトの再生は、2026-10-06から頂点ごとの輪郭線の倍率を当てています。
材質ごとの指定は3つ
| 項目 | 中身 | three.jsのMMDLoader |
|---|---|---|
| 描画フラグ 0x10 | この材質に輪郭線を描くか | 読む(描くかどうか) |
| エッジ色 | 赤・緑・青・不透明度 | 読む(色と不透明度) |
| エッジサイズ | 太さ(1が標準) | 読む(300で割って画面上の太さにする) |
| モデル | 材質 | 輪郭線あり | エッジサイズ | 輪郭線なしの材質の例 |
|---|---|---|---|---|
| 人物A(ad_ik2) | 53 | 40 | 0.7が35、0.4が3、0.5と0.68が1ずつ | 目・白目・瞳レンズ・眉・ハイライト・チーク・髪影 |
| アリシア | 22 | 12 | 0.8が11、1.0が1 | eye・eyebrush・tere(照れ)・hairShadow |
| ステージ | 23 | 17 | すべて1.0 | 床・天井・壁 |
目・眉・頬の赤み・影の材質は、どのモデルも輪郭線を切っていました。輪郭線の色は、人物Aでは赤みのある色(0.45, 0.20, 0.30)や濃い灰色など10通り、不透明度は0.6〜0.7でした。真っ黒の不透明度1ではありません。
three.jsは輪郭線を「画面上の太さ」として描きます(カメラから遠くても細くならない。MMDのスケールと単位)。エッジサイズを300で割った値を太さにしていて、ソースには「TODO: better calculation?」と書かれています。MMD本体と同じ太さに見えるかは、ここでは確かめていません。
頂点ごとの「エッジ倍率」
PMXの頂点には、位置・法線・UV・ウェイトのほかにエッジ倍率(Float32)が1つあります。材質のエッジサイズに掛ける値で、0にするとその頂点のまわりだけ輪郭線が消えます。
| モデル | 頂点 | 倍率が1でない頂点 | どこ |
|---|---|---|---|
| 人物A(ad_ik2) | 39,540 | 342(0が340、0.5が2) | 顔00の182頂点・髪00の160頂点 |
| 人物A(ad_org8) | 40,688 | 342(同上) | 同上 |
| アリシア | 22,311 | 0 | — |
| ステージ | 4,669 | 0 | — |
three.jsのOutlineEffectは、この倍率を見ていません。 頂点シェーダに const float ratio = 1.0; と書かれ、「TODO: support outline thickness ratio for each vertex」のままです。パーサは倍率を読んでいるのに、描くときは全頂点を1として扱っていました。
このサイトでの直し方と結果
モデルを読み込むときに倍率を頂点の属性として持たせ、輪郭線のシェーダの ratio をその属性に置き換えました。倍率を持たないモデル(全頂点が1のもの)には属性を足さず、そのときは1として描くので、今までと同じ太さになります。
人物Aの頭に寄った画面(1200×900、物理を止めて比較)で、直す前と後で変わった画素は、正面554・横507・後ろ350でした。拡大して見比べると、変わったのは主に髪の毛先の輪郭線で、作者が倍率0にしたところの線が消えています。
- PMD(古い形式)にも頂点ごとの「輪郭線を描かない」指定がありますが、手元に実物が無く確かめられないため、PMDには当てていません。
- three.jsは、PMDの輪郭線を材質ごとに黒・太さ0.003で描きます(PMDの材質は色と太さを持たないため)。