見出し画像

WebGLフレームワークを作る Part3 使い続ける

断捨離GL(dan-shari-gl)について

断捨離GL(dan-shari-gl)は2018年10月から開発を開始し、以前作っていたTubuGLの使える部分を拝借し、改良を加え2018年11月にGithubに初めてプッシュしました。

TubuGLの開発とプロジェクトでの利用によってWebGL APIを実際のプロジェクトでどう利用するか把握できました。

なんでもかんでもクラス化することをやめて、WebGL APIで2行以上の処理が必要な場合、関数化することと最適化するためになるべくWebGL APIを使うことを断捨離GLではルールとして設けました。

以下が断捨離GLを使ったサンプルです。dsr.***が断捨離GLの関数となります。球体のプログラム・バッファーの作成、uniformのlocationの取得をしています。

/**
* 断捨離GLで球体を作成
* dsr.**が断捨離GLの関数である
*/
const vertexShaderSrc = `(省略)` // vertex shader
const fragmentShaderSrc = `(省略)` // vertex shader

function createSphere(){
    // 球体をレンダリングするためのprogramを生成する
    const program = dsr.createProgram(gl, vertexShaderSrc, fragmentShaderSrc);

    // 球体の座標、法線、インデックスを配列として取得する
    const { vertices, normals, indices } = dsr.getSphere(5, 32, 32);

    // vertex shaderにattributeとして渡す頂点、法線、インデックスバッファーを取得
    const buffers = {
	position: dsr.createBufferWithLocation(gl, this.program, new Float32Array(vertices),'position'),
	normal: dsr.createBufferWithLocation(gl, this.program, new Float32Array(normals), 'normal'),
	index: dsr.createIndex(gl, new Uint16Array(indices))
    };
    
    // uniformのロケーションを取得する    
    const uniforms = dsr.getUniformLocations(gl, program, ['uMVPMatrix']);
    
    return {program, buffers, uniforms};
}

TubuGLの管理が面倒・複雑になった1番の理由は多くのリポジトリを作ってモジュール化したことです。コア部分を少し更新するたびに他のリポジトリにバグがないかを確認する作業が増えました。

断捨離GLでは基本的にリポジトリを1つにして、更新の面倒さを減らすようにしました。


リポジトリについて

TypeScript library starterを使用して開発すすめています。

当初はJavaScript(以下js)で開発してたのですが、使用しているVS CodeだとTypeScriptの補完が強力なのとTypeScript library starterはドキュメントの作成やjsの書き出しがとても簡単なのでTypeScriptにしました。静的な型付け言語であるTypeScriptは規模が大きくなればなるほど、安心しますね。


フレームワークの構成

フレームワークの構成は以下のようになっています。

フレームワークのファイルが入っているsrcフォルダーとデモやドキュメントを管理し公開するdocsフォルダーによって構成されています。

SRCフォルダー

以下のようなフォルダー構成でフレームワークを作成しています。

src - dan-shari-gl.ts
    |
    | - utils
    |       | --- common
    |       | --- functions 
    |       | --- generate
    |
    | - camera
    |
    | - math
    |
    | - subComponents

dan-shari-gl.ts: srcフォルダー内のファイルをすべてエクスポートする

utils: よく使う関数や定数などをまとめているフォルダー

utils/common: WebGL APIのよく使う定数。gl_contextなくても使えるようにしている。

utils/functions: シェダーのコンパイル、programの作成、テクスチャーの作成などwebgl開発で1番使うけど、なかなか覚えられないものをまとめている。

utils/generate: よく使う四角、立方体、球体などのgeometryの頂点や法線など返す関数などを入れている。

camera: perspectiveカメラ、orthographicカメラを扱うクラス。projection行列やview行列を返す関数でもよかった。よく使うのでクラス化した。

math: よく使う数学の関数をRayクラスが入ってる。Rayクラスはベクトルと面の交差を計算するクラス。マウスオーバーなどのを機能を追加することができる。

subComponents: cameraをマウスのドラッグで動かせるcameracontrollerファイルなど個人的によく使うファイルコレクション。

docsフォルダー

dan-shari-glのサイトを構成するディレクトリーです。dan-shari-glのサイトは以下から見ることができます。

docsの中にはDocuments, Examplesがあります。今年中にはTutorialを作成していきたいです。


Documents

srcフォルダーに入ってるフレームワークを構成するファイルから自動的に生成されます。

コマンド一つで生成されるので、非常に便利です。

Examples

断捨離GLを使ってデモを作っています。

デモを作る基準は使い回しがききそう、技術的に取れ入れていかないといけない、忘れないために作る必要があると感じたものを作成しています。

デモの数が少ないので、今後もう少し増やしていきます。(週1で増やしていきたい。いやいかないと、、)

日々のプロジェクトに使用する

自分用のフレームワークを使い続けることは作ること・日々改良を加えたり、デモを作るのと同じくらい大切だと感じています。

スムーズに試作やプロジェクトに着手できるように以下の断捨離GLを使ったリポジトリを2つ使用しています。


スケッチや簡単な試作を作成するときには使うリポジトリです。

リポジトリのsrcフォルダです。ベースとなるboilerplateとして使用しています。

src - index.ts
    |
    | -components - sphere - sphere.ts
                           |
                           | - shaders - shader.frag.glsl
                                       - shader.vert.glsl

index.tsにはglの生成、球体(sphere)のオブジェクト作成、描画の実行などアプリケーションのベースを作成しています。sphereフォルダーには、シェーダーとsphereを描画するときに使用するupdateやrenderなどのメソッドやbuffersやprogramといったプロパティが存在します。


html要素も入ったアプリケーションレベルに使うリポジトリです。先程のリポジトリ+アルファといったものになっています。

canvas(gl)とhtml要素を連携したり、ローディングコンポーネントなどが入っています。

簡単なmvvc(mvc)フレームワークもオリジナルです。backboneの簡易版で、プロジェクトのjson変えたら文章の差し替え、ページや画像の追加などはできるので、事足りてます。


ツールを作成する

頻繁に作るものなどはツールでベースとなる機能を簡単にすぐに作成できるようにしています。

現在使用できるものはdan-shari-gl Mesh Generatorというツールだけです。

meshファイルとfragment/vertex シェーダーのベースとなるファイルとコードを一式作成します。

node.jsで作成していて、グローバルにインストールするとcliとしても使用できます。


今後の課題点

API

- WebGL2のAPIを導入する。


デモ・サンプル

- 作りたいデモがまだ30%ぐらいしか作れていない。

- dsr-graphic-samplesというリポジトリを作成し、phong shadingやpbrなどレンダリング手法のサンプルをまとめる。


その他

- Tutorialページを作成する。

- テストコードを作成する。


最後に

フレームワークを作成するのは非常に地味で時間のかかる作業です。学ぶ領域が大きいと感じています。

学びながら成長し、成長しながら改良していくという知的な刺激の多い体験です。日頃使うライブラリの内部構造を知るのに役立ちます。three.jsのライブラリからレンダリング箇所についてもわからないということがなくなりました。

VRやARのデモを見て、行列の問題として自然と捉えることができるようになったのはフレームワーク作り続けているおかげだと感じています。

完成を目標とせずリアルタイム・レンダリングの日々の疑問や好奇心をベースにし、過去の偉大なる巨人の肩に載せてもらいながら、作り・使い続けていこうと思っています。

この記事が気に入ったらサポートをしてみませんか?