Dynamic Shader Linkage vs Uber Shader

ビックカメラで安かった『Far Cry 2』を買って遊んだんですが、リアルにすればそれで良いとか考えてるゲーム開発者は死ねばいいんだ、とちょっと思った。

基本的にJRPGと同じでお使い、作業の連続。それでいて移動には時間がかかるし、行ったり来たりも多い。

こちらはリアルであることを強制され、とにかく敵の位置も把握しにくいジャングルの中で四苦八苦。

それに比べて敵は下生えの草に隠れててもこっちを見つけてくる。こっちからは相手が見えなくても相手にはこっちが見えるのは理不尽すぎる。

スニーキングができればまだ楽しめたかもしれませんが、敵の背後から近づいて殺しても次の瞬間には他の敵にこちらの位置がばれる仕様。MGSのように簡単に警戒態勢を解いてはくれないしね。

しかも酔いそうになった。『KILLZONE2』なんて目じゃないほどに。最後には慣れたけど。

リアルはリアルでもCoD4はうまくバランスとってたのにねぇ…。遊びやすくないゲームは駄目だと思う。

ここから本題。

GameDev.netのフォーラムでタイトルのようなスレッドを見つけました。

Dynamic Shader LinkageはDX11で追加される、シェーダプログラムをリンクさせる機能です。要はシェーダジェネレータとかでやってることをやってくれるやつ…だと思う。

このスレッドでは多分自前のシェーダジェネレータのことを言ってるのでしょう。DX11はまだ出てませんので。

Uber Shaderは究極のシェーダというような意味。何でも屋のようにすべての機能を持っているシェーダのようです。

つまり、if文、for文といったフロー制御をバンバン使って1つのシェーダプログラムで複数の機能を持たせているやつですね。

前者の利点はデザイナが自分でいろいろなシェーダを作れるようになることです。トライエースもそうやってますね。

欠点は管理が難しいところと、最適化が難しいところ。単純に動的生成していたら最適化は無理ですね。

後者の利点はシェーダプログラムの管理がしやすいところでしょうね。シェーダを増やすもの、最適化するのもプログラマです。

欠点はなんと言っても速度。フロー制御はとにかく遅い。

…ほんとに遅いのでしょうか?

まことしやかに囁かれていることですが、実際にはどの程度重いのでしょう?

Dynamic Shader Linkageの場合、シェーダをほぼ常に切り替えながら使っていく必要がありますが、Uber Shaderではレジスタの設定だけで済みます。

フロー制御が重い、と言うのと同じくらいに、シェーダやレジスタ、レンダーステートの設定は重いと言われています。

わからなかったら人に聞く!とはいうものの、こういうのは自分でパフォーマンス計測した方が速い。

そこで計測してみました。前回と同じような方法で。

前回も今回も自宅マシンでテストしています。

CPUがCore2Duo E6750、メモリが2G、GPUがGeforce8600GTSです。

描画するモデルは前回も使用した1900ポリゴン、2マテリアルのモデル。

このモデルを点光源1?4、それぞれについてディフューズのみとディフューズ+スペキュラで描画します。

その、計8回の描画を100回繰り返します。合計800体のモデルが描画されます。

描画位置はすべて同じですが、Zテストあり、Z書き込みなしで描画するので、常に描画されます。

Uber Shaderはピクセルシェーダ側でのみフロー制御を利用します。頂点シェーダはどちらも共通です。

シェーダプログラム以外はUber Shader有利に設定してあります。マテリアル情報はどちらの描画でも常に設定しますが、シェーダ自体の設定はUber Shaderが800体描画するうちに1回だけ、Dynamic Shader Linkageはマテリアル1つにつき1回設定、つまり1600回設定します。

Dynamic Shader Linkageは実際にはシェーダを自動生成していません。8つのシェーダを予め作成しています。シェーダ生成の時間やキャッシュのチェック等は行っていません。

上記のプログラムを600回繰り返し、かかった時間を計測した結果が以下です。

 かかった時間平均時間FPS
Uber Shader840981407
Dynamic Shader Linkage354535916

圧倒的にDynamic Shader Linkageの方が速いですね。2倍以上速いです。

やはりフロー制御は重い。SM3.0でないと使えないし、シェーダジェネレータで対処できるなら使うべきではないでしょうね。

おまけ

ShaderXの編集者であるWolfgang Engel氏は、我々はシェーダジェネレータは使用しない、と言ってます。

やはり最適化が難しく、品質の高い映像が作れないからだそうです。

技術的に独立できる部分はヘッダファイルのようにして保存しておき、これを各プログラマ間で共有すればいいとか。

シェーダジェネレータはインディーズタイトルや非商用のものならいいけど、パッケージソフトで使うべきではないそうで。

しかし、ロックスターは金あるからいいけど、こちとらそんなこと言ってられねぇんだ!と言いたくなったりもしますね。

とはいえ、個人でゲーム作るならシェーダジェネレータっていらないんですよね。そんなにシェーダプログラム使わないでしょうし。

多くても200はないんじゃないでしょうかね。個人で作るゲームでは。

PS

表が間違ってたので修正しました。