もんしょの巣穴blog

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

[UE4] 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の頃から使えた手法らしいのでそんなに簡単に潰されることはないとは思いますが、使用の際には十分注意してください。

[[UE4] Customノード3分ハッキング]の続きを読む
スポンサーサイト
  1. 2015/12/23(水) 12:01:42|
  2. UE4
  3. | トラックバック:0
  4. | コメント:0

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

前回前々回のAdvent Calendar用記事ではGBufferを拡張してワールド空間タンジェントを保存、異方性スペキュラを実装とやっていました。
しかし、GBuffer拡張時にも書いたように、GBufferが増えることによってGBuffer書き込み時の処理速度に影響を与えるという問題が浮上してきます。

昔のハードウェアはGPUの計算能力が低かったため、色々なものをテクスチャに保存してルックアップテーブルとして参照するということをやっていました。その方が速かったわけです。
しかし現代のハードウェアは計算能力が大変高くなったため、ルックアップテーブルを利用することで遅くなる事例も出ています。
GBufferにしても同様で、GBufferを増やして書き込み、読み出しを行うより、今あるGBufferに圧縮して書き込み、読みだしてデコードする方が高速な場合も存在します。
もちろん、実装方法や条件によっても変化はすると思いますが、GBufferを増やさなくて済むならそれに越したことはないはずです。
某ハードの場合だと特に、GBufferを増やしたらESRAMに載らなくなりました、なんてことになりかねませんからね!

というわけで、前回まではGBufferを増やして高品質な異方性スペキュラをやる方法を提示したわけですが、今回はGBufferを増やさずに対応する方法を提示していきます。
ついでにマテリアル入力を増やして、タンジェントと異方性の度合いをマテリアルエディタで計算、設定ができるようにします。

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

[[UE4] GBufferを拡張せずに異方性スペキュラをやってみる]の続きを読む
  1. 2015/12/13(日) 14:05:25|
  2. UE4
  3. | トラックバック:1
  4. | コメント:0

[UE4] 拡張した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にマージする必要が出てきます。
が、これだけ巨大なエンジンですので、マージコストは相当高くなるはずです。
そもそも自分が改造した部分に大幅な改良が行われていたりすると目も当てられません。

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

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


[[UE4] 拡張したGBufferを使って異方性スペキュラをやってみる]の続きを読む
  1. 2015/12/07(月) 06:42:36|
  2. UE4
  3. | トラックバック:1
  4. | コメント:0

[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なりコメントなりでおねがいします。


[[UE4] GBufferを拡張する]の続きを読む
  1. 2015/12/06(日) 05:13:16|
  2. UE4
  3. | トラックバック:2
  4. | コメント:0

プロフィール

monsho

Author:monsho
ゲームプログラマ?

最近の記事

最近のコメント

最近のトラックバック

月別アーカイブ

カテゴリー

ブロとも申請フォーム

この人とブロともになる

ブログ内検索

RSSフィード

リンク

このブログをリンクに追加する

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。