WebGL で MRT を使い Deferred Shading(遅延シェーディング)を実装したデモが公開中!

doxas : 2016-12-04 14:14:15

複数のバッファへの書き出しを利用する

今回ご紹介するのは、WebGL で実装された遅延シェーディング、すなわち Deferred Shading のデモです。

レンダリングのコア部分には three.js を活用しつつ、MRT(Multiple Render Targets)を利用することで複数のバッファへと同時に値を書き出し、複数のライトを使いながらも高速にレンダリングすることを可能にしています。

MRT や Deferred など、あまり見慣れないキーワードが多いかと思いますが、そのあたりの概要も含めて紹介します。

デモでは実際に実行されているものを見ることができるので、非常に参考になりますね。

「遅延」と呼ばれるシェーディングとは?

これをご覧のみなさんは、Deferred Shading(ディファードシェーディング)や、あるいは Deferred Rendering と呼ばれる手法を聞いたことがあるでしょうか。

そのまま直訳すれば Deferred は「遅延」となることから、日本語では遅延シェーディングや遅延レンダリングというように呼ばれるこの手法。

その訳からもわかるとおり、シェーディングを遅延させて行う様子からそのように名付けられた手法なのですが、WebGL ではこれを利用しているケースは稀です。

というのは、この手法を用いるためには、前提として MRT(Multiple Render Targets)を行う必要があり、これが WebGL では既定でサポートされていないからなんですね。

厳密には WebGL では実現できないということではないのですが、拡張機能を使う必要があることから、単に実装例が非常に少ないのがこの遅延シェーディングです。今回のデモは、パラメータ調整なども行うことができるメニューを備え、非常に様子を分析しやすいように工夫されています。

遅延シェーディングは、MRT と呼ばれる 複数のカラーバッファに同時に出力する 機能を使って実現します。

レンダリングの最初のステップでは、まず MRT で複数のバッファに、深度や頂点の座標、あるいは法線などだけを書き出します。この段階では最終的なレンダリング結果を得るための、表に見える必要のない、頂点に関する情報だけがバッファに書き込まれます。

そして次のステップでライトの当たり方や強さを計算するのですが、その際に、最初のステップで書き出した諸情報をまとめてテクスチャから参照して取り出していきます。

通常、ライトの計算を行うためには、ライトがひとつ増えるたびに、シェーダ内で複数のライトの演算を行ってやる必要があり、とても計算の負荷が高くなります。

しかし遅延シェーディングにおいては、既に頂点に関する情報は MRT によって出力されているものがあるので、それらを参照しながら処理することによって、高速に処理できるという寸法ですね。

今回のデモでは、画面の右端に備え付けられたメニューから、それぞれのバッファにどのように情報が書き出されているのかを閲覧することができるようになっています。

あるバッファには深度を、あるバッファには法線を……といったように、それぞれ異なる意味の情報がテクスチャに焼き込まれるわけですね。

そして、それらを再度参照しながら、一気にライトに関する計算を行っていく……

言葉で説明すると単純ですが、自分で実装しようとなると結構面倒ですね。

今回のデモは、それぞれのバッファに格納された情報を個別に画面に表示させることができるため、リアルタイムにどのような結果がテクスチャに焼きこまれ、最終的にどのような描画結果になっているのか、それら全てをつぶさに観察することができます。

レンダリングのコア部分は three.js で実装されていますので、ピュアな WebGL の記述に不慣れであったりしても、参考にできる部分は多いでしょう。

一緒に Github でソースコードが公開されていますので、参考にさせてもらいましょう。

技術的なデモなので派手さはあまりありませんが、ぜひチェックしてみてください。

リンク:

CIS 565 WebGL Deferred Shading

WindyDarian/Project5-WebGL-Deferred-Shading-with-glTF: Project5B-WebGL-Deferred-Shading-with-glTF

share

follow us in feedly

search

search

monthly

sponsor

social