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?

ローカル3D生成の覇権交代?Hunyuan3Dを諦めてMicrosoftの「Trellis.2 4B」に乗り換えた話

2
Last updated at Posted at 2026-06-12

[!IMPORTANT]
この記事は AI(Antigravity / Gemini が起草、Claude Code が加筆・技術検証)によって執筆され、Qiita API を通じて自動投稿されたものです。記載のエラーやコードは実際の作業ログから転記しています。

個人開発中のゲーム(Lost Historia)で、AIを使った「1枚絵からの敵キャラ3D化パイプライン」を構築しています。

前回の記事では、「2D画像のまま部位分割してSpineで動かすアプローチは破綻したため、Hunyuan3Dを使って3Dメッシュ化に方針転換した」という話をまとめました。

しかし、実際にHunyuan3Dを使って本格的なパイプライン(自動リギング、テクスチャのマルチビュー化、パーツ分割など)を構築したところ、品質の壁にぶつかりました。対症療法を重ねて「遠目にはゴブリン」までは到達したものの、製品レベルには届かない。

そんな中で試したMicrosoftの最新オープンモデル**「Trellis.2 (4B)」**が、これまでの苦労を一撃で過去にする品質でした。今回は、Hunyuan3Dで直面した課題、ARM環境(DGX Spark系)へのTrellis.2移植バトルの実録、そして実際の生成結果をまとめます。

題材は終始この1枚です。ゲームの敵キャラ「ゴブリン」のコンセプト画(透過PNG)を、各モデルに同条件で入力しています。

画像0: 入力のコンセプト画(1枚絵・透過PNG)。これを3D化するのが目標


1. なぜHunyuan3Dでのパイプライン化に失敗したのか?

Hunyuan3D-2は強力なモデルですが、ゲームの量産パイプラインに組み込もうとした際に「3つの問題」が浮き彫りになりました。重要なのは、どれも生成直後ではなく「動かそうとした瞬間」に発覚することです。

① 結合メッシュ(一枚岩)の自動リギングの限界

Hunyuan3Dが生成するモデルは、腕・武器・胴体が物理的に融合した1個のメッシュです。これにBlenderの自動ウェイト(ボーンヒート)を試みると、メッシュの状態によっては全ボーンで失敗します(私の環境では、UV展開で頂点分割したメッシュに対してウェイト付与数が 0/15915 という完敗のログが残っています)。

距離ベースの決定論的ウェイトを自作して粘りましたが、今度は「武器がグリップで折れ曲がる」「武器の捕捉範囲が太ももを巻き込んで脚が曲がる」という別の破綻が出ます。剛体であるべき武器に緩いウェイト勾配を与えてはいけない、武器と脚の奥行きをゲートで分離する、など対処は積めるのですが、部位が分かれていないことの対症療法でしかありませんでした。

② 3Dメッシュの「パズルピース化」問題

「融合しているなら、2Dの部位マスク(SAM系で作成済み)を使って3Dメッシュをボクセル単位で部位分割すればいい」と考えました。ラベリング自体は動いたのですが、生成された無垢の立体を切り分けると、各パーツは**断面が平坦な「パズルピースのような破片」**になります。それ自体が完結した形(完全な頭、完全な腕)ではないので、関節を曲げた瞬間に切断面が露出します。

画像2: 3Dメッシュのパズルピース化(部位分割の分解ビュー。断面と断片が露出)

③ 側面テクスチャの引き伸ばし

Hunyuan3Dのテクスチャ生成(Paint)はカスタムCUDA拡張(custom_rasterizer)のビルドが必要で、手元のARM環境ではビルドできず、元絵を正面から平面投影してベイクする方式で代用していました。正面は元絵と一致して綺麗な反面、モーションで露出する側面・背面・奥側の脚には「正面の絵の引き伸ばし」しか乗りません。

マルチビュー画像を生成してテクスチャをブレンドする工程(ControlNet depth拘束で側面・背面ビューを安定生成 → 法線重みで焼き込み)まで自作して改善はしたのですが、工程がどんどん長くなっていきました。

画像3: 正面投影ベイクの限界(側面90度。頭部のテクスチャが引き伸ばされている)

ちなみに自作マルチビュー工程はこんな構成でした。ラフメッシュのdepthをControlNetの拘束にすることで「向き間違い・別キャラ化」は0にできた(13枚生成して全勝)のですが、これを敵キャラ全種に対して回すのか…という量産コストが重くのしかかります。

画像7: 自作マルチビュー工程。左のdepth拘束から右の側面・背面ビューを生成してテクスチャに焼き込んでいた


2. 「Trellis.2 4B」とは

そんな折にこちらの記事で、MicrosoftのTrellis.2 (4B) がローカルimage-to-3Dの新たな最高峰だと知りました。Hunyuan3Dの最新版がクローズド化していく中で、オープンに使える大型モデルです。

  • リポジトリ: microsoft/TRELLIS.2 / モデル: microsoft/TRELLIS.2-4B(Hugging Face)
  • O-Voxel構造: 穴あき形状・複雑トポロジー・鋭いエッジの再現に強い表現
  • PBRマテリアル一括生成: BaseColorだけでなくMetallic/Roughnessまで出力
  • 40億パラメータ + Sparse 3D VAE: 高解像度・高ディテール

公式の動作要件はVRAM 24GB推奨(記事では16GB GPUでも512解像度で動作報告あり)。Python 3.12 / PyTorch 2.9+ / カスタムCUDA拡張のビルドあり、という構成です。


3. 導入のハードル: aarch64(DGX Spark系)移植バトルの実録

今回はComfyUIではなく、NVIDIA GB10(DGX Spark系、aarch64 + 統合メモリ)のLinuxマシンに素のPythonで導入しました。世間の動作報告はほぼx86/WSL2なので、ARMでの導入記録はそれなりに珍しいはずです。踏んだ障害と対処を全部書きます。

3-1. カスタムCUDA拡張のビルド

setup.sh は拡張ごとにフラグが分かれています。flash-attnはARMビルドのリスクが高いので、まず外して開始しました。

export TORCH_CUDA_ARCH_LIST="12.1"   # GPUの実アーキテクチャ(GB10)を明示
export MAX_JOBS=16
source setup.sh --basic --o-voxel --cumesh --flexgemm --nvdiffrast

結果、cumesh / flexgemm / nvdiffrast は一発でビルド成功。3D系のCUDA拡張がARMで素直に通るのは正直驚きでした。

なお glcontext(X11ヘッダ不足)と pillow-simd(x86 SIMD前提)は失敗しますが、GLBエクスポート経路には不要なので無視でOKです。

3-2. o-voxel が Eigen 不足で失敗

fatal error: Eigen/Dense: No such file or directory

apt install libeigen3-dev ができない環境でも、Eigenはヘッダオンリーライブラリなのでsudo無しで解決できます。

curl -sL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz | tar xz -C ~
export CPLUS_INCLUDE_PATH="$HOME/eigen-3.4.0:${CPLUS_INCLUDE_PATH:-}"
pip install ./o-voxel   # 成功

3-3. DINOv3 のゲート(401 → 403 の意味)

実行すると画像エンコーダのダウンロードで止まります。

huggingface_hub.errors.GatedRepoError: 401 Client Error.
(facebook/dinov3-vitl16-pretrain-lvd1689m)

Trellis.2は画像エンコーダにMetaのDINOv3を使っており、これがゲート付きリポジトリ(ライセンス同意した人だけDL可)です。ハマりどころは2段階あることです。

  • 401 = トークンが無い → Readトークンを作って設定
  • 403 = トークンはあるがそのモデルへのアクセス権が無い → モデルページで「Agree and access repository」を送信

トークンはアカウント共通ですが、同意はモデルごとに必要です。SAM3など他のMeta製モデルはゲート無しで使えていたので、ここで初めてHFアカウントが必要になりました。

3-4. RMBG-2.0 のゲート(こちらは「回避」が正解)

次に背景除去モデルで再び403。

OSError: You are trying to access a gated repo.
(briaai/RMBG-2.0)

こちらは同意して使う前に注意が必要です。RMBG-2.0は商用利用に有償ライセンスが必要なモデルで、商用ゲーム開発のパイプラインに組み込むと地雷になります。

幸い、パイプラインのソースを読むと preprocess_image() は入力画像にアルファチャンネルがあれば背景除去を呼ばない設計でした。問題は「使わないのに構築時に無条件でモデルをDLする」実装だけ。なので構築をno-opに差し替えます。

# 入力は透過済みPNGなので背景除去は不要。構築だけ無効化する
import trellis2.pipelines.trellis2_image_to_3d as _t2mod

class _NoRembg:
    def __init__(self, *a, **k): pass
    def to(self, *a, **k): return self
    def cpu(self, *a, **k): return self
    def __call__(self, image):
        raise RuntimeError("rembg disabled: input image must have alpha channel")

class _RembgProxy:
    def __getattr__(self, name): return _NoRembg

_t2mod.rembg = _RembgProxy()

これでライセンス問題ごと完全回避できます。ゲーム素材作りでは入力を透過PNGに揃えておくのがおすすめです。

3-5. transformers 5.x との API 差異

AttributeError: 'DINOv3ViTModel' object has no attribute 'layer'

Trellis.2の特徴抽出器はtransformers 4.x時代の内部構造(model.layer)に直接アクセスしますが、5.x系では層リストがEncoderサブモジュール(model.model.layer)へ移動しています。1行のフォールバックで両対応にできます。

# transformers 4.x: model.layer / 5.x: model.model.layer
_layers = getattr(self.model, 'layer', None)
if _layers is None:
    _layers = self.model.model.layer
for i, layer_module in enumerate(_layers):
    ...

3-6. flash-attn 無しで動かす(sdpa + xformers)

ModuleNotFoundError: No module named 'flash_attn'

Trellis.2のAttentionは環境変数でバックエンドを切り替えられます。

  • 密Attention: ATTN_BACKEND=sdpa(PyTorch内蔵。追加ビルド不要)
  • 疎Attention: sdpa非対応で ['xformers', 'flash_attn', 'flash_attn_3'] のみ

flash-attnのARMビルドは長時間+失敗リスクがあるため、xformersをソースビルド(cutlassベースで新アーキ対応が早い)して回避しました。

TORCH_CUDA_ARCH_LIST="12.1" MAX_JOBS=16 pip install --no-build-isolation xformers
# 実行時:
ATTN_BACKEND=sdpa SPARSE_ATTN_BACKEND=xformers python generate.py

4. 生成実行と結果

生成コードは公式 example.py ベースで、ゲーム用に面数とテクスチャサイズを指定しました。

pipeline = Trellis2ImageTo3DPipeline.from_pretrained("microsoft/TRELLIS.2-4B")
pipeline.cuda()
mesh = pipeline.run(Image.open("enemy_forest_goblin.png"))[0]  # 透過PNG
mesh.simplify(16777216)

glb = o_voxel.postprocess.to_glb(
    vertices=mesh.vertices, faces=mesh.faces,
    attr_volume=mesh.attrs, coords=mesh.coords,
    attr_layout=mesh.layout, voxel_size=mesh.voxel_size,
    aabb=[[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]],
    decimation_target=300000, texture_size=2048,
    remesh=True, remesh_band=1, remesh_project=0,
)
glb.export("goblin_trellis2.glb")

そして結果です。1枚絵からの一発生成で、これが出ました。

画像4: Trellis.2による実際の生成結果(左: 正面 / 右: 側面90度。1枚絵から生成、側面のテクスチャ破綻なし)

正直、レベルが違いました。注目ポイント:

  • 側面・背面のテクスチャ破綻が無い。§1③で延々と戦っていた問題が存在しない
  • 腕が胴体から分離した自然な立ちポーズで生成された。§1①の癒着問題も大幅に軽減され、そのままリギング向き
  • 出力は29万面 + PBRテクスチャ(BaseColor / Metallic-Roughness 各2048px)

テクスチャを外したメッシュ(クレイ表示)を見ると、品質差の本質が分かります。顔の彫り、指、布のしわまで造形として入っています。

画像6: テクスチャを外したメッシュ(クレイ表示)。顔・指・布のしわまで造形されている

画像5: 実際に生成されたPBRマテリアル(左: BaseColor / 右: Metallic-Roughness、2048px)

Hunyuan3D-2 との比較(同じ1枚絵・体感まとめ)

正面同士を並べるとこうなります。左(Hunyuan+自作補正)は元絵をそのまま投影しているため正面の「絵の一致度」では勝りますが、これは何週間も自作工程を積んだ結果です。右(Trellis.2)は一発生成で、しかもこの品質が側面・背面まで一貫しています。

画像8: 正面比較。左: Hunyuan3D-2+自作補正の集大成 / 右: Trellis.2 4Bの一発生成

観点 Hunyuan3D-2 (+自作補正) Trellis.2 4B
正面の見た目 ◎(元絵投影のため一致) ◎
側面・背面 △〜✕(投影引き伸ばし。マルチビュー自作で△まで) ◎ 破綻なし
部位の癒着 ✕ 腕・武器が胴と融合しがち ○ 腕が分離したポーズで生成
メッシュの造形感 △ 溶けがち、要シルエット成形 ◎ 彫刻品質
テクスチャ 投影ベイク(自作) PBR一括生成
必要だった自作工程 成形・分割・MVベイク・ウェイト調整… (今のところ)ほぼ不要

5. まとめと次回

  • Hunyuan3Dベースのパイプラインは「動かそうとした瞬間」に課題が噴出し、対症療法の自作工程が伸び続けた
  • Trellis.2 4BはARM環境(GB10/DGX Spark系)でも全依存をビルドして動かせた。ハマりどころはEigen / HFゲート×2 / transformers 5.x / flash-attn代替の5点で、全て本記事の手順で回避可能
  • RMBG-2.0のゲートは同意せず回避がおすすめ(商用ライセンス問題ごと消える)
  • 生成品質は別格。側面テクスチャと癒着というHunyuan時代の2大課題が(少なくとも今回の素体では)発生しなかった

次回は、このモデルをゲームエンジン(Axmol)側のパイプライン — 部位分割、リギング、スプライトシート化 — へ接続して、実際にゲーム内で動かすところまでをレポートします。

個人開発で3D生成AIに振り回されている方の参考になれば幸いです。

2
0
0

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?