MMDモデルの顔に影が落ちる|PMXの材質フラグ(両面描画・地面影・セルフ影・輪郭)の中身
ブラウザでMMDモデルを再生すると、顔に前髪の影が帯のように落ちることがあります。多くのモデルは、顔や白目に影を落とさないよう材質ごとに指定しています。その指定を再生側が読まないと、作者が消したはずの影が出てきます。
このサイトの再生は、2026-10-06からセルフ影の指定を材質ごとに当てています。 手元のモデルはローカル再生で確かめられます。
材質フラグは1バイト
PMXの材質は、拡散色・反射色・環境色の後ろに1バイトのフラグを持ち、ビットごとに描き方を決めます。
| ビット | 意味 | three.jsのMMDLoader |
|---|---|---|
| 0x01 | 両面描画(裏からも見える) | 読む(DoubleSide にする) |
| 0x02 | 地面影(床に影を落とす) | 読まない |
| 0x04 | セルフ影マップへの描画(ほかの部分へ影を落とす) | 読まない |
| 0x08 | セルフ影(ほかの部分から影を受ける) | 読まない |
| 0x10 | 輪郭線を描く | 読む(輪郭の太さが0より大きいときだけ描く) |
PMD(PMXより古い形式)の材質には、このフラグがありません。輪郭線の有無を表す1バイトがあるだけです。
実物のモデルでの使われ方
| モデル | 材質 | 両面 | 地面影 | セルフ影マップ | セルフ影 | 輪郭 |
|---|---|---|---|---|---|---|
| 人物A(ad_ik2) | 53 | 8 | 47 | 47 | 42 | 40 |
| アリシア | 22 | 2 | 11 | 12 | 12 | 12 |
| ステージ | 23 | 0 | 0 | 6 | 11 | 17 |
セルフ影を切っている材質は、どのモデルでも顔まわりに集まっていました。 人物Aでは「顔00」「顔01」「白目」「目」「ハイライト」「眉」「舌」「髪影」「チーク」など11材質、アリシアでは「eye」「tear」「tere」(頬の赤み)「hairShadow」など10材質です。顔に影が落ちると表情が読みにくくなるので、作者が切っています。「髪影」「hairShadow」は名前のとおり髪の影を表す材質で、これも影を受けないようにしてあります。
両面描画は、裏側も見える布や髪に付いていました。人物Aではスカート・上着・襟など8材質、アリシアでは「hair」「maegami」(前髪)の2材質です。
読まないと、顔に前髪の影が落ちる
three.jsでは、影を受けるかどうかをモデル全体で1つしか決められません。このサイトも以前はモデル全体に影を受けさせていたので、顔にも前髪の影が帯のように落ちていました。人物Aの顔に寄った画面(1200×900)で、セルフ影の指定を当てる前と後を比べると、18,605画素が明るくなりました(当てた後は顔に影が落ちていません)。アリシアでは3,556画素でした。暗くなった画素は1つもありません。
このサイトでは、セルフ影を切っている材質だけ、影の計算を外すようにしました。three.jsの材質は1つずつシェーダーを差し替えられるので、その材質では「影を受ける」をいつも「受けない」として扱います。
まだ当てていないもの
- 地面影(0x02)とセルフ影マップ(0x04)。 影を落とすかどうかもthree.jsではモデル全体で決まり、材質ごとには切れません。白目やハイライトのような小さな材質も影を落とします(顔はセルフ影を切っているので、顔には落ちません)。
- 片面描画の半透明の材質は、three.jsでは両面になります。 MMDLoaderが、不透明度が1未満の材質を自動で両面描画にするためです。人物Aでは「瞳レンズ」(不透明度0.40)と「胸章」(0.80)がこれに当たります。