ブレンド

2010年1月6日

ファイル

23-blend.tar.gz

見所

半透明の赤がちゃんと緑に隠されているところ、半透明の青と半透明の黄色がちゃんと混合されているところを確認しましょう。下手な書き方をすると、常に赤が手前に来たり、青が黄色とブレンドされなかったりします。

内容

色のブレンド、半透明処理を試してみましょう。ブレンドでは、デプスバッファをそのまま使うことができません。ブレンドは、先に描かれたものの上に別のものを描いて色を混合する、という処理を行いますが、たとえば先に手前の半透明物体を描き、それと重なった奥の不透明物体を描くと、デプステストによって不透明物体は半透明物体を上書きしませんし混合もしません。デプステストをしないようにすると、今度は奥にあるはずの不透明物体が手前の半透明物体の上に描かれますので、これもおかしいです。不透明物体を先に描き、その後に半透明物体を描くようにすればどうかというと、不透明物体と半透明物体の混合の問題は解決しますが、今度は半透明物体同士の重なりで混合が起こりません。

ではどうするのかというと、半透明物体を描くときはデプスバッファに書き込みを行わないように指定します。描画の流れは以下のようになります。

  1. 不透明物体を描く
  2. ブレンドを有効、デプスバッファの書き込みを禁止にする
  3. 半透明物体を描く
  4. ブレンドを無効、デプスバッファの書き込みを可能にする

対応するコードは以下の通りです。

	glPushMatrix();
	glTranslatef(-0.25, 0., 0.5);
	glColor3f(0., 1., 0.);
	drawPolygon();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(0.5, 0., -1.);
	glColor3f(0., 1., 1.);
	drawPolygon();
	glPopMatrix();

	glEnable(GL_BLEND);
	glDepthMask(GL_FALSE);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glPushMatrix();
	glTranslatef(-0.5, 0., 1.);
	glColor4f(1., 0., 0., 0.5);
	drawPolygon();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(0., 0., 0.);
	glColor4f(0., 0., 1., 0.5);
	drawPolygon();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(0.25, 0., -0.5);
	glColor4f(1., 1., 0., 0.5);
	drawPolygon();
	glPopMatrix();

	glDepthMask(GL_TRUE);
	glDisable(GL_BLEND);

最初は不透明物体の描画です。次に、glEnable(GL_BLEND) でブレンドを有効にし、glDepthMask(GL_FALSE) でデプスバッファへの書き込みを無効にしています。glBlendFunc() ではブレンドの方法を指定しています。半透明の指定は、glColor4f() の第 4 引数で 1 より小さい値を渡すことで行っています。最後に、glDepthMask(GL_TRUE) でデプスバッファへの書き込みを有効にし、glDisable(GL_BLEND) でブレンドを無効にしています。

OpenGL プログラミング 目次へ