2022.11.16 Web制作
軽くリアルに!ベイク処理で3DモデルをWebサイトに描写する方法
はじめに
今回は、よりリアルな3DモデルをWebサイト上で表現する方法についての記事になります。
3Dモデルをそのまま読み込む方法については、前回の記事で紹介しております。
今回はBlender側で処理することが多いので根気が必要です。
ですが、高品質かつ高パフォーマンスで3Dモデルを読み込むことができるので、描写したいモデルにこだわりたい場合はベストな方法だと思います。
ベイクについて
ベイクとは3Dモデルの形状や質感または、関与する影や光など画像に焼き込むことです。
この処理をBlender側で行うことで、Three.jsでライトや影の設定が不要になるのでパフォーマンスは向上し、質感もBlenderのレンダリング結果と近づけることができるのでメリットづくしというわけです。
ただ、やらなくてはならないことが増えるのでそこそこ覚悟しなければなりません。
ちなみに今回はベイクマップを作成するにあたって、Blenderのアドオン(拡張機能のようなもの)を使用しないで行ったのですが、手間がかかるのでUV展開やベイクを行う工程はアドオンを使用することをおすすめします。
3Dモデルを作成 (Blenderレンダリング結果)
今回Blenderでモデリングしてレンダリングした結果が下記になります。
Webで表現したときにどこまで質感を再現できるのか試したかったので、
ランタンの本体のテクスチャーは少し傷がはいった黒の金属を使用しました。
ライト部分はオレンジ色の発光を設定し、
反射光などの影響を確認するために簡単な壁と床も置きました。
3DモデルをUV展開する(Blender操作)
モデルに意図通りにマテリアルを設定するにはUV展開が欠かせません。
一つ一つシーム(切り込み)をいれてモデルを展開するのがメジャーかもしれませんが、自動でUVマップを作製してくれる機能のスマートUV投影を使います。
・オブジェクトモード→編集モードに切り替える
・対象のメッシュをすべて選択し⇒UV⇒スマートUV投影
・重ならないようにアイランドの余白を少し設定することをおすすめします。
作成したUVマップを確認(Blender操作)
UVエディターで作成したUVマップを確認します。
展開した面が他の面と重なっていないか確認してください。
また作成したモデルの面が裏返ってたりすると意図通りにならないことがあるので、面の向きも確認したほうがいいです。
画像エディターでベイク先の画像を作成(Blender操作)
画像エディターを開き、ベイク先の画像を作成します。
このデータをThree.jsでも使用します。
新規作成する画像の設定(Blender操作)
画像サイズを幅4096px、高さ4096pxで設定しました。
カラーは白で設定します。
アルファチェックを外し、
32ビット浮動小数点にチェックしました。
新規作成する画像の保存形式設定(Blender操作)
作成した画像を名前をつけてBlenderファイルと同じフォルダに保存します。
最終的にJPGに変換するのですが、高品質にしたいのでファイルフォーマットはHDR形式を選択してください。
シェーダーエディターを開く(Blender操作)
シェーダーエディターを開き、メッシュすべてに画像テクスチャを追加します。
ノードを繋げる必要はないですが、先ほど保存したベイクのベースとなる画像を開きます。
準備ができたのでベイク開始(Blender操作)
すべてのメッシュに画像テクスチャを追加し、ベイク先の画像を開いた状態にできたらベイクを開始します。ここでBlenderが突然落ちたりするのでベイク前に保存しておくことをお勧めします。
また処理に時間もかかります。
レンダープロパティからベイクできます。
完成した画像がこちら
うまくベイクできました。
こちらをJPGに変換して3Dモデルのテクスチャーとして貼り付けるイメージですね。
光や影も事前に焼き込んでいるのでThree.jsでライトや影の設定をする必要がないです。
作成したベイクマップをJPGに変換(Blender操作)
3DモデルをglTF形式でエクスポート(Blender操作)
3DモデルをエクスポートしてBlender側の操作は終了です。
内容ではもっていきたい情報を設定します。
ライトやカメラは不要なのでチェックを外します。
トランスフォームでは+Yが上にチェックします。
ジオメトリではUVのみを選択します。
アニメーション等の項目も使用しないのですべてチェックを外しておきます。
モデルとテクスチャーの読み込み(Three.js)
モデルとベイクマップをThree.jsを用いてWebサイトで描写してみましょう。
Three.jsのインストール方法についてはこちら(公式)になります。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>project</title>
</head>
<body>
<canvas class="project"></canvas>
</body>
</html>
JS
import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
const canvas = document.querySelector('canvas.project') const scene = new THREE.Scene() const textureLoader = new THREE.TextureLoader() const gltfLoader = new GLTFLoader() // ベイク画像の設定 const bakedTexture = textureLoader.load('texture.jpg') bakedTexture.flipY = false bakedTexture.encoding = THREE.sRGBEncoding // マテリアル設定 ベイク画像をマテリアルとして適用 const bakedMaterial = new THREE.MeshBasicMaterial({ map: bakedTexture }) // モデルの読み込み gltfLoader.load( 'model.glb', (gltf) => { gltf.scene.traverse((child) => { child.material = bakedMaterial }) scene.add(gltf.scene) } ) const sizes = { width: window.innerWidth, height: window.innerHeight } window.addEventListener('resize', () => { sizes.width = window.innerWidth sizes.height = window.innerHeight camera.aspect = sizes.width / sizes.height camera.updateProjectionMatrix() renderer.setSize(sizes.width, sizes.height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) }) // カメラの初期位置など設定 const camera = new THREE.PerspectiveCamera(45, sizes.width / sizes.height, 0.1, 100) camera.position.x = 2 camera.position.y = 4 camera.position.z = -7 scene.add(camera) const controls = new OrbitControls(camera, canvas) controls.enableDamping = true // レンダー設定 const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true }) renderer.setSize(sizes.width, sizes.height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) renderer.outputEncoding = THREE.sRGBEncoding const clock = new THREE.Clock() const tick = () => { const elapsedTime = clock.getElapsedTime() controls.update() renderer.render(scene, camera) window.requestAnimationFrame(tick) } tick()
Web上での表示がこちら
質感やライティングなどBlenderのレンダリング結果と近い品質で表現することができました。
またライトや影は、ベイクマップで焼き込んだものを描写しているだけでなのでパフォーマンス面も良いです。
まとめ
今回の作業のなかで難解なポイントは、
ベイクがうまく実行できなかったり、
ベイクマップを正しく貼れなかったりすることだと思います。
よくある原因としては、ノードや他の設定が引っ掛かっていたり、UV展開が正しくなかったり、オブジェクトの面の向きが反転していたりすることなのですが、根気強く原因を探るしかないです・・・。
個人的に躓いたのはベイク時に何度もBlenderが落ちることでした。レンダリングの設定が甘かったのかスペックが足りなかったのか何度か繰り返したらうまくいったので原因ははっきりしなかったです。
アドオンを使ってUV展開やベイクをすることで処理が楽になるので、自分に合ったBlenderのアドオンを探してみるのもおススメです。
WEBサイト・ホームページの制作をご検討の方
フライング・ハイ・ワークスの紹介
フライング・ハイ・ワークスは、東京のホームページ制作・Web制作会社・システム開発会社です。東京都及びその近郊(首都圏)を中心として、SEO対策を意識したPC及びスマホのサイトをワンソース(レスポンシブ対応)で制作します。
実績
デザイナーチームは、グラフィックデザインやイラストの制作も得意としており、著作権を意識しない素材の提供が可能です。システム・コーディングチームでは、Laravelなどを使用したスクラッチからのオリジナルシステム開発を始め、WordPressのカスタマイズを得意としております。
また、SEOやランディングページ(LP)、広告向けバナーなどを他社様でやっていた作業の引継ぎでも問題ありません。制作実績は多数ございますので、お客様に合わせたご提案が可能です。
500点以上のフライング・ハイ・ワークスの制作実績ページをご覧ください。