はじめに
これまでR3Fを使ってWEBGLを遊んできました。
何かしら最終目標が欲しいので、3Dゲームを作るうえで、
R3Fの可能性を信じて最速で動くマルチプレイヤー用のゲームエンジンを集大成として作り始めようと思いました。
ThirdPersonでの動作検証と物理エンジンの設計はすでに完了済みです。
以下、動作検証済みの動画
https://twitter.com/sakanosho/status/1629990635074891779
今回目標とするのは、スマホでも軽快に動き、最高品質のグラフィックを提供できるような設計をできる限り考え、UnrealEngineライクに編集でき、すぐにデバッグができるようなシステムです。
アルファ版完了後はオープンソースとして公開したいです(願望)
設計
ライブラリ名は、NinjaGLとして作成を始めます。
要件
- UnrealEngineライクなエディタ
- UI周りの必要なものはテンプレートとしてある程度用意する事
- スケーラブルでスマホでも快適に動作するマルチプラットフォームである事
- WebRTCを利用したマルチプライヤー対応である事。
- エディタモードと実行モードによる素早いデバックができること。
- 玄人用のスクリプトエディタやシェーダー言語を用意する事
- ビルドしたデータは、各自React環境で実行できること。
システム構成
個人開発なので、複雑なアーキテクチャは組みません。
Next.jsとReactで簡潔に制作をすすめます。
エンジン内ライフサイクル
可視オブジェクト管理領域と物理世界管理に分けています。
基本的に、接続デバイスや高級GPUありなしで、解像度や品質を動的に変更するようにします。
エディタUI画面
あんまり複雑にはしたくないと思ったので、必要最小限の機能で考えてます。
随時アップデートで機能は更新していけばいいかなみたいな感じで。
ただタッチ用のコントローラなどはサンプルプロジェクトで使うものは、デフォルトとして用意することを想定します。
スクリプトの実装例(想定)
現状の想定、これ通りにできるかわかりませんが。
/**
* 初回実行時
**/
setup(){
const obj = NGL.getObjectById("box1");
// マテリアルの変更
obj.material = new MaterialStandardMaterial({color: 0xff0000});
}
/**
* 1フレーム事の処理
**/
loop(state, delta){
const obj = NGL.getObjectById("box1");
// 少しずつ位置の変更
obj.position.x += 0.1 * delta;
}
高速化のための工夫
独自物理エンジン
リッチな物理判定が今回の要件にはアンマッチなので、
Meshwalk.jsを改良して独自エンジンとして実装しました。
- Anmo.jsやCannon.jsに依存しない独自物理エンジン
- 高級すぎずある程度精度を荒く物理判定を行う。
- 物理判定後の衝突移動も基本考慮しない。
- スケーラブルに動的な物理世界のON/OFFの実装
- 8本木法による高速な物理判定と段階数のスケール化
カメラレイヤーの可視化のON/OFF
一定間隔で水平座標にグリッドを引き、
カメラ座標から一定の距離にあるものだけを可視化を行う。
表示できるLは接続デバイスやGPUの使用状況から可変的に動作させることで、描画のクオリティを担保しながら表示を行えます。
また、強制的に表示したいものに関しては、レイヤー0に設定することで、強制表示とします。
// 表示
camera.layers.enable(layerNumber);
// 非表示
camera.layers.disable(layerNumber);
LODの自動化
これに関して考慮するのが2点あり、
粗さに関してはカメラ距離からモデルを切り替えることで高速化につながることが1点と、近いオブジェクトに関しても、見た目上の描画するポリゴン数と物理世界で計算させるポリゴン数は異なってもいいということです。
今回はなにより高速化を考慮したいので、見た目は鮮明なものも低ポリしたものを物理世界で計算させる、もしくはシンプルなAABBとして計算させることで高速化を行います。
-
表示用の低ポリ化は基本モデルアップロード時にサーバー側に送りサーバー側で底ポリ化を行います。
追記:具体的な方法を公式Forumで聞いたところ、すぐに回答くれました。
https://discourse.threejs.org/t/automatic-low-polygon-reduction-for-glb-models/47865/6 -
物理世界の低ポリ化は以前作成した自動LODの記事で行います。
https://qiita.com/osakasho/items/16094d31b43bef8fe60a
最後に
長い道のりになりそうですが、
毎日作業していこうと思います。
終わっているころにはきっとWebGLマスターになっていることでしょうという妄想を抱きながら。
毎朝2時間程度と夜1時間で毎日3時間くらいは確保して進める予定です。
記事ですが毎日投稿は面倒なので、
見せられる切りのいいとこでまとめて投稿する予定です。