FMX3Dで任意のシェーダを使う
シェーダってなに?
FireMonkeyでのシェーダ
FireMonkeyでは基本的にTCustomMaterial(の派生クラス)とシェーダが1:1で対応します。そしてTCustomMaterialはTMaterialSource(の派生クラス)が保持します。つまり、3DオブジェクトにTMaterialSourceを割り当てることは、3Dオブジェクトにシェーダを割り当てることと同義です。
上記のような関係により、FireMonkeyで任意のシェーダを使う場合は、TCustomMaterialとTMaterialSourceを実装すればいいことになります。
サンプル
説明より実際のコードを見た方が早いと思うので、最低限の実装を用意してみました(今回はWindows向けなのでDX9とDX10用)。XE4での実装なのでそれ以外の環境では修正が必要かもしれません。
ダウンロード
使い方
インストールして普通のMaterialSourceと同じように割り当てるか、動的に割り当てる場合は以下のようなコードを書きます。
var mat: TCheapMaterialSource; begin mat := TCheapMaterialSource.Create(Self); Sphere1.MaterialSource := mat; end;
シェーダを動的に読み込むようになっているので、同梱のシェーダはexeと同じ階層に置くか、あるいはCheapMaterial.pas内のファイル名指定部分を修正して下さい。
注意点
TContextShaderSource.Createの最後の引数であるSizeは、TContextShaderArchによって扱いが異なります。DX9の場合、ここはfloat*4を1つと数えた場合のデータの数で、DX10は単純にバイト数になります。なので例えば4x4行列を渡す場合、DX9は4、DX10は64を指定することになります。DX11やGLSLは未調査ですが、TContext3Dの各実装を見ればたぶん分かると思います。
シェーダはDirectX SDKやWindows SDK(こっちに入ってる方が最新)に含まれるfxc.exeでコンパイルできます。compile_shaders.batを実行するとDX9とDX10用の頂点シェーダとピクセルシェーダがコンパイルされるようになっていますが、各環境に合わせて一行目のパスを書き換えて使ってください。
その他
かなりざっくりと書いたので、不明点等あれば @lynatan までお願いします。