OpenGLで透明なオブジェクトの描画
以下個人的メモ。
混合関数について
glEnable(GL_BLEND);
で混合機能を有効にする必要がある。しかしこれだけでは何の役にも立たないので、
glBlendFunc( src, dst );
で混合元と混合先それぞれの混合関数を設定してやる必要がある。
よく使うだろう混合関数の組み合わせメモ
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
- ほとんどの場合はこれ一本でOK。アルファ値が0.5の場合、ちょうど半々の混合比率になる。
- glBlendFunc(GL_SRC_ALPHA, GL_ONE)
- ソースの色が加算される。つまりもとの色より暗くなることがないので、光線や爆発などの表現にぴったり。ちなみにOpenGLは標準で減算合成はサポートしていない。
半透明オブジェクトの描画について
普通にデプステストありで何も考えずに半透明ポリゴンを描画するとおかしなことになる。半透明ポリゴン同士が重なっている場合、奥にある半透明ポリゴンが手前の半透明ポリゴンに隠されてしまう。本当なら奥にあるポリゴンが透けて見えていないといけないのに。
OpenGLのデプステストは半透明ポリゴンのことまで考慮されていないため、奥にあるポリゴンは「見えない」ことにされてしまうため。
ならばと、
glDisable(DEPTH_TEST);
とデプステストを無効にしてしまうのはさすがにやりすぎなので、デプスバッファへの書き込みだけを禁止したい。
OpenGLにはデプスバッファを読み込み専用にするモードが存在する。
glDepthMask(GL_FALSE);
半透明ポリゴンを描き終わったら元に戻しておくこと。デプスバッファを読み込み専用にしてしまうと、当然ながらデプスバッファには半透明ポリゴンの情報は書き込まれないため、半透明ポリゴンがきちんと奥から描画されるよう自力でソートしてやる必要がある。