この記事は WebGL Advent Calendar 2016 の11日目の記事です。
年の瀬せまる師走の日曜日。皆様はどうお過ごしでしょうか。
筆者はもちろんWebGLでした!
ま、担当日ですから…
それで、結論としては記事タイトルのようなものを作りました。
#【発端】 PTW Tipsというリポジトリを作りました
個人的に、「ファンタスティック トリノワールド」というゲームをもうずっと作っているのですが、ある程度完成が近づいてきて、色々思うところあり、技術的な総まとめを目的としたリポジトリを作りました。
今回の記事はある意味その一環なのです。
コンセプトというかやりたいことは次のようなことです。
- WebGLの技術を自分なりにまとめたい
- ゲームプログラミングの基礎を自分なりにまとめたい
- TypeScriptでクラスを活用したプログラミングを模索したい(PG的欲求)
- ゲーム開発に関連する作業を統合して自動化するツールを作りたい
- ツールの実行環境はElectron(どこでも動く、ライブラリも豊富)
- コンバート処理と描画処理は分離する(描画処理は最適化されたjsonファイルを読み込むだけ)
まだまだ作成中ですが、今のところTypeScriptでWebGLを扱うための基礎的な部分はだいたい作りました。
WebGLでスキンモデルを扱うためのデータ作成と描画の簡単なサンプルも作ったのですが、モデルが簡単すぎてものたりないので、少しきちんとしたモデルでサンプルを作ろうと思いました。
で、時期が合うのでアドベントカレンダーで出すことにしました。
#スキンモデルでトゥーンレンダリングで髪を揺らしたい
また個人的な話ですが、実は映像作品を作りたいという気持ちから、トゥーンレンダリングで髪を揺らすのをやりたいなと常々思っておりました。それでアドベントカレンダーでやろうと。
しかしなかなかに厳しく遠い道です。必要なものが色々あります。ゲームエンジン?知りまs
- スキンモデルのコンバータ作成(鬼畜難易度)
- アニメーションのコンバータ作成(わりと簡単)
- アニメーションの計算実装(わりと簡単)
- スキンモデルの描画実装(けっこう面倒)
- レンダーバッファ描画(仕組みは簡単だが数が増えるととややこしい)
- トゥーンレンダリングの実装(たいてい微妙にうまくいかない)
#スキンモデルデータ作成、コンバートの流れ
- Blenderでモデルを作る
- Collada(.dae)形式でエクスポート
- Electron 上で THREE.js の Collada ローダで読み込む(THREE.jsを描画には使わない...合掌)
- TypeScriptで書いたコンバート処理でjsonファイルを作成
#アニメーションデータ作成、コンバートの流れ
- Blenderでアニメーションを作る
- Electron上で BlendFileReader.js (拙作)で読み込む
- TypeScriptで書いたコンバート処理でjsonファイルを作成
#スキンモデルの描画
モデルを分割して描画します。
コンバータの段階でボーン2つを使用するパーツ、ボーン4つを使用するパーツに分けています。
ドローコールはそれなりに多くなりますが、シェーダの処理は比較的単純になります。
シェーダはTypeScriptでクラスで作成し、共通する部分は継承を使ってできるだけ差分だけ書きます。
文字列で埋め込んだりしていて、少し特殊かもしれません。
それでも関数の中でソースコードを組み立てることができるので、工夫しだいで差分プログラミング的な
こともできるはず。
#トゥーンレンダリング
トゥーンレンダリングは色々考えた結果、形状を決めるためのモデルと影を付けるためのモデルをそれぞれ用意する方法をとることにしました。
下の画像はBlenderからエクスポートするとき選択状態のオブジェクトを出力するため常にこの状態にするのですが、なんというか絵づらがやばい。
描画の流れは次のようになります。
- 背景を描画
- バッファに顔の中(目、口など)以外のモデルを描画
- バッファに深度テストオフで顔の中のモデルを描画
- バッファを参照しながら影モデルを描画
4ではキャラをすっぽり覆う影用モデルを描画して、HSVで明度を落として影を付けます。
影用モデルのアルファ値は無視してバッファのアルファ値を使うことで、
キャラ部分だけに影を付けたような感じになります。
#最後に
なかなかWebGLらしいネタって難しいですが、
ひたすらjsonをデータとして使ってるのがWebGLらしいと思いました。
glTFも熱いですし。
それではよいお年を!