トップ 問題解決の記録

UV coverage 0%問題

目的

頂点カラーをテクスチャ画像にベイク(後述)するため、Blenderのsmart_project UV展開 + Cyclesベイクを使用する。高解像度(2048²以上)のテクスチャを生成する。

用語: smart_project — Blenderが自動で3Dモデルの表面を切り開き、平面上にパズルのように配置するUV展開方式。手動での継ぎ目編集が不要だが、複雑な形状では多数の小さな島(UV island)に分割される。ベイク(bake) — 3Dモデルの各頂点に保存された色情報(頂点カラー)を、平面的な画像(PNGテクスチャ)に「焼き付けて」転写する処理。料理の「焼く」が語源。

問題

Blenderのsmart_project UV投影で、1024²以上の解像度を指定するとUV coverageが0%になる現象が発生。テクスチャが真っ黒(またはベイクされていない状態)で出力された。

用語: UV coverage — テクスチャ画像の領域のうち、実際に3Dモデルの表面(UV island)が割り当てられている面積の割合。0%は「UVマップが事実上消失している」ことを意味する。

原因

island_margin=0.02(UV island間の余白)が高解像度でUV空間の大部分を消費し、実質的にUVマップが消失した状態になっていた。Blenderのデフォルト値を無条件で信頼したことが原因。

用語: island_margin(アイランドマージン) — smart_project UV展開で各UV islandの周囲に設ける余白。隣接island間の色混ざり(bleeding)防止用。単位はUV空間に対する比率(0.0〜1.0)で、0.02 は全体の2%。

フォトグラメトリで生成されるメッシュは複雑な地形・建物で構成されるため、smart_project展開では数百〜数千の小さなUV islandに分割される。island_margin は島ごとに適用されるため、島数が多いほど累積的な余白面積が増える:

島2個の場合:  □□□    余白 = わずか
島200個の場合: □□…□  余白 = UV空間の大部分

これがUV空間を圧迫し、coverage 0%を引き起こす。単純なモデル(島数少)では同じ 0.02 でも問題になりにくい。

調査経緯

以下の表記(v2-v6, v7, v8-v10)は問題解決の過程で試行したパイプラインのバージョン番号である。

バージョン試行内容結果
v2-v6GPUデバイスでベイクcoverage 0%
v7CPUデバイスに変更coverage 28-42%で動作(一見解決)
v8-v10island_margin=0.02 を設定1024²以上で再び0%
v11island_margin=0.0全解像度で正常動作
planarsmart_project → 平面UV投影に方式変更継ぎ目問題も同時解決

CPUとGPUの比較について

v2-v6でGPUがcoverage 0%、v7でCPUが28-42%と異なる結果になったが、これは統制実験によるものではない。GPUとCPUの切り替えと同時に他のパラメータも変化しており、真の原因は後で判明した island_margin である。GPUでも island_margin=0.0 にすれば正常動作した可能性が高く、GPU/CPUの違いは本質的ではなかった。

処理時間の参考値(Cyclesベイク, samples=1, EMIT):

GPUの方が2〜4倍高速だが、4GB VRAMの制約下では大メッシュでOOMするリスクがある。現行パイプラインでは安定性を優先しCPUを使用している。

対策

恒久対策

  1. island_margin=0.0 に設定 → 全解像度で正常動作(EMITベイクでは隣接UVのbleedingは無害)
  2. 最終的に平面UV投影(planar)に方式変更 → 継ぎ目問題も同時解決

教訓

Blenderのデフォルトパラメータ(特に island_margin)は環境や解像度によっては致命的な問題を引き起こす。実際の出力を検証して調整することが重要。

ステータス

恒久対策済みisland_margin=0.0 + planar投影