はじめに
わたしは、Web制作における3Dコンテンツの活用を目的としてBlenderを使用しています
通常、Three.jsのようなライブラリを用いてWeb上で3Dモデルを展示する場合、Blenderで作成された3Dモデルは主に形状、テクスチャ、マテリアルなどのアセットとして利用し、ライトやカメラの設定は、実際にWebページ上での視覚的な表現をコントロールするために、Three.js側で行うのが一般的です
しかし、高品質な静止画を直接出力したいシチュエーションも多々あり、カメラとライトの基本的な操作や、シチュエーションを備忘録として残します
カメラの基本的な操作
カメラのプロパティ
- タイプ :透視投影(遠近感あり)・平行投影(遠近感なし)・パノラマ状から選択
- レンズ単位:焦点距離(ミリメーター単位)か視野角を選択
- 一方を選ぶことは他方の特性も決定することになります
基本的にはレンズの焦点距離(ミリメーター単位)を選ぶことは、同時に特定の視野角(値が大きいほど広角)を選ぶことも意味している - 透視投影とパノラマ状の時に選択
平行投影の場合、「焦点距離」や「視野角」という概念はなく、「平行投影のスケール」で、描画されるオブジェクトのサイズや、特定のビューポート内に表示されるシーンの範囲を指定
- 一方を選ぶことは他方の特性も決定することになります
- 焦点距離:値が小さいほど広角
- 短い焦点距離(例:24mm、28mm): 広角レンズ(広い範囲の景色を撮影)
建築物の撮影や風景写真に適している
*被写体の前後に広がる空間が強調され、遠近感が強く出ます。ただし、顔などの撮影では歪みが出やすい - 標準焦点距離(例:50mm、35mm): 人間の目が見る範囲に近い視野
日常の撮影によく使用される - 長い焦点距離(例:85mm、200mm以上): 望遠レンズ(遠くの被写体を大きく撮影)
スポーツや野生動物の撮影に適している
*被写体がフレームに大きく映り、背景がぼけやすくなります。遠近感は抑えられ、被写体を際立たせることができる
- 短い焦点距離(例:24mm、28mm): 広角レンズ(広い範囲の景色を撮影)
- シフトX・シフトY:カメラの位置はそのまま向きをずらす
撮影する範囲や角度を微調整 - 範囲の開始 :カメラからどの距離からオブジェクトが見え始めるかを指定
この値を大きくすると、カメラに近いオブジェクトが表示から除外され、シーンの「前方」部分が切り取られます
非常に近い距離のオブジェクトによるビューの妨げを防ぐのに役立つ - 終了: カメラからどの距離までのオブジェクトが表示されるかを指定します
この値を小さくすると、遠方のオブジェクトが表示から除外され、遠い距離のオブジェクトがシーンの計算やレンダリングを複雑にしないようできる - 被写界深度:カメラの焦点が合っている範囲のことで、この範囲内にあるオブジェクトは鮮明に、範囲外にあるオブジェクトはぼやけて表示
- 絞り:F値が小さいほど、背景がぼける
カメラの移動
3Dビューで自分が見ている視点にカメラを移動させる方法
今見ている視点にカメラのビューを合わせる
- 画面上で撮りたい視点に移動
- 「ビュー」→「視点を揃える」→「現在の視点にカメラを合わせる」
またはCtrl + Alt + Numpad 0
画角を見ながら見え方を微調整
カメラのビューをロックして画角の調整をします
- 「Numpad 0」でカメラビューに切り替える
- 「Nキー」でサイドバーを開く
「ビュータブ」→「ビューのロック」→ロック「カメラをビューに」にチェック - 画角や見え方を調整
カメラビューがロックされている状態で、3Dビューポートを操作したり、カメラプロパティを調整して、画角や見え方を微調整します
*画像サイズは「出力」プロパティの「フォーマット」→「解像度」の項目から変更できます
複数のカメラを配置した場合は、シーンプロパティの「カメラ」からアクティブカメラを切り替える
*アクティブカメラは、カメラの上の三角の部分が黒くなります
ライトの基本的な操作
ライトの種類
- ポイントライト:イメージは裸電球やろうそくの光
特定の点から全方向に光を放射します
位置によって光の影響が決定され、光の強さは距離に応じて減衰します - スポットライト:イメージはステージのスポットライトや懐中電灯の光
一定の方向に向けて光を放射するライトで、光の範囲(角度)を調節できます
光の範囲(コーンの形状)、強さ、減衰率を調整でき、シャープな影を作り出すのに適しています - サンライト:イメージは太陽光
無限遠から来る一様な光で、シーン全体に均一な照明を提供
主に屋外のシーンや日中の光源として使用されます
方向は調整できますが、位置は光の影響に影響しません - エリアライト:イメージは窓からの自然光
一定の面積から光を放射するライトで、ソフトで拡散した影を作り出します
形状(四角形、円形など)やサイズを調整でき、それによって光の分布や柔らかさが変わります
黄色の点をクリックして動かすと、ライトの当たる方向を変更できます
「3点照明」は、オブジェクトや人物を照らすために3つの光源を使用するもので
キーライト(主光源)、フィルライト(補助光源)、バックライト(逆光)の3つから構成されます
- キーライトは、オブジェクトに対する主な光源で、形状とテクスチャを明らかにします
これが最も強い光で、シーンの視覚的な焦点を作り出します - フィルライトは、キーライトの反対側から来るより弱い光で、キーライトによって作られた陰の中にあるディテールを引き出します
オブジェクトの立体感を強調し、コントラストを和らげる効果があります - バックライトは、オブジェクトの背後から照らし、オブジェクトの輪郭を明瞭にし、背景から際立たせます
被写体の立体感が増します
テクスチャを適用したライトを使用
*ライトは、形や色だけでなく、「テクスチャ」を設定して画像を投影することができる
- ライトにテクスチャを使う際は、「レンダーエンジン」を「Cycles」に設定する
- ライトのオブジェクトデータプロパティで「ノードを使用」をクリックし、シェーダーエディターを開きくか、または、ライトを選択してシェーダーエディターを開き「ノードを使用」をチェック
- 「Node Wrangler」を有効にした状態で「放射」を選択して Ctrl+ T
*必要なノードを生成してくれる - 画像テクスチャの「開く」から、画像を読み込みむ
- テクスチャ座標の「ノーマル」と、マッピングの「ベクトル」を接続
環境マップを生成する
例えば、Blenderでパノラマカメラ設定を利用し、360度のパノラマ画像を生成できます
オブジェクトを配置して、360度のパノラマ画像を作成するのは現実的ではないかもしれませんが、ライトを使って360度のパノラマHDR画像を作成し、それをThree.jsの環境マップとして使用したりできます
*HDR画像は、通常の画像が持つ明るさの範囲よりもはるかに広いダイナミックレンジを表現できる画像フォーマットです
1:レンダリングエンジンを「Cycles」に切り替えます(よりリアルなレンダリングが可能になります)
2:レンダリングのサンプリング値を設定し、レンダリングとビューポートの両方で最大サンプル数を256程度に下げて設定します
*完全な品質でのレンダリングが必要ない場合や、素早くプレビューを確認したい場合は、サンプリング数を低く設定することで、レンダリング時間を短縮することが可能
シーン全体の背景色を黒に設定します
*背景を黒にすることで、照明されたオブジェクトと背景との間のコントラストが高まり、シーン内のオブジェクトを照らすために追加されるライトがより目立つようになります(ライトの設定が重要になる)
2048×1024のような2:1のアスペクト比を持ち、かつ2のべき乗の解像度を選択する
*環境マップやパノラマ画像の目的で使用する場合は、2:1のアスペクト比が一般的に推奨
*またWebGL 2環境でのパフォーマンス最適化および他のソフトウェアとの互換性のため2のべき乗の解像度を推奨
パノラマカメラを設定
1:カメラを選択
2:Nキーを押して、パネルを表示、「アイテム」タブから「位置」と「回転」をリセット
3:X軸の回転を90度に設定
4:「カメラ」プロパティの「レンズ」で、タイプは「パノラマ状」に、パノラマタイプは「正距円筒図」を選択
ライトがレンダリング時にカメラから見えるようにする場合
ライトを選択して「オブジェクト」プロパティ→「可視性」→「レイの可視性」の中の「カメラ」にチェックをつける
ライトを配置する
F12キーを押し、アクティブなカメラの視点からのシーンのレンダリングを開始
画像を保存します
ALT + S 一番下でファイル名を変更、ファイル形式として「Radiance HDR」を選択
const rgbeLoader = new RGBELoader()
rgbeLoader.load('作成したHDR画像のパス', (environmentMap) =>{
environmentMap.mapping = THREE.EquirectangularReflectionMapping
// scene.background = environmentMap //背景も表示したい場合
scene.environment = environmentMap
})
影をベイクしたテクスチャの作成
モデルに影をベイクしたテクスチャを使用すると、動的な照明や影に対応できませんが、リアルタイムでの光源計算を必要としないため、レンダリングパフォーマンスが向上します
ただし、モバイルデバイスは、一般的にデスクトップPCや専用のゲーム機に比べてGPUの性能が制限され、特に、GPU内部の帯域幅が限られているため、高解像度の画像や複雑な3Dモデルなどのリソースを大量に同時に処理する際には、注意が必要です
UV展開を開始する前の準備
- 非表示の面を削除する
*計算リソースの節約 - 光の影響をテクスチャにベイクしたい場合は、リンクされた複製(Alt + D)のオブジェクトはリンクを解除する
*リンクされた複製の場合、オブジェクトが同じデータ(メッシュやマテリアルなど)を共有している状態
リンクされた複製の解除:オブジェクトモードでAキーを押してシーン内の全オブジェクトを選択します(または、ベイキング対象のオブジェクトのみを選択
「オブジェクト」→「関係」→「シングルユーザー化」→「オブジェクトとデータ」 - 面の向き(面と裏)を正しく設定する
*Blenderでモデリングしている際、特に押し出しや内部押し出し、その他の操作を行うときに、意図せず面の向き(法線の向き)が反転してしまうことがあります
面の向きが正しくないと、テクスチャベイキングのプロセス中に予期しない結果が生じることがあります
例として、法線が内側を向いている(つまり、面が裏向きである)ために、テクスチャのベイキング時に適切に光を受け取れない状態になり黒く表示される
法線の向きを確認して、修正する方法- 確認:ビューポートの右上にあるオーバーレイ表示オプションから
「面の向き」にチェック
*正しい向きの面は青で、誤った向きの面は赤で表示 - 修正:赤く表示されている(向きが誤っている)面を修正するオブジェクトを選択
編集モードで誤った向きの面を選択
「メッシュ」→「ノーマル」→「反転」
- 確認:ビューポートの右上にあるオーバーレイ表示オプションから
- 編集モードとオブジェクトモードでスケーリングを行った場合、スケール値とジオメトリのサイズが不一致になるので、スケールを正規化する
オブジェクトモードにて、Aキーを使ってシーン内の全オブジェクトを選択
Ctrl + Aを押して「Apply」メニューを開き、「スケール」オプションを選択
UV展開の実施
ベイクしたテクスチャ画像を作成
- 新規画像を作成、幅と高さは大きめ(4096)に、テクスチャにアルファは必要ありません
32ビット浮動小数点数にチェック(HDR テクスチャを作成したことになります)
*作成した画像は.hdrで保存 - マテリアルごとにベイク処理をします
シェーディングタブを開き、テクスチャの画像テクスチャノードを追加
作成しておいた画像を割り当てます
画像テクスチャノードが選択されていることを確認 - レンダープロパティで「Cycles」に
サンプリングの最大サンプルは128程度、デノイズのチェックを外す
ベイクのパラメーターを調整
主なパラメーター
*ベイクタイプ:統合(すべての光の情報を含む総合的なレンダリング結果をベイク)
*ビュー元:アクティブカメラ(アクティブなカメラの視点からレンダリング)
*出力:ターゲットが画像テクスチャになっていることを確認、画像クリアのチェック不要
*余白:拡張にするとエッジがより滑らかに、サイズはもしベイクされたアイランドが隣り合うアイランドに重なってしまう場合は16pxからサイズを減らすことができる
ベイクボタンをクリック
ベイク処理完了後のHDR画像のポストプロセッシング(映像や画像が生成された後に行う追加の処理や編集)
コンポジターでこれらの問題に対処する
- ノイズの問題:レンダリング時にデノイズ処理を行っても、ベイクした画像にはその設定が適用されず、ノイズが目立つ
- 色の問題:ベイク処理を行うと、Filmic色空間が適用されないため、レンダリングされた画像に比べて、コントラストが高くなる
- 画像タイプの問題:Three.jsなどのウェブベースのアプリケーションで使用するためには、軽量なJPEG形式で、sRGBエンコーディングを適用した画像が望ましい
コンポジターは、ノードベースの画像編集ツールで、レンダリングされた画像に対してデノイズ処理を行ったり、Filmic色空間を適用したり、最終的に望ましいフォーマットで出力するための処理を行えます
- コンポジターを開き、「ノードを使用」にチェック
*レンダーレイヤーとコンポジットが存在する - 1:ベイクされた画像を入力の「画像」ノードを使用して読み込み
2:フィルターの「デノイズ」ノードを追加して、画像にノイズ除去処理を適用
*Filmicの適用:レンダリングプロパティのデフォルトのカラーマネジメントのパラメータが「Filmic」なので、通常は 自動的に適用されます
3:レンダーレイヤーを選択して、Mキーでミュート(無効にする) - 出力プロパティで、画像の解像度をベイクされたテクスチャと同じに設定する
- レンダリングを実行(時間がかかる)、得られた画像はJPEG形式で保存
Three.jsを使用してダウンロードしたモデルにベイクしたテクスチャ画像を適応する
モデルをエクスポート
オブジェクトをマージする(レンダリングすべきオブジェクトの数を少なくする)
*ドローコールが減少し、パフォーマンスが向上します
マージしたいオブジェクトを選択し、Ctrl + JまたはMacは「Cmd + J」を押すことで、選択したオブジェクトを一つに統合できます
*注意:マージすると戻せないので、作業を始める前にバックアップする
gltfファイルでエクスポート
*べイクされたテクスチャには、影や色などビジュアルディテールが含まれているので、基本的には「マテリアルを含めない」、データ(メッシュ)は「UV」が必要
備考
マテリアルの設定:MeshBasicMaterial(照明が必要ないので)のmapプロパティにテクスチャを適応する
テクスチャのY座標が反転している問題に対処するため、flipYプロパティをfalseに設定
テクスチャがsRGB色空間でエンコードされているので合わせる
const textureLoader = new THREE.TextureLoader()
const gltfLoader = new GLTFLoader()
const bakedTexture = textureLoader.load('テクスチャのパス(.jpg)')
bakedTexture.flipY = false
bakedTexture.colorSpace = THREE.SRGBColorSpace
const bakedMaterial = new THREE.MeshBasicMaterial({ map: bakedTexture })
gltfLoader.load(
'モデルのパス(.glb)',
(gltf) =>{
gltf.scene.traverse((child) => {
//すべてのメッシュオブジェクトに対してbakedMaterialを適用
if (child.isMesh) {
child.material = bakedMaterial;
}
})
scene.add(gltf.scene)
}
)