2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Blender経由で出力したVRMのCutout透過がUnity外プラットフォームで誤表示される原因と対策

Last updated at Posted at 2025-08-15

VRoid Studioで作成したVRMを一度Blenderに読み込み、再度VRM形式で出力すると、
VRoid Hub上でCutoutマテリアルの透過部分が背後のメッシュごと透過してしまう現象が発生した。
Unity上では正常に表示されるため、原因の特定に4日もかかりました…
備忘録として残します。

結論

  • 原因
    Blender出力時、MToonのCutoutマテリアルに_ALPHABLEND_ON: Trueキーワードが付与されてしまう。
    このキーワードは半透明合成用であり、Cutoutでは(おそらく)不要。

Blender VRMアドオン作者様から「Blender 4.2以降で発生していたバグで、最新版(v3.11.1)で修正した」とのコメントをいただきました。最新版では_ALPHABLEND_ONがfalseで出力されるようになっています。感謝。

  • 対策
    最新版アドオン(v3.11.1以降)を使用する ←推奨
    出力されたVRMファイル内の、MToonシェーダーのCutoutマテリアルのkeywordMapから_ALPHABLEND_ON: Trueを削除する。
    またはUnity上でマテリアルを新規に作り直す(回避策)

再現条件

  • 現象
    VRoid Studioで作成したVRMを一度Blenderに読み込み、再度VRM形式で出力すると、
    Unityでは正常に描画されるが、VRoid Hubでは透過部分が背後まで抜けて見える
  • 再現例
    瞳の輪郭、胸元のリボン、袖口部分
    image1.png

環境

現象の再現には、VRoid StudioのAvatarSample_Mに協力してもらっています。

ソフトウェア/アドオン バージョン
VRoid Studio 2.1.5
Blender 4.2.10 LTS
vrm-addon-for-blender 3.6.0
Unity 2022.3.17f1
UniVRM 0.129.3

調査経緯

  1. Unity上では正常
    Unityで表示した場合、VRoid Studio出力版とBlender経由版で見た目に差はなし。
    Render Queueやマテリアルの各種設定も完全一致している。

    image2.png

  2. VRoid Hub上で誤表示
    VRoid Hubにアップロードすると、Blender経由版のみ透過処理がおかしくなる。
    背後の肌や髪まで透過してしまう。
    下図では、瞳の輪郭(赤線で囲った部分)、胸元のリボン、袖口部分で発生。

    左:VRoid StudioでVRM出力   右:VRoid Studio → BlenderでVRM出力
    image001.png

VRMファイル内部の比較

原因が全くわからないので、Pythonで正常版と異常版の中身を読み出し、マテリアル周りの記述を吐き出させて、違いを確認する。

VRMは、3Dモデルの標準形式であるglTFを拡張したファイル形式である。
この拡張部分の中にあるextensionsセクションでは、VRM独自の追加情報が定義されており、MToonのマテリアル設定を扱うmaterialPropertiesもここに含まれる。

ここではmaterialPropertiesに記録されるプロパティを詳しく見ていく。
PythonではglTFを取り扱うパッケージをインポートすることでVRMファイルの中身を簡単に見ることが可能。

glTFのoverviewを参考にVRMファイル内のマテリアル周りの記述を抽出する。

VRMの拡張機能は、extensionsのエントリポイント内に記載されており、
MToonのマテリアル情報はextensions["VRM"]["materialProperties"]に格納されている。

関連しそうな違い(Cutoutマテリアル)

レンダリングタイプがCutoutマテリアルに関して、keywordMap項に関連しそうな違いがあった。
異常なモデル(Blender経由版)では_ALPHABLEND_ON: Trueが追加されている。

正常(VRoid Studioで出力)
...
 'keywordMap': {
  '_ALPHATEST_ON': True,
  '_NORMALMAP': True,
  'MTOON_OUTLINE_COLOR_FIXED': True,
  'MTOON_OUTLINE_WIDTH_WORLD': True},
...
異常(VRoid Studio → Blenderで出力)
...
 'keywordMap': {
  'MTOON_DEBUG_LITSHADERATE': False,
  'MTOON_DEBUG_NORMAL': False,
  'MTOON_OUTLINE_COLOR_FIXED': True,
  'MTOON_OUTLINE_WIDTH_WORLD': True,
  '_ALPHABLEND_ON': True,
  '_ALPHAPREMULTIPLY_ON': False,
  '_ALPHATEST_ON': True,
  '_NORMALMAP': True}
...

VRM 0.x仕様にはCutout時のキーワード一覧は明記されていないがUnity Standard Shaderの挙動から推測するに、_ALPHABLEND_ONは半透明のブレンド処理を有効にするためのキーワードなので、Cutout「アルファ閾値で完全表示 or 完全非表示」では必要ないはず。

VRM 0.xの各レンダリングモードにおけるキーワードの違いに関する情報は見つけられなかったが、Unity の公式ドキュメントでは、「Standard Shader」における各種レンダリングモードと、それに対応した Shader キーワードが明示されている。Cutout モードでは「透過合成」ではなく「アルファ値による切り抜き」によって描画されるため、_ALPHABLEND_ONは使用されず、_ALPHATEST_ONが使われる。

Unity 上で動作するMToonも同じキーワード対応で描画処理が動作すると理解するのであれば、CutoutにおいてALPHABLEND_ONは記載する必要はないはず。

修正してVRoid Hubで表示確認

ためしにcutoutが使われている衣装マテリアルのALPHABLEND_ONを消してみる。

読み込みから修正まで
import pathlib
import pygltflib

# VRM読み込み
path = pathlib.Path('.\\blender_output\\AvatarSample_M_compression.vrm')
glb = pygltflib.GLTF2().load_binary(path)

# 例:衣装マテリアル(配列インデックス5)のkeywordMapを修正
glb.extensions['VRM']['materialProperties'][5]['keywordMap'].pop('_ALPHABLEND_ON', None)

# 保存
glb.save_binary('fixed_model.vrm')

この修正版をVRoid Hubにアップロードすると、衣装の透過の誤表示が解消された。
(瞳の輪郭部分については何もしていないのでもちろん表示がバグったまま。)
image002.png

追記:調査の過程でPythonでVRM内部を直接編集しましたが、現在はアドオンの最新版を利用するのが最もシンプルな解決策です。

関連情報

同様の事象は、VRMアドオンのGitHub Issueにも報告があったみたい。
Blenderとアドオンのバージョン組み合わせにより発生する可能性があったようです。

v3.11.1リリースに伴いresolvedとなりました。

  • glTFに関して、Pythonでの取り扱い方の参考記事

透過処理の話はまじでむずぃ。

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?