kumaryu日記
2009-04-08 あつい
_ [Riko] 描画パスを直した
しばらく手を入れられてなかったRikoですが、描画パスを少しまともにした。
放置してたわけではなく、描画パスをどうすればいいのかずっと悩んでただけなんだけど。
基本的にはシーングラフを作って、それを辿って描画。OK簡単だ。
ただそれだとマルチパスなエフェクトがあった時に困る。あと適度にZソートしたいとか。Zソートはシーングラフのノード単位でもいいと思うので、辿るときにやってしまってもいいんだが。
問題はマルチパス。大抵エフェクトはシーングラフのノードにくっついてるわけだ。で、パスはエフェクトにくっついてるわけだ。
ひとつのノード(モデル)内で完結するマルチパスエフェクトならノード単位で複数パス描画しちゃってもいいんだけど、シャドウマップとかみたいに他のノードも関係すると無理だよね。
あと出来ればエフェクトをまとめて一回のシェーダ設定で複数のモデルを描画したいと思ってた。
そんなこともあって、Zソートの前にパス単位およびエフェクト単位でソートもしようとしていた。
そのためにシーングラフ辿って描画コマンドリストを作り、さらに描画コマンドリストをソートなりなんなりして辿って描画。
ここまではいままでできてたんだけど、かなり無理がある構成で改善したかったんだよねぇ。
無理があったのは、やはりマルチパス。ソートしようとすると前もってパス間の順序を指定しておかないといけなかった。これめんどい。
あとはエフェクト単位のまとめこみも無理だ。エフェクト単位でまとめたいけどZソートは考慮したいとか。まとめ込む関係上必ずエフェクトがないと描画できないとかめんどい。
で、ここ数週間悩んだんだが、大して変わらずに整理出来た。
そもそもパスをソートってのが無理があった。カメラの設定みたいな全パスでやる必要があるものもあるし。
そこで、描画コマンドリストを作るときに、このコマンドはこのパスで実行できるよーというのを記録しておく。パスに関係なく実行してほしいコマンドは全パスを指定しておく。で、パス数分だけコマンドリストを辿る。
これだと無駄に実行されるコマンドもあるかもしれないが、まああんまり気にしないことにする。ステート設定コマンドなんかは実際に描画するコマンドまで実行を遅延させて、無駄なステート設定を省くこともやる気になればできるしね。
エフェクトのまとめこみはとりあえず無かったことにする。コマンドリストでそれをやるよりは、やっぱり遅延実行で無駄なシェーダを設定しないとかの方がまともな気がした。
というかそこまで気にする必要があるかどうか怪しい。Rubyレベルでの遅さの方がやばいんじゃね。
こうしていろいろ割り切ったおかげで使い易くなった感じ。むしろ今まで使いづらかったから、割り切って使い易くしたんだが。
シーングラフで直接描画でなく描画コマンドリストをにコマンド追加ってのはちょっとわかりづらいが、まあこんなものだと思えばこんなものだろう。
とりあえず最低限動く状態まで持っていけたのでコミット。
これでマルチパスエフェクトもちょっと作り易くなったはずなので、デスクトップマスコットに、ポストエフェクト版の輪郭線稜線描画でもかいてみようかな。
あー、行列をcolumn-majorにするのもやらなきゃなぁ。