節のある木の板を作る

Substance Designerで木の板を作ろうとした場合、比較的簡単なのは[Wood Fibers]のノイズを利用して適当に作ることです。

なんとなく木目を意識した形状に先のノイズをブレンドするだけでもそれっぽく出来ます。

ただ、節のある木の板になるとそういうわけにもいかず、少し工夫してやる必要があります。

今回はそんな節の部分を作る割と基本的(と思われる)手法を紹介します。

Youtubeなどから持ってきたネタです。

まず、木の節となる丸い形状を作成します。

これは複数配置されている必要があるので、手っ取り早く[Tile Generator]を使うことにします。

sd109.jpg

楕円は[Pattern Type]を放物面にし、[Interstis X]を少し入れてあげます。今回は0.34を入れました。

他には[Number X], [Number Y]を4、[Scale Variation]を0.24、[Free Rotation Random]を34.7にしています。

重要なのは配置で、[Offset Random], [Position Random]と各種マスクをうまく利用して、重ならないように配置します。

なんとなく納得できる配置ができたら次に進みましょう。

次はもう1つ[Tile Generator]を配置し、[Pattern Type]はデフォルトのレンガのまま、数はXYともに24、回転、オフセットなどのランダムを利用して紙吹雪のように適当に散らします。

[Luminance Variation]で明るさにも変化をつけましょう。

これを[指向性ブラー]に接続、[回転]を0.25(90度回転)、[強度]を2000程度にします。

すると縦方向の線のノイズのようなものが出来ます。これが木目の基本部分となります。

sd110.jpg

さて、ここから節の部分の木目の歪みを作成します。

[指向性ブラー]の結果を[ワープ]に接続し、最初の[Tile Generator]に[Blur HQ Grayscale]を接続してから[ワープ]の[グラデーション入力]に接続します。

[ワープ]の[強度]を調整してあげるとこのように節の部分で歪んでいる木目のように変化します。

sd111.jpg

木目部分はできたので、今度は節の部分を作成します。

まず、節の[Tile Generator]に[Gradient Map]を接続します。これはマスクとして使うので、グラデーションはこんな感じ。

sd112.jpg

次に[ブレンド]ノードを配置し、フォアグラウンドに節の[Tile Generator]を、バックグラウンドに[ワープ]の結果を、不透明度に先ほどのマスクを接続します。

sd113.jpg

蓮コラみたいで気持ち悪いですが、こいつを[Gradient Map]に接続します。

グラデーションは白と黒が交互に配置するだけです。ちょっと数は多いですが。

sd114.jpg

なんとなく木目っぽさが出てきましたが、まだまだ気持ち悪い何かです。

この結果は少し粗めなので、[Blur HQ Grayscale]で少しだけ柔らかくブラーを掛けます。[強度]1.0くらいで良いでしょう。

これを[ブレンド]のバックグラウンドに接続し、フォアグラウンドには[Wood Fibers 2]を接続しましょう。

[ブレンド モード]をDivideにすると一気に木目っぽくなります。

sd115.jpg

ここまでくればあとはここから法線とラフネスを生成するだけです。

もうちょっと全体的に歪ませたい人は[ワープ]ノードと[Perlin Noise Zoom]を利用して歪みを作ると良いでしょう。

また、このままラフネスに差し込むと高い部分が粗く、溝の部分が滑らかになってしまいますので[レベル]ノードで反転しつつ調整すると良いでしょう。

サンプルでは以降はこんな感じで作りました。

sd116.jpg

[レベル]ノードの結果がラフネスになります。

ベースカラー部分は割愛。この辺はけっこう適当なので。

今回作成したものの結果はこのようになっています。

sd117.jpg

全体的に、パッと見は悪くないですが、木の節の部分が板にくっつきすぎているというか、融合しすぎているように見えるのが気になりますね。

節の部分だけ少し凹ますとか、節らしくヒビを入れておくとかの工夫がまだまだ必要ですが、短時間でさくっと作ったものとしては悪くない出来だと思います。今回もサンプルをアップしてあるので、興味のある方は御覧ください。

https://dl.dropboxusercontent.com/u/39588440/Substance/Blog_Wood.sbs

また定番の作り方を覚えたら公開していこうと思います。

様々な形状を作ってみよう

『Forza Motorsports』というゲームシリーズをご存知でしょうか?

Xboxで発売されているレースゲームで、MS傘下のTurn10スタジオが制作しています。

リアルなドライビングを楽しめるゲームではありますが、日本のユーザには痛車を作れるゲームとしての方が有名かもしれませんね。

このゲームは様々な形状のステッカーを貼り付けて自分なりのペイントを車に施すことが出来ます。

本来であればレースなどで使用されるスポンサーのロゴを貼り付けたような車を作成することを目的としていたのでしょうが、どこかの馬鹿げた人たちが丸、三角といったようなプリミティブ形状を組合わせて素晴らしい絵を作成するようになりました。

アニメキャラや宅急便会社のロゴ、某豆腐店ロゴなどなど…

基本形状を組み合わせて別の形状を作成するというのはポリゴンモデルも一緒ではありますが、なかなか根気のいる作業です。

ですが、うまく作れるようになれば様々な形状を簡単に作ることも可能なはずです。

Substance Desingerはテクスチャを読み込むことが出来るのでわざわざ複雑な形状をプリミティブの集合体で作成する必要はないのですが、この場合は元のテクスチャの解像度に依存することになります。

この依存を排除するにはやはりプロシージャルに作成する必要があるでしょう。

今回は簡単な形状を作成することで、プロシージャルな形状作成に慣れていこうと思います。

まずよく使うノードの紹介をします。

プロシージャルな形状の作成には基本形状となる物が必要となります。

それに使用されるのは以下の3つのノードでしょう。

sd095.jpg

[Shape] は様々な形状を選択できるノードで、丸や四角などをプロパティで変更できます。

[Polygon 1]と[Polygon 2]は正多角形を作成するノードですが、1は真っ白な形状を、2はグラデーションのかかった形状を作成します。

基本はこれらの形状を[Blend]ノードでブレンドしまくって作成することになります。

これらのノードをそのまま重ねあわせてもうまくいかないので、移動や回転を行いたいと考えるでしょう。

その際に使用するのが [Transform 2D]ノードです。名前のとおり、2Dのトランスフォーム(回転、スケール、平行移動)を行うノードです。

通常は回転角度などを指定することになるのですが、プログラマであれば行列で指定する方がわかりやすいかもしれません。

パラメータの [行列] をクリックすると2x2の行列を数値直接で指定できます。

sd096.jpg 

また、このノードを選択中はマウスを使ってトランスフォームを変更することが可能です。

sd097.jpg 

赤い部分をドラッグすると平行移動、黄色はスケール、緑は回転を変更できます。

ただし、シアーは行列直接指定でなければ設定できません。

sd098.jpg

他にも使うノードはあるのですが、今回はこのくらいの説明にしましょう。

さて、今回作成するのはこのような形状です。

sd099.jpg

パッと見はどういう形状かわかりにくいかもしれませんが、三角形6つで六角形を作成し、これをタイル状に敷き詰めたパターンです。

各三角形は重心位置が飛び出ていて、外に向かうほど高さが下がっていきます。

これだけを見るとこの三角形1つは[Polygon 2]ノードを使えば済むように思えますが、よく見ると飛び出ている重心位置が三角形の底辺に近いことがわかります。

そこで、この三角形を作成するために3つの三角形をブレンドして作成することにします。

sd100.jpg

この図のように3つの三角形を組み合わせます。

まずはベースとなる三角形を用意します。これは[Polygon 1]で三角形を作成しましょう。

この三角形は横向きなので、縦に向けるために[Transform 2D]ノードで回転します。

このままの状態では三角形は真っ白で、重心が盛り上がるようにはなりませんので[Gradient Linear 1]と乗算の[Blend]を行います。

[Gradient Linear 1]は一応レベルでグラデーション調整できるようにしておきます。

sd101.jpg

次にこの三角形を[Transform 2D]で変形します。シアーも使うので行列をある程度直接指定する必要があります。

sd102.jpg

適当に縦に潰したあと、行列のY1の項目に0.5を入れればこんな形状になるはずです。

この三角形は同一形状の2つの三角形のうちの1つです。つまり、これと同じ形状がもう1つ入りますが、こちらはY軸に対して対称になります。

そこで、やはり[Transform 2D]を使って[水平方向にミラー]ボタンを1回押して対称となる形状を作ります。

この2つの三角形を[Blend]ノードを使って合わせます。ブレンド方法は[最大(明)]を使いましょう。

sd103.jpg

こうなったら上図の下側の[Transform 2D]を回転、平行移動して1辺がピタリと合うように調整します。ただ、完全にぴったり一致する必要はありません。

また、元のグラデーション付き三角形を別の[Transform 2D]ノードに繋いで、底辺部分の三角形を作り、やはり[最大(明)]で[Blend]します。

結果はこのようになりました。

sd104.jpg

これで目的の形状ができたように思われますが、2Dビューで最後のブレンドを拡大してみてください。

隙間ができていたりしないでしょうか?ちょっと飛び出てたりしないでしょうか?

これらを完全に塞ぐのは正直いって無理なので、[Blur HQ Grayscale]ノードを利用して軽くブラーを掛けてみましょう。

sd105.jpg

ブラー前は隙間がありますが、ブラー後には隙間がなくなりました。

ちょっとボケすぎのようにも見えますが、引いた絵を見ればそこまでボケていないことがわかるでしょう。

ちなみに、ブラー強度は1.0を指定しています。

このような微妙な隙間は法線マップ作成時に微妙に影響を与えたりするので、できるだけブラーを掛けて潰しておきましょう。

三角形は出来上がったので、今度はこれを6つ並べて六角形を作ります。

[Splatter Circular]ノードを使うことでこれを実現できますが、多分元の三角形は正三角形ではないのでうまく六角形にならないでしょう。

そこで、今回も[Transform 2D]ノードを挟んでスケールの調整をしつつ六角形を作成します。

[Splatter Circular]の設定としては、[Number]が6、[パターン]がInput Image、[Center Orientation]がTrue、[ブレンド モード]が最大の状態にしましょう。

あとは半径等をうまく調整し、[Transform 2D]と合わせて六角形になるようにします。

ここでも微妙な隙間などができているかもしれませんので、[Blur HQ Grayscale]ノードで軽くブラーを掛けます。

sd106.jpg

最後は[Tile Generator]を使って敷き詰めます。

設定としては[Number X]と[Number Y]を同じ数値にしておきます。今回は6を設定しました。

また、[オフセット]に0.5、[Pattern Type]にImage Input、[ブレンド モード]に最大を設定します。

これによって六角形が互い違いにはなりますが、隙間ができてしまっています。

この隙間を埋めるには[Interstice]という項目をいじります。

この項目は形状同士の隙間の大きさを設定するための数値で、大きくすると隙間が開きます。

今回は隙間を閉じたいので負の値を入れてやる必要があります。

負の値が入ってくるのが気持ち悪いという方は[Scale]で形状同士が重なるくらいまで大きくしてから[Interstice]をいじるようにしましょう。

隙間が埋まったら[法線]ノードに繋いで強度を設定して完了です。

sd107.jpg

今回は比較的シンプルな形状でしたのでノード数は少ないですが、複雑な形状を作成しようとするとより多くのノードを使います。

重くもなりやすいので注意してください。

ただ、複雑な形状でもやることはあまり変わりません。

複数形状を合成する場合にはピッタリ合わせる必要はなく、ある程度合わせて軽くブラーしてやればOKです。

変な隙間ができていないかはノードの途中で法線マップを生成してみると分かりやすかったりしますのでオススメです。

おまけ

sd108.jpg 

https://dl.dropboxusercontent.com/u/39588440/Substance/Blog_Shape.sbs

昔懐かしいレンズフレア

少し前にある方々と飲んだ時のこと、VRにおけるポストプロセスはなんとかならないだろうか、という話題が出ました。

VRでは、主に速度的な問題で、全画面処理を複数回行わなければならないポストプロセスはコストが高くなります。

その上立体視なので、左右で画面の描画状態が異なり、派手なポストプロセスほど誤魔化しきれない問題を発生させます。

しかし、主に映像業界の人からすると、ポストプロセスはできるだけ使いたくなるわけです。

派手でかっこいい映像を作ろうと思えば思うほどポストプロセスは重要になります。

エフェクトやモーションももちろん重要ですが、よりかっこよく!と求めていくとポスプロに進まざるを得ません。

ポスプロの速度的なコストは、最悪恐ろしいレベルのハイスペックPCを用意すればなんとかなるかもしれません。

しかし、立体視との相性問題はかなり手強い技術的問題です。

特に飲み会で話題になっていたのはDOFとレンズフレアでした。

この2つはランタイムコストもさることながら、立体視との相性が疑問視されるポスプロです。

DOFについてはエンジニア(自分含む)は比較的肯定的でした。

DOFによって視線誘導がしやすいのではないか、というのが理由でした。

しかしこれに関しては反対意見もありますので、何ら問題がない、とは言えないでしょう。

下手をすると視線誘導が露骨すぎて酔う原因になるかもしれません。

もう一つのレンズフレアは特にUE4では難しいです。

UE4レンズフレアはやはり描画された画面情報から生成するわけですが、強い光源が左右の画面で同じように出るとは限りません。

つまり、レンズフレアを生成する光源が右目用画面のみに描画されるという状態では、右目画面にはレンズフレアが発生し、左目画面には発生しないという状態になります。

これはもちろんよろしくない状態で、しかも解決が難しい問題になってしまいます。

そこで白羽の矢が立ったのが昔ながらのスプライトを利用したレンズフレアです。

太陽や点光源くらいにしか使えませんが、演出として使うには必要十分でもあります。

さて、ここで問題。

立体視で昔ながらのスプライト式レンズフレアはどのように見えるのが正しいのか?

レンズフレアはレンズ内部での光の再反射によって発生するのでレンズ面(スクリーン面とほぼ同じ?)に張り付いて見えるのが正しい?

しかし、人間の目は左右で場所が違っているので、光の再反射の仕方も変わるはず。左では見えるけど右は見えない、もしくはその逆だっておかしくないのでは?

これらは本来の正しさよりも、人間が自然に見えるのは何か?という感覚的な問題になってくるような気がします。

これはある作品で実装したことがあるのですが、リファレンスとした作品は2作品あります。

1つはPC版バイオハザード5です。

あまり知られていないかもしれませんが、PC版バイオハザード5立体視に対応していました。

そしてレンズフレアはスクリーン面に張り付いている形、つまり視差なしの状態ですべてのフレアが描画されていたのです。

これを見て思ったのは…開発者の方には大変申し訳無いのですが、これはひどいw でした。

バイオハザード5立体視はスクリーン面をガラス窓として、その奥でゲームシーンが進行するジオラマのような立体視の使い方でした。

もしかしたらシーンによっては飛び出しも利用していたかもしれませんが、自分が確認した短い時間では確認できませんでした。

つまり、ガラス窓を通して動くジオラマを見ていたら、そのガラス窓にぺたりとレンズフレアっぽい光の輪がいくつも張り付いていたわけです。

残念ながら見たことがある人でなければこの感覚は正確にわからないと思いますが、ある程度想像できるのではないでしょうか?

もう1つの作品は、これは見たことがある人も多いと思われますが、映画トランスフォーマー/ダークサイド・ムーンです。

この作品は当時増えてきていた立体視作品の中でも特に出来が良かったと思います。

レンズフレアやグレアなどの表現もそれまでの作品と比べて非常に多く使われていて、前述の作品を作成している最中に大変参考になった作品です。

実際にレンズフレアが使われているのは予告編でも見られます。

https://www.youtube.com/watch?v=rRIf17ntga0

もちろん、立体視で見なければどうなっているのかわかりませんが。

この作品を立体視で見たのは劇場でのみ1回だけですが、その時にこの手のポスプロは極力チェックするようにしてました。

…まあ、途中から映画が面白くてそちらにばかり集中してしまいましたがw

運が良かったのはレンズフレアがかなり早いうちに出てきてくれたことです。

少なくとも自分が見た限り、レンズフレアには奥行きがありました。

光源からどんどんこちらに向かってきていると感じられたわけです。

自分はそう感じた、というだけで現実にはそうではなかったかもしれませんが、少なくともバイオハザード5のようなものではありませんでした。

申し訳ありませんが、以前関わった作品でどう実装したかについてここでは書けません。

とりあえず言えることは、今回の実装方法とは別、ということだけですね。

着想自体はトランスフォーマーで間違いないです、はい。

今回UE4での実装では、通常は2Dスクリーン上に貼り付けるフレアスプライトを今回は3D空間上に、奥から手前に配置されるようにしてみました。

処理的にも軽いので、VRでも使用できるかもしれません。

残念ながらVRHMDを持っていないので確認できていませんが、どなたか確認していただけると助かります。

とまあ前置きが長くなりましたが、続きからで実装を提示します。

続きを読む

Customノード3分ハッキング

UE4 Advent Calendar その2、12日目の割り込み記事です。

代わりに書くボタンが出来ていたので、予定のものとは全く異なる記事ですが割り込ませていただきました。

元担当者の方、問題があるようならコメンとなりTwitterなりで呼びかけていただけると助かります。

10月のUnreal Fest後の飲み会にて、ギルティギアなどでお馴染みのアークシステムワークス家弓さんからマテリアルエディタの [Custom] ノードについて面白い話を教えてもらいました。

試してみたところ実際にうまくいき、そのことをTwitterで呟いたら家弓さんが簡単にまとめてくださいました。

プログラマであればこの情報だけで色々とできるようになるかと思いますが、[Custom] ノードはこの方法を使ったちょっと特殊な手法なんかもありますので、ここでまとめておこうと思います。

なお、最新のUE4.11 Preview1にて動作を確認しています。

今後のアップデートで使用できなくなったり、使用できるけどやり方変えないとダメという場合もあるかもしれませんのでご注意ください。

元々、Epic Games的には、[Custom] ノードはノードベースで作成するには面倒だけどコードで書いたらすごく簡単、といったものを簡単に実装できるように用意したものではないかと思います。

わかりやすい例を挙げるならベクトルの要素のスウィズルですね。

スウィズルは主にシェーダで用いられますが、要素の入れ替え処理です。

使い道はともかくとして、例えばfloat3のカラーの値があったとして、これのrgb値をgbrの順番に入れ替えたい、という場合です。

これをマテリアルノードで表現するとこうなります。

ue392.jpg

[Texture Sample] ノードの場合は [Component Mask] を使う必要は本来ないのですが、定数でも同じように処理できるようにするために使用しています。

この程度のノードの組み方は別に難しくはありませんが、同じような処理が散見されるようになってしまうと可読性が悪くなってしまいます。

この組み方がマテリアルエディタのいたるところで使用されている、という状況を想像するだけで処理を追いたくなくなるんじゃないでしょうか?

では、これを [Custom] ノードで表現すると、このようになります。

ue393.jpg

結果は同じですが、マテリアルノードは[Custom]1つだけです。

処理もたったの1行で、極めて簡単です。

ベクトル要素のスウィズル機能は現在のプログラマブルシェーダを組み込んでいるハードであればこのように簡単に実装できるのですが、ノードで表現するとどうしても冗長になってしまいますね。

このように冗長なノードを簡単にまとめられるという利点が [Custom] ノードには存在しますが、いくつか弱点が存在しています。

プログラムコードを書かなければならないためシェーダプログラムに対する知識が必要だという点が1つ、プラットフォームごとにコンパイルが通るコードを書かなければいけないという点が1つ、そしてなにより、マテリアル関数として作成されている関数を呼び出すことが出来ないという点です。

1つ目の問題は、まあ [Custom] ノード使う人はシェーダコードの書けるプログラマかTAくらいでしょうからそれほど問題にならないでしょう。

2つ目の問題も当たり障りのない処理を書く分には処理系に依存することはほぼありません。四則演算やlerp, powといった、どのプラットフォームにも存在する命令だけを使っておけば問題になりません。

3つ目の問題は現状では対応できません。が、やはり使いたいと思うことはあるのではないかと思います。

実は今回の [Custom] ノードの家弓メソッド(適当に命名w)を使うと、この問題にも限定的ではありますが対応できるのです。

というわけで、続きからで家弓メソッドの詳細と、様々な使い方について書いていこうと思います。

ただ、先に注意しておくと、この手法はハック的な手法であるため、いつか使用できなくなる可能性もあります。

家弓さんの話ではUE3の頃から使えた手法らしいのでそんなに簡単に潰されることはないとは思いますが、使用の際には十分注意してください。

続きを読む

GBufferを拡張せずに異方性スペキュラをやってみる

前回前々回のAdvent Calendar用記事ではGBufferを拡張してワールド空間タンジェントを保存、異方性スペキュラを実装とやっていました。

しかし、GBuffer拡張時にも書いたように、GBufferが増えることによってGBuffer書き込み時の処理速度に影響を与えるという問題が浮上してきます。

昔のハードウェアはGPUの計算能力が低かったため、色々なものをテクスチャに保存してルックアップテーブルとして参照するということをやっていました。その方が速かったわけです。

しかし現代のハードウェアは計算能力が大変高くなったため、ルックアップテーブルを利用することで遅くなる事例も出ています。

GBufferにしても同様で、GBufferを増やして書き込み、読み出しを行うより、今あるGBufferに圧縮して書き込み、読みだしてデコードする方が高速な場合も存在します。

もちろん、実装方法や条件によっても変化はすると思いますが、GBufferを増やさなくて済むならそれに越したことはないはずです。

某ハードの場合だと特に、GBufferを増やしたらESRAMに載らなくなりました、なんてことになりかねませんからね!

というわけで、前回まではGBufferを増やして高品質な異方性スペキュラをやる方法を提示したわけですが、今回はGBufferを増やさずに対応する方法を提示していきます。

ついでにマテリアル入力を増やして、タンジェントと異方性の度合いをマテリアルエディタで計算、設定ができるようにします。

今回もまたソースコード量が多目です。

一部のコードは前回と被りますので、そちらも参照していただければと思います。

続きを読む

拡張したGBufferを使って異方性スペキュラをやってみる

UE4 Advent Calendar 2015 その2の7日目の記事です。

前回、UE4 Advent Calendarの記事としてGBufferの拡張を行いました

しかし、GBufferを拡張しただけでは何も起こりません。ただGPUが重くなるだけです。

そもそもGBufferを拡張したのだから、何かに使わないともったいない。

ということで、拡張したGBufferにはワールド空間タンジェントを格納していますので、これを使って異方性スペキュラをやってみます。

まず、異方性スペキュラ(異方性反射)とは何か?

異方性反射で画像検索するとたくさん出てきますが、よくあるのはディスク状の金属板に扇型の光の反射が出ているものではないでしょうか。

もしくは球に髪の毛に出るような天使の輪が入っている映像ですね。

これらは傷ついた金属やヘアライン加工された金属、CD/DVDの盤面、人間の髪の毛などに出てくる特殊なスペキュラです。

細いものが束になっているようなものの場合、その形状の関係から反射光が接線方向(傷の方向に対して垂直方向)に光が伸びたりします。

これをUE4で実装する方法は2種類あります。

1つはContent Exampleにあるように、法線方向を加工することで擬似的にそれっぽい反射をさせる方法です。

擬似ではありますが、UE4のエンジンを改造せずに実装できるので、どうしてもという人はこちらを参考にした方がいいのではないかと思います。

ただ、ちょっと特殊なので特定の異方性スペキュラを実現するのは難しいかもしれません。

もう1つはマテリアル内でライティング計算を行い、Emissiveの出力として異方性スペキュラを実現する方法です。

多光源に対応できないという問題はありますが、各種計算式やテクスチャの使用などをかなり自由に行うことが可能です。

そもそも多光源が不要なトゥーン系のゲームを作る場合はUE4のディファードシェーディングを無理に使うよりマテリアル内で計算してしまった方が有利かもしれません。

ただしシャドウマップが使用できないなどの問題もありますので何でもかんでもうまくいくというわけではないです。

なお、後者の実装については『Unreal Engine 4 マテリアルデザイン入門』の付録にWardの異方性スペキュラでの実装を書いておきました。

気になる人は買ってね!

…よし、自然に宣伝できたぞ

今回やるのはこの2つの実装のどれでもなく、エンジンを改造してしまえば好き勝手出来るよね!という実装です。

実装しておきながらなんですが、はっきり言ってオススメできません。

オススメできない理由としては、やはりエンジン改造のリスクです。

UE4ソースコードを公開してエンジンの改造もOKというスタンスを採っていますが、もちろんEpic Gamesでも日々エンジンの修正は行われています。

エンジンを改造したあと、正式版のUE4で入った新しい機能を使いたいとなったらどうすればいいでしょう?

それだけを持ってくる、というのはそれほど簡単ではないので、改造した分を新しいUE4にマージする必要が出てきます。

が、これだけ巨大なエンジンですので、マージコストは相当高くなるはずです。

そもそも自分が改造した部分に大幅な改良が行われていたりすると目も当てられません。

とは言っても、どうしてもやらなければならない場合というのが特にコンシューマゲーム開発では出てくることもあります。

そういう状況があった場合は…がんばって!

というわけで(どういうわけだ?)、続きからで異方性スペキュラの実装をやっていきます。

続きを読む

GBufferを拡張する

UE4 Advent Calendar 2015、6日目の記事です。

今回は誰得な感じはありますが、エンジンコードを改変してGBufferを拡張してしまえ!という記事です。

正直、個人製作でこれをやることはほとんどないかと思いますが、なんかすげぇ映像表現を思いついたのにGBufferに情報がなくて断念せざるを得ない…というかなり奇特な方には有用かもしれません。

…まあ、そういう人は勝手に調べて勝手に改造してしまうんでしょうけどね。

まず、GBufferについて簡単に解説を行います。

まだDirectXが8くらいの頃はマルチレンダーターゲット(MRT)と呼ばれる機能が存在していませんでした。

この頃は1回のドローコールで描画できるバッファはカラーバッファと深度バッファの2つだけで、深度バッファについては深度とステンシル値以外は描画することが出来ませんでした。

そのため、カラーバッファに描画する情報はマテリアルにライティングを行った結果を描画していました。

これがフォワードレンダリングです。

さて、DirectXが9.0cとなり、ShaderModelが3.0となると深度バッファを除いて最大4枚までのバッファに一度に情報を描画できるMRTが実装されました。

MRTの描画条件はビューポートが同一であり、バッファのサイズが同一であり、描画するポリゴンの位置が同一である必要がありました。

これだけ聞くと、ライティングしたマテリアルを描画する以外に何を描画するんだ?と思われるかもしれませんが、そこで登場したのがディファードレンダリングというレンダリング手法でした。

ディファードレンダリング自体の考え方は結構昔からあったらしいのですが(20世紀には論文が出ていた、という話を聞いたことがあります)、ハードウェアの制約上実現が難しかったわけです。

しかしMRTの実現によって現実的な手法となったわけです。

その具体的な手法はいろいろな場所で語られていますが、要はライティングに必要な情報をバッファに書き込んでおき、ライティング計算を遅延(ディファード)させるという手法です。

この場合、バッファに書き込む情報はテクスチャカラーだけではなく、メッシュの法線情報であったりその他のカラーとは関係ない情報だったりします。

そのため、これらのバッファはカラーバッファとは呼びにくく、カラーも書き込むけどカラーじゃないものも書き込むグラフィクス用の汎用的なバッファ、という意味でGBufferと名付けられました。

GBufferのGはGraphicsのGらしいです。Generalかと思ってたんですが、違うらしい…

今回やるGBufferの拡張とは、GBufferを増やして新しい情報を格納し、それをライティングで使用するというものです。

GBufferを増やすことのメリットはとにかく情報を格納できる点です。

マテリアルやモデル形状に関する情報を多く格納できるのであれば、ライティング時やポストプロセスなんかで使用することが出来るようになります。

デメリットはバッファを確保するメモリが増えることと、描画するバッファが多くなればパフォーマンスに影響を与えるという点です。

特にパフォーマンスに与える影響は大きくなるかと思いますので、VRアプリを作る際には気をつけるべきでしょう。

というわけでGBufferの解説は簡単ですが終了です。

続きからではGBufferの拡張方法について書いていきますが、ほとんどコードの提示になります。

また、単純に拡張するだけでもつまらないので、拡張したGBufferに接線情報を保存し、異方性スペキュラをやってみます。

こちらは次回のエントリーとなります。

解説も最小限になると思うのですが、どうしても詳しく解説してほしい部分がありましたらTwitterなりコメントなりでおねがいします。

続きを読む