torutkのブログ

ソフトウェア・エンジニアのブログ

JavaFX 3DのテクスチャマッピングとAffine変換

(7/17 勘違いがあり、文章を大分修正しています)

JavaFX 3Dの座標系は、画面の横方向がX軸、画面の縦方向がY軸、画面の奥行き方向がZ軸となっており、X軸の正は右方向、Y軸の正は下方向、Z軸の正は画面の奥方向となっています。

最初左手系の座標系と思っていましたが、これは右手系の座標系ですね。ちょっと勘違いしていました。

テクスチャマッピングを施した3Dプリミティブ形状(立方体や球体など)に対して、X軸、Y軸、およびZ軸の正負をそれぞれ反転させると、テクスチャの画像もその変換に応じて縦方向や横方向が反転したような表示となります。


球体(Sphere)にテクスチャマッピングして、Affine変換をしたときの表示例

Group に Sphereを追加し、GroupにAffine変換を設定します。

    Group lhsGroup = new Group();
    Sphere earth = new Sphere(10);
    lhsGroup.getChildren().add(earth);
    :

テクスチャマッピングで使用する画像は次です。

カメラ位置はこのAffine変換を受けないようにしています(lhsGroupにはカメラを子ノードとして指定しない)。

以下に、Affine変換において、X軸、Y軸、Z軸をそれぞれだけ反転させる変換を指定し、そのときの表示結果を示します。

恒等変換
lhsGroup.getTransforms().add(new Affine(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0));

これはふつうに表示されています。

X軸方向を反転
lhsGroup.getTransforms().add(new Affine(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0));

画面でX軸は横方向になります。ちょうど、左右が逆転した画像となっています。

Y軸方向を反転
lhsGroup.getTransforms().add(new Affine(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0));

画面でY軸は縦方向となります。ちょうど、上下が逆転した画像となっています。

Z軸方向を反転
lhsGroup.getTransforms().add(new Affine(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0));

画面でZ軸は、高さ(奥行き)方向となります。画面の手前から奥の方向です。
JavaFXの座標系は左手系右手系なので、画面の手前から奥に向かう方向がZ軸の正となっています。
これを反転させると、画面の手前に向かう方向が正となります。
テクスチャマッピングの画像は次のようになっています。

この変換では、テクスチャマッピング画像の両端の接合が球の中央(Z軸がAffine変換後の負の側)となっています。

  • 左右方向も逆転しています。画面ではオーストラリアが右下に、アジアが右上に位置してします。
  • 画像が暗いのは、点光源がAffine変換の結果、カメラから見て球体向こう側になっているためです。