仮眠プログラマーのつぶやき

自分がプログラムやっていて、思いついたことをつぶやいていきます。 2025年からzennに移行

自作ゲームやツール、ソースなどを公開しております。
①ポンコツ自動車シュライシュラー
DOWNLOAD
②流体力学ソース付き
汚いほうDOWNLOAD
綺麗なほうDOWNLOAD
③ミニスタヲズ
DOWNLOAD
④地下鉄でGO
DOWNLOAD
⑤ババドン
DOWNLOAD
⑥圧縮拳(ツール)
DOWNLOAD
⑦複写拳
DOWNLOAD
⑧布シミュレーション
DOWNLOAD
⑨minecraft巨大電卓地形データ
DOWNLOAD
⑩フリュードランダー
デジゲー博頒布α版
DOWNLOAD
⑪パズドラルート解析GPGPU版
DOWNLOAD
⑫ゲーム「流体de月面着陸」
DOWNLOAD

2013年01月

HSPSHAD途中経過。今回はマルチレンダリングターゲット

HSPSHADを今年に入って作り続けてもうver1.5になった。
このプラグインは命令数こそ少ないが(現在16種類)できること、機能はとても多く、その根源は全てエフェクトファイル=HLSLの力を借りていることによる。逆にHLSLがよく分からずエフェクトファイルが上手く書けなければ、このプラグインを使っている意味はほとんど無いのだ。

残念ながらHLSLのサンプルはなんだか多いような少ないようなよくわからない感じだし、仮にネット上に落ちているとしても大半は3Dゲームのソースとして公開されている。

なのでこのブログではこれから、数値計算用途の視点からHLSLのソースを解説していければいいかなと思っている。



さて話は本題にいくが
HSPSHADで、今まで、一つのシェーダで一つのレンダリングターゲットにしかレンダリングできなかったのが、4つまでレンダリングターゲットを指定できるようになった。

例えば、Aというテクスチャが32bit 浮動小数点の数値を格納しているテクスチャだとする。
これの仮数分と指数部を分けてBとCのテクスチャで取得したい場合、今まででは仮数分だけを取得するシェーダと、指数部だけを取得するシェーダの両方を作成し、別々にシェーダ実行しないといけなかったのが、これにより一つのシェーダーに統合できるというわけだ。

しかし、グラフィックボードが古いものだと物によってはできないこともあるらしい。
私の環境Geforce GTX550tiで、マルチレンダリングターゲット最大数は4であった。
HSPSHADにはこの最大数を取得する命令も追加し、さらに使いやすくなった(と思う)。


ということでHSPSHAD ver 1.5とマルチレンダリングターゲットのサンプルを公開
DOWNLOAD
無題

画面に出しているのはマルチレンダリングターゲットとはあまり関係なく、HLSL内でテクスチャ座標がどのように指定できるかを表している。
テクスチャ座標は3Dプログラミングっぽく言えばUV座標のこと。
ピクセル指定は(x,y)という整数座標ではなく、float型の0.0~1.0までで表される小数で行う。

サンプルの例(4×4ピクセル)では、左上は(0.000,0.000)、右下は(0.750,0.750)として座標指定しているのが分かるように、HSPスクリーン上で数値を表示させたものだ。




今回参考にさせていただいたサイト
http://marupeke296.com/DXG_No50_MultiPassRendering.html

「HSPSHAD」mrefでウィンドウのrgb分解実験

サンプルはこちら

HSP標準命令のmref でウィンドウの画面データを取得することがでる。それをpeek や pokeなどでいじるのが定番だが、今回はHSPSHADを使えばシェーダに送り込ませることができますよ、という記事。

D3DFMT_L8フォーマットはint 8bitの明度情報を1ドットとするレンダリングバッファである。
これはHSP画面データのRGB(8bit+8bit+8bit)を1ドットとするものの3分の1の容量。

なのでD3DFMT_L8で640×480の3倍の大きさのバッファ1920×480を作って、そこにmrefで取得したデータを転送。シェーダで扱えるような形式にする。
今度はD3DFMT_L8の640×480の大きさを3つ作り、それぞれをR要素、G要素、B要素を格納するバッファとする。

そして私の作ったピクセルシェーダーでRGB要素に分解する。

-------------------------------------------------------------------------------------------------------
PS_OUTPUT  PStyusyutu(VS_OUTPUT In) : COLOR
{
 PS_OUTPUT Out;
float ss1;
ss1=tex2D(gputex00,In.Tex0+float2(0.5/(WIDTH*3.0)+dot0,0.5/HEIGHT));
Out.Color=ss1;
return Out;
}
-------------------------------------------------------------------------------------------------------

dot0やWIDTH、HEIGHTはHSP側から変更できる任意の変数


これでR要素、G要素、B要素に分解したバッファができた。
サンプルでは、ここでR要素のバッファを以下のピクセルシェーダーに流す。
これはクリックした点を中心として円状に減算する処理だ。中心点からの距離で減算値が変わる。

---------------------------------------------------------------------------------------------------------

PS_OUTPUT  PScircle(VS_OUTPUT In) : COLOR
{
 PS_OUTPUT Out;
float4 ss1;
float xxx,yyy;
ss1=tex2D(gputex00,In.Tex0+float2(0.5/WIDTH,0.5/HEIGHT));
xxx=In.Tex0.x-mousexf;
yyy=(In.Tex0.y-mouseyf)/WIDTH*HEIGHT;
if (xxx*xxx+yyy*yyy<0.04){
ss1-=3.0*(xxx*xxx+yyy*yyy+0.04);
}
Out.Color=ss1;
return Out;
}
-------------------------------------------------------------------------------------------------------------------- 


同じようにGB要素も様々なピクセルシェーダに流す。


mref実験



一番気になるFPSだが、私の環境のcore i7 3820 + GTX550ti では約8~10であった。
あまり喜ばしい数値ではないが、HSPの画面データをGPUに転送して分解して、さらに3つのシェーダ使って、統合して、GPUからHSPに戻す、というあまりに重い処理をしているだけに仕方がないのだろう。


もちろんbuffer命令で作成した任意の大きさのバッファでも、mrefで取得して同じことができるはずなので小さいバッファならリアルタイムでいけるかもしれない。
さらに当然、高速化できる部分は多く残されているのでもっとFPSは上がる可能性は十分にある。


数値計算用に作ってきたプラグインであったが、mrefと組み合わせることで思わぬ副産物を生み出すことができた。
これからシェーダーがHSPで格段に扱いやすくなるだろう!


※PC環境によってはD3DFMT_L8に対応してなくて、クリックしてもうまく↑の画像のようにならないかもしれません

HSP用GPGPUプラグイン「HSPSHAD」途中経過

とりあえず途中経過

http://sourceforge.jp/downloads/users/1/1813/hspshadver12.rar/

サンプルソースを見てもあまりわからないかもしれないが、やっていることは1024*1024の大きさのD3DFMT_R32F(float要素がひとつ)のバッファを作りそれをGPU上の変数に見立てて計算している。

HSP側で1024*1024要素の整数型変数を作り、0-10までのランダムな値を代入。それをCPUでFLOAT型に変換してGPUバッファに転送。
これで1024*1024このランダムな値が格納されたGPUバッファができた。
それをもう一つ作る。
シェーダーで2つの値を足して2でわって1.5かけた値を出力させる。

出力結果の入ったGPUバッファをHSP側の整数型変数にデータ転送させて、さいごに一部を表示している。

まだ未完成な命令も多いが、HLSLを使えればすでにGPGPUができる状況にはなっている。

只今ver1.2だ。
上のリンクからダウンロードできる。
プロフィール

toropippi

記事検索
アクセスカウンター

    QRコード
    QRコード
    • ライブドアブログ