Irrlichtでは、OpenGL, Direct3Dともプログラマブルシェーダを使用することが出来る。このサンプルは、"10.Shaders"にある。
しかし、fxc等を使ってコンパイルしたシェーダを使えないので、実行環境にシェーダコンパイラを要求する。シェーダコンパイラはDirectX End User Runtimeに含まれているため、DirectX End User Runtimeのインストールされていない環境ではプログラマブルシェーダを使うことが出来ない。
Windows10においてはDirectX End User Runtimeが正式サポートされていないため、これは好ましくない。また、ストアアプリ全般において、実行環境でのシェーダのコンパイルは禁止されている。
本節においては、コンパイル済みシェーダを使用できるように改造する。
10.Shadersのサンプルは、mediaフォルダ内のd3d9.hlslを使用する。これを開発環境にてコンパイルしておく。コンパイルはDirectX SDK付属のfxc.exeで行なう。本節においてはDirectX SDK (June 2010)付属のものを使用した。
下記にて各シェーダをコンパイルする。
fxc d3d9.hlsl /Gec /T vs_1_1 /E vertexMain /Fo d3d9.hlsl.vs.bin
fxc d3d9.hlsl /Gec /T ps_1_1 /E pixelMain /Fo d3d9.hlsl.ps.bin
Irrlicht内部において、シェーダ定数の書き換えのために、D3DXライブラリのID3DXConstantTableを利用している。これはD3DXCompileShaderでコンパイルした場合にしか利用できないので、これと同等の情報をコンパイル済みシェーダから引き出す必要がある。
幸いにも、これについては既に実装があるため、小改造して利用させていただいた。
(ConstantTable.cpp / ConstantTable.h) 出所はここ。
元のコードのままだと、行列がRow-majorかColumn-majorかの情報が得られないので、機能追加している。
与えられたシェーダプログラムがバイナリであれば、コンパイルせずにシェーダ生成するように変更する。バイナリかどうかの判別処理が手抜きなので、問題が起きたら変更すること。
シェーダ定数テーブルについては、コンパイルする場合もしない場合も、前述ConstantTableクラスで扱うよう統一した。
ID3DXConstantTableを使用する個所を前述ConstantTableクラスを使用するように変更した。
ソースコードのダウンロード
改造箇所については、#ifdef SUPPORT_COMPILED_HLSL にてマークしてある。
case video::EDT_DIRECT3D9:
if (UseHighLevelShaders)
{
#ifdef USE_COMPILED_HLSL
psFileName = "../../media/d3d9.hlsl.ps.bin";
vsFileName = "../../media/d3d9.hlsl.vs.bin";
#else
// Cg can also handle this syntax
psFileName = "../../media/d3d9.hlsl";
vsFileName = psFileName; // both shaders are in the same file
#endif
}
以上の改造により、10.Shadersサンプルを、End User Runtimeの導入されていないPCにおいても正常動作させることが出来る。
本節の改造においては、10.Shadersのサンプルを動作させるところまでは確認しているが、それ以上の動作確認はしていないので、注意すること。