RGSS互換ライブラリを考える

DXRubyのViewportがバグっているようだ。
DirectXでいうViewportというのは、射影変換後のxyそれぞれ-1〜1になった座標(zは0〜1)のはみ出したものをクリッピングした後、スクリーン座標系にスケーリングするときに使う。
つまり、元の座標を640*480の座標系で指定すると、Viewportで指定した範囲に縮小されて描画される。
3Dの仕組みで2DのViewportを実現するには、もともとのワールド変換時にScreenとViewportの比を掛けておくか、射影変換時のクリップ範囲を変えるかしないといけないのではないかと思う。
各種行列をきちんと設定できれば可能だと思うし、擬似3Dをするときにはそれが必要な処理となるので、そのうち自然に直るだろう。
DXRubyでちゃんと描画されているように見えることがあるのは、DirectXの行列設定処理まわりで初期化されるところとされないところがあって、中途半端な状態になっているからだと思われる。


さて、そういうことで互換ライブラリのViewportをどのように作ればいいのか、という話になる。
RGSSではどのようにやってるのかよくわからないが、とりあえず描画時間が描画面積に比例するようなのでソフトで描画しているのではないかと思う。
その場合、スプライト1枚ごとにはみだしてるかの確認と、クリッピング描画をすればできる。
ソフト処理はすべてにおいて柔軟だ。
DXRubyでは3D描画を応用して2D描画することで、ハードウェアの性能を引き出そうとしているから、ソフトでやるほど柔軟ではなく、仕組みを理解してうまいこと細工する必要がある。
そのひとつがさっきの座標変換時の細工であり、もうひとつの策がViewportサーフェイスの導入だ。
Viewportをサーフェイスとして作り込むと、描画範囲外になるからクリッピングは普通にでき、ピクセルシェーダを使ったブレンド&グレースケール化が視野に入ってくる。
その場合、Viewportがビデオメモリを食うようになるから、
s = Sprite.new(Viewport.new(0,0,640,480))
とか書いちゃう人(検索したら実際にいる)は大変なことになるはずだ。
ヒトコトで言えばViewportの使い方が間違っているのだが、Viewportの概念と正しい使い方をマニュアルに書いてないのだからしょうがない。
そこまで想定して作ってあるとは思えないが、サーフェイスにしてしまうと大きな違いになるのは確かだ。