床面反射 / magicien 

image 馬鹿は風邪をひかないと言いますが、エイプリルフールで患った病がこじれた挙げ句、こんな感じになりました。

このページを参考にして実装。
床面反射は今のところ、y=0平面で反射した結果(y軸のスケールを-1にした結果)を描画しているだけ。
ただ、それだと床面の枠からはみ出してしまうので、stencilを使って床があるところだけ描画するようにする。

WebGLでステンシルバッファを使う場合は、getContextをするときにオプションを指定する必要がある。
var canvas = $('canvas');
var context = canvas.getContext('webkit-3d', {stencil: true});
あとはOpenGLと同様。

以下、今回使った描画の流れの個人的メモ。
1.Color、Depth、Stencilの各バッファをクリア
2.Color有効、Depth有効、Stencil有効(Always 1に上書き)にして床面を描画
3.Color有効、Depth有効、Stencil有効(Always 0に上書き)にして床面以外を描画
4.Color無効、Depth有効(rangeを1〜1に指定)、Stencil有効(1の箇所のみ描画、値は変更せず)にして床面を描画
5.scale(1, -1, 1)でY=0平面で反射、カリング指定をしている場合はFrontとBackを入れ替え
6.Color有効(blendFunc(ONE、ZERO) →元のAlpha値を気にせず上書き)、Depth有効、Stencil有効(1の箇所のみ描画、値は変更せず)にして床面以外をRGBAそれぞれの値を70%にして描画
7.scale、カリング指定を元に戻す
8.Color有効(blendFunc(ONE_MINUS_DST_ALPHA, DST_ALPHA)→元のAlpha値が100%なら描画しない、70%ならAlpha30%で描画)、Depth有効、Stencil有効(1の箇所のみ描画、値は変更せず)にして床面を描画

問題点
・ClipPlaneが使えないので、床面の裏側のオブジェクトが描画されてしまう。自力で実装するか...
・6&8のStencilの指定方法は改善できそう。
・6のAlpha値の指定が悪いらしく、Alpha値を持つテクスチャがうまく描画されない
・そもそもAlpha値が1.0じゃない部分はzソートした上で最後に描画しないといけない


2012/05/10(Thu) 02:11:55