こんにちは、もしくはこんばんは。シロです!
最近、Blenderを使用して3Dモデリングをする人が増えてきました。
3Dモデルはゲームやメタバース空間などで幅広く活用できます。しかし、Webコンテンツとしての活用方法はまだ情報が少なく、技術的に難しい思っている人も多いかと思います。
この記事では、3Dグラフィックスを描画するためのJavaScriptライブラリであるThree.jsを使って、3DモデルをWebページに表示する方法をご紹介します!
Three.jsについては以下の記事でも紹介しています。

できるようになること
この記事を読むと、Webページにあなたが作成した3Dモデルを掲載できるようになります。
デモページを用意しました。マウス操作もできるようになっているので、ぜひ3Dモデルをぐるぐる操作してみてください。
前提条件
- 3Dモデルをもっていること
- Blenderの基本的な操作ができること
- Javascript/CSSの基礎知識があること
ステップ1:3Dモデルの準備
まず初めに、Webページの表示に対応したデータ形式であるglTF形式で3Dモデルをエクスポートします。
Blenderを使ってglTF形式で3Dモデルをエクスポートする方法については、以下の記事をご覧ください。

また、3Dモデルのアップロードについては、各サーバやプラットフォームによって方法が異なります。
WordPressでのアップロード方法については、上記の記事に記載していますので、あわせてご覧ください。
ステップ2:Three.jsのインポート
Webページの<head>にThree.jsのインポート文を追記します。<head>内が推奨ですが、<body>内でも問題ありません。
このコードでは、importmapを使用してThree.jsのモジュールを読み込んでいます。
  <head>
    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@v0.151.3/build/three.module.js",
          "three/addons/": "https://unpkg.com/three@v0.151.3/examples/jsm/"
        }
      }
    </script>
  </head>ステップ3:3Dモデルの表示
Webページの<body>にGLTF形式の3Dモデルを表示するスクリプトを記載します。以下はスクリプトの全文です。
  <body>
    <script type="module">
        // 1. Three.jsライブラリの読み込み
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
        // 2. シーンを作成する
        const scene = new THREE.Scene();
        // 3. カメラを作成する
        const camera = new THREE.PerspectiveCamera(
            75, // 視野角
            window.innerWidth / window.innerHeight, // アスペクト比
            0.1, // ニアクリップ面
            1000 // ファークリップ面
        );
        camera.position.z = 5; // カメラの位置を設定する
        // 4. レンダラーを作成する
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.zoomSpeed = 0.5;
        controls.update(); // 初期化時に一度だけ呼び出す
        // AmbientLightを追加する
        const ambientLight = new THREE.AmbientLight(0xffffff, 1);
        scene.add(ambientLight);
        // 5. GLTFLoaderを作成する
        const loader = new GLTFLoader();
        
        const dracoLoader = new DRACOLoader(); // DRACOLoaderのインスタンスを作成
        dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.1/');
        loader.setDRACOLoader(dracoLoader); // GLTFLoaderにDRACOLoaderのインスタンスを提供
        // 6. 3Dモデルのロード&描画
        loader.load(
            "path/to/model.gltf",
            function (gltf) {
                scene.add(gltf.scene);
            },
            undefined,
            function (error) {
                console.error(error);
            }
        );
        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
        animate();
    </script>
  </body>1. Three.jsライブラリの読み込み
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';このコードは、Three.jsを使用して3Dモデルを表示するための準備をするためのものです。
import文は、Three.jsのライブラリから必要な機能をインポートします。ここでは、THREEオブジェクト全体をインポートし、OrbitControls、GLTFLoader、DRACOLoaderの各機能をインポートしています。
OrbitControlsは、カメラをマウスで制御するためのユーティリティであり、GLTFLoaderとDRACOLoaderは、それぞれGLTF形式の3Dモデルと、その圧縮バージョンであるDRACO形式の3Dモデルを読み込むためのユーティリティです。
2. シーンを作成する
        const scene = new THREE.Scene();このコードは、Three.jsのSceneオブジェクトを作成するコードです。
Sceneオブジェクトは、3Dオブジェクトを保持するコンテナのようなもので、3Dオブジェクトを配置するための基盤となります。
Sceneオブジェクトを作成したら、この中に3Dオブジェクトを追加していきます。例えば、立方体や球体、テキストなどが3Dオブジェクトにあたりますが、今回はGLTF形式の3Dデータを追加します。
3. カメラを作成する
        const camera = new THREE.PerspectiveCamera(
            75, // 視野角
            window.innerWidth / window.innerHeight, // アスペクト比
            0.1, // ニアクリップ面
            1000 // ファークリップ面
        );
        camera.position.z = 5; // カメラの位置を設定するこのコードは、three.jsのカメラオブジェクトを作成し、適切な位置を設定するコードです。
具体的には、PerspectiveCameraを作成しています。
第1引数は視野角、第2引数はアスペクト比、第3引数はニアクリップ面、第4引数はファークリップ面を指定します。
- 視野角:この角度で描画範囲を調整します。
- アスペクト比: カメラが描画する領域です。一般的に、ディスプレイの縦横比と同じ値を指定します。
- ニアクリップ面:カメラが描画する最も近い距離です。この距離よりも近いオブジェクトは描画されません。
- ファークリップ面:カメラが描画する最も遠い距離です。この距離よりも遠いオブジェクトは描画されません。
また、カメラの位置をz方向に5に設定しています。
4. レンダラーを作成する
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.zoomSpeed = 0.5;
        controls.update(); // 初期化時に一度だけ呼び出す
        // AmbientLightを追加する
        const ambientLight = new THREE.AmbientLight(0xffffff, 1);
        scene.add(ambientLight);このコードは、レンダラーとカメラコントロールを設定し、シーンにAmbientLightを追加している部分です。
rendererは、Three.jsが提供するWebGLRendererオブジェクトです。setSize()を使用して、描画領域のサイズを指定し、domElementをdocumentに追加することで、シーンをレンダリングするためのキャンバスをHTMLに挿入します。
OrbitControlsは、Three.jsが提供するカメラコントロールオブジェクトです。この例では、OrbitControlsを使用してカメラを制御し、マウスでシーンをズーム、回転、平行移動することができます。
AmbientLightは、環境光源を表すThree.jsのライトオブジェクトです。この例では、白色光を1.0の強度でシーンに追加しています。環境光源は、影を落とすことはできませんが、3Dモデルをより自然に見せるために使用されます。
5. GLTFLoaderを作成する
        const loader = new GLTFLoader();
        
        const dracoLoader = new DRACOLoader(); // DRACOLoaderのインスタンスを作成
        dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.1/');
        loader.setDRACOLoader(dracoLoader); // GLTFLoaderにDRACOLoaderのインスタンスを提供このコードは、GLTFファイルを読み込むためのローダを設定しています。
GLTFファイルを読み込むためには、GLTFLoaderを使用します。GLTFLoaderは内部的に、バイナリファイルの解析やテクスチャの読み込みを行います。
DRACOLoaderは、3Dモデルのファイルサイズを小さくするための圧縮技術であるDracoのデコーダを提供します。DRACOLoaderを使用するには、DRACOのデコードに必要なファイルをロードして、GLTFLoaderに渡す必要があります。
dracoLoader変数は、DRACOLoaderのインスタンスを作成し、setDecoderPath()メソッドを使用してDRACOデコーダのパスを設定します。そして、setDRACOLoader()メソッドを使用して、GLTFLoaderにDRACOLoaderのインスタンスを提供します。
6. 3Dモデルのロード&描画
        loader.load(
            "path/to/model.gltf",
            function (gltf) {
                scene.add(gltf.scene);
            },
            undefined,
            function (error) {
                console.error(error);
            }
        );
        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
        animate();このコードは、GLTFLoaderを使用して3Dモデルを読み込み、Three.jsを使って表示するためのものです。
loader変数は、GLTFLoaderのインスタンスを作成するために使用されます。
loader.load()メソッドは、引数として3Dモデルのパスを受け取り、モデルを非同期で読み込みます。読み込みが完了すると、引数として渡されたコールバック関数が呼び出され、モデルをシーンに追加します。読み込みに失敗した場合は、エラーメッセージがコンソールに出力されます。
animate()関数は、requestAnimationFrame()メソッドを使用してアニメーションを実行し、renderer.render()メソッドを使用して、シーンとカメラをレンダリングします。
このコードを実行すると、指定したパスのGLTFファイルが読み込まれ、Three.jsのレンダラーで表示されます。
まとめ
この記事では、Thess.jsを使ってWebページ上に3Dモデルを表示する方法について解説しました。
Three.jsを使えば、自分で作った3Dモデルをブログやウェブサイトに簡単に表示できます。
ぜひこの記事を参考にして、より魅力的なコンテンツを自分のウェブサイトやブログに追加してみてください!
以上、「【Three.js】Blenderで作成した3DモデルをWebページに表示する方法」についての紹介でした。
 
	
コメント
コメント一覧 (3件)
シロさま
はじめまして。
blenderを勉強し始めて2日目・・・のFJと申します。
ホームページを現在構築しておりまして、
その中で3Dデータを表示したいと思っていまして、
検索して見つけました。そして実行したらできたので感動しています!
もしご迷惑でなければ教えていただきたいのですが、
今検討・構築しているサイトで行いたいことの一つとして
3Dデータを表示・回転させる。という事にプラスして
ボタンを押すと、パーツが追加されたり色が変わったりという変化をさせたいのです。
シロ様のキャラで言うと、
1)「帽子」ボタンを押下すると帽子をかぶって回転などする
もう一度押すと帽子が無くなる。
2)「色(赤)、(黄色)(白)」ボタンを押すと体の色が変わる
3)追加するパーツは少し多くて「帽子」「ジャケット」などがありますが
「帽子1」「帽子2」のように帽子でも数種類
「ジャケット1」「ジャケット2」「ジャケット3」という風に
したいと思っています。
ボタンは「帽子」ボタン→「1」「2」「3」とするか
「帽子1」「帽子2」「帽子3」
というようにボタンは並べて用意しておくか・・・と頭の中では
想定はしているのですがそもそも、パーツを追加して表示させ
元のデータと同期を取って同じように回転したりできる仕組みがhtml+Three.jsで
作れるのだろうか?と疑問に思っています
お忙しいとは思いますがご教示お願いいたします
はじめまして!
ブログをご覧いただき、ありがとうございます。
ご希望の方法について、記事をまとめてみました。FJさんの参考になれば嬉しいです!
【Three.js】Blenderで作成した3DモデルをWebページで色・表示/非表示を変更する方法
基本的には、こちらの記事のコードを参考にJavaScriptを組んでいただくとご希望の状態を作れるかと思います。
変更したいパーツが多い場合も、blenderで設定したマテリアル名をJSで指定していただくと、そのパーツだけ色変更・表示変更を切り替えられるはずです。
最初から表示したくないパーツがある場合は、blenderでエクスポートする時点で非表示にしておくか、GLTFのロード処理の時点でvisibleをfalseにする等の手段が考えられます。(試していませんが)
以上、HTML+Three.jsをお楽しみください!
シロさま
いつもありがとうございます。
参考になるページありがとうございます。
このページを参考にいろいろ試してみたいと思います。もしかしたらどうしても出来ない・分らないことも出てくるかと思いますのでその時はまたご教示お願いいたします
ありがとうございます。