はじめに
最近、Blenderをちょいちょい触ることがあったので、それをブラウザで表示できないかと思い、その方法を調べてみた。
開発環境
- Ruby on Rails 7.0.0
- Blender 2.93.5
3Dモデルを用意
glTF形式の3Dモデルを用意。今回はBlenderを使って作成した。
- BlenderでglTF形式でエクスポートをかける際に、Draco圧縮をかけてデータを圧縮をする
Draco圧縮とは?
DRACO(Dynamic Range Adaptive Compression Optimization)は、Googleが開発した、3Dモデルのデータ圧縮を目的としたオープンソースのライブラリ。DRACOは、3Dメッシュデータを非常に効率的に圧縮することができ、ファイルサイズを小さくし、モデルの読み込みや表示のパフォーマンスを向上させる。
出力したglTFは、GLTFLoaderで読み込むことができるが、Draco圧縮した場合は、DRACOLoaderを設定する必要有り。
https://www.pentacreation.com/blog/2020/02/200213.html
① ファイル → エクスポート → glTF形式ファイルを選択
② 次の画像のように設定(フォーマットはglTFバイナリで)
エクスポートしたglTFファイルは、publicディレクトリ内にmodelsというディレクトリを新たに作成し、そこに格納した。
HTMLの用意
今回は、HTMLファイルにスクリプトもCSSも記述した。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>gltf形式の3DモデルをThree.jsを用いてブラウザに表示する方法</title>
// 外部モジュール
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.151.3/build/three.module.js",
"OrbitControls": "https://unpkg.com/three@0.151.3/examples/jsm/controls/OrbitControls.js",
"GLTFLoader": "https://unpkg.com/three@0.151.3/examples/jsm/loaders/GLTFLoader.js",
"DRACOLoader": "https://unpkg.com/three@0.151.3/examples/jsm/loaders/DRACOLoader.js",
"lil-gui": "https://cdn.jsdelivr.net/npm/lil-gui@0.19/+esm"
}
}
</script>
</head>
<body>
<!-- // 3Dモデルを表示させるcanvas要素を作成 -->
<canvas id="canvas"></canvas>
<script type="module">
import * as THREE from 'three';
import { GLTFLoader } from "GLTFLoader";
import { DRACOLoader } from 'DRACOLoader';
import { OrbitControls } from "OrbitControls";
import GUI from 'lil-gui';
// 画面サイズの取得
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
// レンダラーの作成
const canvas = document.getElementById('canvas')
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(windowWidth, windowHeight);
// シーンの作成
const scene = new THREE.Scene();
// 背景色の設定(黒)
scene.background = new THREE.Color('#000000');
// 見やすいようにヘルパー(網目)を設定
let gridHelper = new THREE.GridHelper();
scene.add(gridHelper);
// カメラを作成
const camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000);
camera.position.set(0, 0.45, -1);
camera.rotation.set(-2,1,3);
camera.lookAt(camera.position);
// ライトの作成
const light = new THREE.PointLight(0xffffff, 2, 100);
light.position.set(10, 20, 5);
scene.add(light);
// マウス制御
const controls = new OrbitControls(camera, renderer.domElement);
// DRACOLoaderを設定
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.1/'); // デコーダーのパスを設定
// 3Dモデルの読み込み
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('../models/ファイル名', function (gltf) {
const model = gltf.scene;
model.scale.set(0.1, 0.1, 0.1);
scene.add(model);
}, undefined, function (error) {
console.error(error);
});
// アニメーション
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
//lil-GUI
const gui = new GUI();
const cameraFloder = gui.addFolder("camera_position");
cameraFloder.add(camera.position,"x").min(-5).max(5).step(0.01);
cameraFloder.add(camera.position,"y").min(-5).max(5).step(0.01);
cameraFloder.add(camera.position,"z").min(-5).max(5).step(0.01);
//ブラウザのリサイズに対応
function onWindowResize(){
renderer.setSize(window.innerWidth,window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); //カメラのアスペクト比を正したら必ず記述
}
window.addEventListener("resize",onWindowResize);
// アニメーション実行
animate();
</script>
<style>
body{
margin:0;
width:100%;
height:100%
}
</style>
</body>
</html>
今回読み込むのは、以下の4つ。
- DRACOLoader:Draco圧縮したデータを読み込む。
- OrbitControl:OrbitControlsを使用する事で空間内のカメラの動きをマウスで制御可能。
- GLTFLoader:GLTFLoaderを使用することでglTF型式の3Dモデルを読み込む。
- lil-GUI:パラメータを視覚的に操作できるUI。
JavaScript
・GridHelper: 地面がどこにあるのかを把握できる。
let gridHelper = new THREE.GridHelper();
scene.add(gridHelper);
・OrbitControls: canvas内での空間内のカメラをPCならマウス操作、モバイルならタッチ操作する事が可能。
const controls = new OrbitControls(camera, renderer.domElement);
参考
https://qiita.com/enumura1/items/c62f15c4fbeb541fa830
https://lil-gui.georgealways.com/#Guide#Installation
作品
https://syeimee.com/creations/tunnel.html
今回はここまで。