6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

WEBGL用ゲームエンジン作ってみる ~ 1日目 ~

Last updated at Posted at 2023-02-27

はじめに

これまでR3Fを使ってWEBGLを遊んできました。
何かしら最終目標が欲しいので、3Dゲームを作るうえで、
R3Fの可能性を信じて最速で動くマルチプレイヤー用のゲームエンジンを集大成として作り始めようと思いました。

ThirdPersonでの動作検証と物理エンジンの設計はすでに完了済みです。
以下、動作検証済みの動画
https://twitter.com/sakanosho/status/1629990635074891779

以下、動作検証済みのキャプチャ図
layera1.gif

今回目標とするのは、スマホでも軽快に動き、最高品質のグラフィックを提供できるような設計をできる限り考え、UnrealEngineライクに編集でき、すぐにデバッグができるようなシステムです。

アルファ版完了後はオープンソースとして公開したいです(願望)

設計

ライブラリ名は、NinjaGLとして作成を始めます。

要件

  • UnrealEngineライクなエディタ
  • UI周りの必要なものはテンプレートとしてある程度用意する事
  • スケーラブルでスマホでも快適に動作するマルチプラットフォームである事
  • WebRTCを利用したマルチプライヤー対応である事。
  • エディタモードと実行モードによる素早いデバックができること。
  • 玄人用のスクリプトエディタやシェーダー言語を用意する事
  • ビルドしたデータは、各自React環境で実行できること。

システム構成

個人開発なので、複雑なアーキテクチャは組みません。
Next.jsとReactで簡潔に制作をすすめます。

image.png

エンジン内ライフサイクル

可視オブジェクト管理領域と物理世界管理に分けています。
基本的に、接続デバイスや高級GPUありなしで、解像度や品質を動的に変更するようにします。

image.png

エディタUI画面

あんまり複雑にはしたくないと思ったので、必要最小限の機能で考えてます。
随時アップデートで機能は更新していけばいいかなみたいな感じで。
ただタッチ用のコントローラなどはサンプルプロジェクトで使うものは、デフォルトとして用意することを想定します。

image.png

スクリプトの実装例(想定)

現状の想定、これ通りにできるかわかりませんが。

samplescript.js
/**
* 初回実行時
**/
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

一定間隔で水平座標にグリッドを引き、
カメラ座標から一定の距離にあるものだけを可視化を行う。
image.png

表示できるLは接続デバイスやGPUの使用状況から可変的に動作させることで、描画のクオリティを担保しながら表示を行えます。
また、強制的に表示したいものに関しては、レイヤー0に設定することで、強制表示とします。

// 表示
camera.layers.enable(layerNumber);
// 非表示
camera.layers.disable(layerNumber);

LODの自動化

これに関して考慮するのが2点あり、
粗さに関してはカメラ距離からモデルを切り替えることで高速化につながることが1点と、近いオブジェクトに関しても、見た目上の描画するポリゴン数と物理世界で計算させるポリゴン数は異なってもいいということです。
今回はなにより高速化を考慮したいので、見た目は鮮明なものも低ポリしたものを物理世界で計算させる、もしくはシンプルなAABBとして計算させることで高速化を行います。

最後に

長い道のりになりそうですが、
毎日作業していこうと思います。
終わっているころにはきっとWebGLマスターになっていることでしょうという妄想を抱きながら。

毎朝2時間程度と夜1時間で毎日3時間くらいは確保して進める予定です。

記事ですが毎日投稿は面倒なので、
見せられる切りのいいとこでまとめて投稿する予定です。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?