床井研究室

テクスチャの回転

前回は2004年末にタイヤを回して以来恒例?となっていた「テクスチャの回転」を止めてしまいましたけど、実はキューブマッピングは、スフィアマッピングよりもずっとテクスチャを回すのが得意(謎)だったりします。スフィアマッピングでは視線を軸にテクスチャを回すのが関の山だったんですけど、キューブマッピングではテクスチャをトラックボールのようにぐるぐる回しても平気なんですね。

テクスチャ座標の補間

スフィアマッピングでは、テクスチャ座標の補間を (s, t) の2次元で行っていました。したがって法線ベクトルや反射光ベクトルを求めるには、この2軸の補間結果から残りの1軸の値を求める必要がありました。しかしこの方法では、この残りの1軸の符号を決めることができません。スフィアマッピングにおいてテクスチャ座標がテクスチャの周辺部で狂うという現象は、これが原因になっています(多分…)。

これに対してキューブマッピングでは、テクスチャ座標を (s, t, r) の3軸について補間します。つまり、ごく普通に反射ベクトルや法線ベクトルの補間を行っています。そして得られた法線ベクトルが6枚のテクスチャのうちどれに向かっているのかを調べ、そのテクスチャをサンプリングします。

したがって、このテクスチャ座標に回転の変換を施せば、テクスチャを任意の方向に回転することができます。それでは試しにやってみましょう。今回は前回作ったキューブマッピングのプログラムを雛形にします。

テクスチャ座標の回転再開

まず、前回止めてしまったテクスチャ座標の回転を再開します(前回#if 0#endif ではさんだ部分は削除しています)。ただし、今回は視線の軸を中心に回転するのではなく、図形をぐるぐる回すのに使っているトラックボール式の回転を使うことにします。とりあえず、図形の回転をやめます。

/****************************
** GLUT のコールバック関数 **
****************************/

static void display()
{
  /* モデルビュー変換行列の設定 */
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  /* 光源の位置を設定 */
  glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

  /* 視点の移動(物体の方を奥に移動)*/
  glTranslated(0.0, 0.0, -3.0);
  //gluLookAt(1.5, 2.0, 2.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

  /* トラックボール処理で図形を回転 */
  //glMultMatrixd(trackballRotation());

そんでもって、テクスチャ座標の方を回転するようにします。

  /* テクスチャ行列の設定 */
  glMatrixMode(GL_TEXTURE);
  glLoadIdentity();

  /* トラックボール処理でテクスチャを回転 */
  glMultMatrixd(trackballRotation());

これだけです。これは前回、最後にやってみろと書いてあるんですけど、再掲します。

キューブマッピングでテクスチャを回転