こんにちは
ビッシーです
以前、
【プロシージャル雲に挑戦! 第一回目】の記事を投稿して、
長らく更新が無い状態になっておりましたが、
今年こそ改めてプロシージャル雲に再チャレンジを進めていきたいと思います
プロシージャル雲レンダリングをするにあたって、
大気散乱やボリュームレンダリングといったレンダリング技法を利用していくことになります。
これらの技法をソフトウェアレンダリングで実装することも可能ですが、
計算量が多いため1回のレンダリングに時間がかかってしまいます
ブラウザ上でも、WebGLを使えばシェーダーを使うことができますので、
今回からWebGLを使ったレンダリングに移行していきたいと思います。
(ブラウザ上でWebGLを使ったシェーダーを書けるサービスではShaderToyは有名です)
今回の記事は、雲レンダリングを実装する前に、
HTML5 Canvasを使った2D描画からWebGLを導入して前準備を整えるまでになります。
① WebGL初期化
まずはWebGLの初期化ですが、Canvas 2D同様にHTML側にcanvasタグを作成して、
JavaScriptからwebglコンテキストを作成するだけです
var canvas = document.getElementById("cvs"); gl = canvas.getContext("webgl", {preserveDrawingBuffer:true}) || canvas.getContext("experimental-webgl", {preserveDrawingBuffer:true});
webglのコンテキスト作成に成功すれば、通常のOpenGL同様に、
頂点バッファ・シェーダー・シェーダープログラム等、
必要なリソースを作成して、Canvas描画をすることができるようになります。
(詳細はサンプルコードをご確認ください)
② シェーダーのリロード
シェーダーのリロードも簡単に実装できます。
サンプルでは、編集用にtextareaタグを配置してシェーダーコードのコピーを値として格納しています。
再描画ボタンを押した際に、
下記のサンプルコードのようにtextareaからシェーダーコードを取得して、
シェーダーを再ビルド・再リンクしています。
<textarea id="tarea" class="bg-blue-grey full-width" wrap="off" rows="29"></textarea> <p class="bg-red" id="err"></p>
var err = document.getElementById("err"); gl.shaderSource(fragmentShader, document.getElementById("tarea").value); gl.compileShader(fragmentShader); if(!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { err.innerHTML += gl.getShaderInfoLog(fragmentShader); } gl.linkProgram(program);
コンパイル失敗時のエラーコードをページに反映させるようにしておくと、
エラーの確認がしやすいので便利です
③ PNG保存
通常のCanvas 2D描画同様に toDataURL を使えば、
Canvasの描画結果をPNG化して保存することができます。
var canvas = document.getElementById("cvs"); var dataURL = canvas.toDataURL(); window.open(dataURL, "save");
注意点
として WebGLコンテキストの初期化時に、
preserveDrawingBuffer:true をオプション設定しておかないと正常にPNG化できないことがあります。
(設定なしの場合、カラーバッファが描画後にリセットされてしまうことが原因だそうです)
詳細はサンプルを用意しましたので、ブラウザで確認ください:
※ GoogleChromeで動作確認しています
上記のサンプルでは、
大気散乱のシェーダーコードは Sky-Particles-Shader を参考に実装させて頂いています。
また、CSSフレームワークとして Papier を使わせて頂いております。
これでブラウザを使って雲レンダリングをするための下地が整いました。
次回は、この上に雲レンダリングを実装していきたいと思います
それでは