言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

ステンシルの問題

croquet のステンシルについて独り言。openGL にはステンシルという機能があって、これで描画領域をマスクできる。つまり、画面の中に自由な形を切り取って、そこに別の画像を表示する事が出来る。問題は、それを使って影を表示しようとした事で起こった。

影を表示するにはいくつか方法があると思うが、僕が選んだのはステンシルにまず影の元になるオブジェトを描画して、そこに半透明の灰色を重ねるという物。まあ、単に http://www.geocities.jp/yuichiy2001/gl/applied/04-simple_shadow.htm のまねをしているだけなんだけど、この方法なら、影の元がどんな複雑な形でも、また、床にどんなテキスチャが張っていても対応出来る。実際に簡単に実験してみると割と自然な影を表示する事が出来た。

問題は、この機能をポータルでも使っていること。ポータルとは、croquet におけるどこでもドアの役割を果たす物だ。ポータルを通して別の世界が見えたり、世界に入っていけたりする。ポータルの中に別のポータルが見えていたりすると、そこから再帰的に別の世界を描画する必要があるからややこしい。これを実現するために、ポータルでは depth という変数で再帰をカウントしている。

つまり、depth = 1 は今の世界で、ステンシルをポータルの形に切り抜くわけだが、その時にステンシル内を 1 で埋め尽くす。それから切り取ったステンシルの内部を描画するのだが、今度は depth = 2 の世界だ。ポータル内ポータルは2で埋めつくされる訳だが、この時に二つのステンシルを重ねた状態になるので、埋め尽くされるのは二つのステンシル穴の共通部分となる。

そんなわけで、僕が勝手に別の場所でステンシルを使ったりしてしまうと、画面がぐちゃぐちゃになってしまうのでした。ややこしい。。。これはステンシルを直接使わないで管理するためのクラスを一つ作るべきなのかな?