【Blender】GLBの大きさが変わるときは|JSON配置のスケールを確認する
個別のGLBを独自JSONから再配置して一部だけ大きさが変わる場合は、位置・回転に加えてスケールも保存しているか確認します。この記事では、1.50mの部材をZ方向へ0.9倍にした配置を例に、1.35mの高さを再現する方法を試します。
対象はBlenderのPythonで配置を自動化している人です。GLBを1つ読み込むだけの操作や、すべてのモデルが100倍になる問題を一律に解決する手順ではありません。Godotへ初めてGLBを読み込む手順は別記事で説明しています。
検証環境:Blender 4.3.2、2026年10月12日。付属スクリプトをバックグラウンド実行し、GLBの書き出し・再読み込みと16項目のチェックを行いました。最新版という意味ではありません。
ここでは、Blender座標の配置情報を独自のJSONに保存し、Blenderへ読み込んだGLBに適用するケースを扱います。GLB内部のglTFノードを直接編集する手順ではありません。
Zスケール0.9を失うと、1.35mの高さが1.50mへ戻る
元の部材の高さを1.50m、原点を底面、回転をゼロとします。配置した部材のZスケールが0.9なら、高さは1.50 × 0.9 = 1.35mです。再構築時にスケールを1へ戻すと、位置が同じでも上端が15cm高くなります。

位置・回転・スケールをセットで記録する
この小例では、単位をメートル、座標をBlenderのXYZ順、回転をZ軸まわりのラジアンに固定します。別の部材配置と区別できる名前も付けます。
{
"instance_name": "support_01",
"location_blender": [0, 0, 0],
"rotation_z_radians": 0,
"scale_blender": [1, 1, 0.9]
}Blenderでは、配置用の親オブジェクトに次の値を設定します。個別GLBを読み込んだ際の内部変換は残し、そのルートを配置用の親の下に置く構成です。配置用の親は新規作成した、制約やアニメーションのないものを想定します。次のコードは変換を設定する部分の抜粋です。
root.location = row["location_blender"]
root.rotation_mode = 'XYZ'
root.rotation_euler = (0, 0, row["rotation_z_radians"])
root.scale = row["scale_blender"]必須キーとして読むと、欠落時にエラーが出ます。「なければ[1,1,1]」という処理は、意図した0.9が保存されなかった不具合を隠すことがあるため、新しい配置データでは明示する方が点検しやすくなります。Blenderの各プロパティは公式Object APIで確認できます。
再現スクリプトで実際の高さを測る
再現スクリプトと配置JSONをダウンロードし、展開してください。reproduce.pyとplacement.jsonは同じフォルダに置きます。JSONファイルを実際に読み込み、生成した部材を一時GLBへ書き出して、2回読み戻します。一方は比較用にscaleを[1,1,1]、もう一方はJSONの値を使います。比較用の1は意図的な設定で、必須キーが欠けた時の代替値ではありません。
Blender 4.3.2での確認は、展開フォルダをカレントディレクトリにして、次のコマンドで行いました。blenderコマンドが見つからない場合は、インストール済みBlender実行ファイルのパスに置き換えます。
blender --background --factory-startup --python-exit-code 1 --python reproduce.py -- --report result.json付属のZスケール0.9では、比較用が1.50m、JSONから配置したものが約1.35mになります。placement.jsonの最後の値を0.5へ変更すると約0.75mになります。結果はresult.jsonにも出力されます。同名のレポートがあれば上書きされるので、作業用フォルダで試してください。
- scaleが[1,1,1]の比較用:実測1.50m
- JSONのscaleが[1,1,0.9]:実測約1.350000m
- JSONのscaleが[1.2,0.8,0.5]、位置[10,20,30]、Z回転0.7rad:実測0.75m
高さは画面上の見た目ではなく、読み込んだメッシュ頂点をワールド座標へ変換し、最大Zと最小Zの差から求めます。Z軸だけを回転させるこの例なら、期待値は1.50 × |Zスケール|です。X・Y軸で傾けるとワールドZ方向の高さが変わるので、同じ式は使えません。

同じテストをまとめて実行する
展開したフォルダで次のコマンドを実行し、付属の検証をまとめて確認します。
blender --background --factory-startup --python-exit-code 1 --python verify_reproduce.py最後に「REPRODUCE_TESTS_PASS」と「checks: 16」が表示され、終了コード0なら付属の検証が通っています。scale欠落、要素数不足、真偽値、非有限数、壊れたJSON、Unit Scaleが1以外のケースを含みます。単純な静的メッシュのテストであり、リグやアニメーションの保証ではありません。
scale_blenderを削除したJSONは、オブジェクトを追加する前にエラーで止まります。各XYZ配列が3つの有限数かも検査します。–python-exit-code 1はPython例外を終了コード1として返す指定です。検証スクリプトverify_reproduce.pyでは、0.9と0.5の実測、結果ファイルの読み戻し、不正なJSONの拒否、既存オブジェクトの位置・表示状態を確認します。
この小例はObject Mode、SceneのUnit Scaleが1.0の状態を前提にします。テスト用オブジェクトを追加して選択状態を変えますが、既存オブジェクトの削除や.blendファイルの保存はしません。一時GLBは測定後に削除します。動作確認用の単純な静的メッシュに限るため、親子階層やアニメーションを含む一般的な配置データの検証器としては使えません。
glTFのscaleと独自JSONを混同しない
glTFのノード変換はmatrix、またはtranslation・rotation・scaleで表します。後者の合成はT × R × Sで、頂点にはスケール、回転、移動の順に作用します。scaleを省略した場合の既定値は[1,1,1]です。これはglTFの仕様であり、独自JSONの不足を自動修復する仕組みではありません。Khronos glTF 2.0仕様
また、BlenderはZ-up、glTFはY-upです。この記事のコードはBlenderのインポーターで読み込んだ後にBlender座標の値を使うため、さらに軸変換を加えません。glTFノードを直接読む処理を作る場合は、座標系や四元数の並びを別途確認してください。Khronos glTFの座標系・単位
「スケールを適用して1にすれば解決」と決めつけるのも早計です。Blenderのスケール適用は変換をオブジェクトデータへ反映します。形状へ倍率を焼き込んだ上で配置JSONにも同じ倍率を残すと、二重に縮小する可能性があります。部材側へ焼き込むか、配置側に持つかを揃えましょう。Blender公式Apply説明(4.0日本語版)
うまくいかないときの確認順
- 一部だけ高さが違う:配置JSONのscale_blenderがXYZの3要素で保存されているか確認します。
- 全体が一定倍率で違う:シーンのUnit Scale、元モデルの寸法、配置側の親スケールを順に調べます。このサンプルはUnit Scale 1.0以外では停止します。
- 倍率を直したらさらに小さくなる:モデルへスケールを焼き込んだ後、同じ倍率を配置側でも掛けていないか確認します。
- 高さは合うが位置がずれる:原点の位置と親オブジェクトの変換を確認します。原点を移動する基本も参考になります。
- Missing required keyで止まる:JSONの必須キーを戻します。[1,1,1]を自動補完して問題を隠すより、保存漏れの原因を直します。
最後は再構築した形状で確認する
JSONの値が揃っただけで終了せず、個別GLBとJSONから組み直して参照シーンと比較します。最低限、配置数、各オブジェクトのワールド変換、外接範囲を確認し、同じカメラと照明で見比べます。
親子階層、制約、アニメーション、XYZ全軸の回転があるシーンには、この記事のZ回転だけの形式では足りません。まずはスケールを含む小さな配置で往復テストを作り、その後に必要な変換情報を増やすと原因を絞りやすくなります。
次に読む記事
- ベベル幅がそろわないときのスケール適用:モデル側へ倍率を反映する基本
- Blenderの3DモデルをGodotへGLBで読み込む:ゲームエンジン側の大きさと材質の確認
- Blenderの機能ガイド:モデリング・UV・書き出しの記事一覧
サイトアイコン-2-150x150.png)