質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2081閲覧

OpenGLにおける座標変換の行列は全体でどうなっているのか知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2020/09/24 09:11

OpenGLの座標ですがワールド行列(回転、移動、拡大縮小) , 透視射形行列の2つでよろしいのでしょうか?それと頂点座標とありますが。説明によってモデル変換、ワールド変換とかたくさん説明があると思うのですが結局どうなっているのかが知りたいです。
最後に 透視射形行列 ワールド行列 * 頂点ということなのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

[ルール1] 最終的に表示される範囲というのは「X,Y,Zが-1~1の範囲に入っているものだけ」です.

[ルール2] 同一の(X,Y)を取る複数の対象が存在する場合には,Zの大小関係によってそれら複数の対象のうちのどれを実際に描画するのかが決定されます(デフォルトでは最もZ小さいやつが描画されるハズ).

これがOpenGLで決まっている事柄です.
(※私の記憶ですので,話の裏はとってください)


だから,いきなり上記のOpenGLのルールに合わせて頂点座標を用意できるのならば,各種行列を用いた計算は一切不要である.
例えば,表示域の左上の方に表示されて欲しい頂点を(-0.8, -0.8, 0)とか,右下ぎりぎりに表示されて欲しい頂点を(1,1,0)だとか,最初から与えればいい.


ところが大抵の場合,私たちはわがままなので

  1. 「同じオブジェクトでも手前にあるほど大きく,奥にある小さく見えてほしい」
  2. 「奥にある物は手前にある物に隠されて欲しい」

とかほざく.

1.を達成するには奥行(Z座標)がでかいほど(X,Y)の絶対値を小さく与えてやる必要がありそうである.
また,2.を達成するためには([ルール2]を利用して)Zの値を,奥にあるほど大きく,手前にあるほど小さく与えてやればよさそうだ.

この2つを達成する計算が(Perspectiveな)透視投影.
だから,このわがままだけを達成するならば,バーテックスシェーダの計算内容は,
出力座標 = 入力座標を透視投影した結果
であり,この透視投影の計算を(わざわざ)行列を用いて実装した結果が,
出力座標 = 透視投影の行列 * 入力座標(同次座標系のベクトル)
ということだ.
※同次座標とかいうのを導入する必要が生じたのも,この計算を行列で達成するため.


人によっては,さらにわがままを言う.

  1. 「カメラ」という概念を与えて,ある位置にある方向でカメラを設置した際にそのカメラで撮影したような絵が作りてぇ…

とか.
これを達成するにはどうすればいいのか.
出力座標 = (入力座標をカメラから見たときの座標になおした座標)を透視投影した結果
とすればよさそうだ.
ここで言う「カメラから見たときの座標」というのは,カメラから見て右側に行くほどXが大きくなって,カメラか見て奥に行くほどZが大きくなって…云々.
で,そのようになる計算を(わざわざ)行列を用いて実装した結果が,
出力座標 = 透視投影の行列 * (カメラ座標系に変換するための行列 * 入力座標)
という形だ.


でも人によっては,さらにわがままで,
物体を回転させたり平行移動させたり拡大縮小させた果ての結果をカメラで撮影したような絵にできれば便利とかなんとかほざきやがる.

で,
出力座標 = 透視投影の行列 * (カメラ座標系に変換するための行列 * (回転と並進と拡縮のための行列 * 入力座標))
みたいな形にどんどんエスカレートしていく.わがままなせいで.

「回転と並進と拡縮のための行列」というのをどう作るのか? というのも,その人のわがままっぷりに依る.
「回転させてから並進させてぇ…」という人と,「せっかくだから俺は先に平行移動させて,後から回転させるぜ!」という人とでは作り方が異なるわけだ.
(なので,あなたが,回転と並進とスケールのための3つの行列を用意したとすれば,その時点でそれをどのような順で掛け合わせるのかは既にあなたにとって自明であるハズだ.人に訊くことじゃない.)


…といった感じ.
何をどういう順で計算していくのかは,あなたのやりたいこと次第.
例えば,「カメラ」なんて概念をわざわざ導入しなくて済むならば,その分だけ計算内容は少なくなる.

投稿2020/09/24 10:18

編集2020/09/24 10:19
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/24 10:23

プログラミングは自由だから決まりきった概念はあまりないのですね。
fana

2020/09/24 10:26

ここに書いたのと同様の内容をやりたいならば,まぁ同様の計算順になるでしょう. (このくらいの形の話をよく見かけるだろうと思う.)
fana

2020/09/24 10:48

実装の形は一意じゃない. ググったり書籍を見たりすれば,大抵の場合,この手のやつでは同次座標を用いているだろうし,回転させるには回転行列をつくってどうこういう話になっていると思うけども, ・俺は平行移動を足し算でダイレクトに実装するぜ!(だって,X方向に2だけ動かしたいなら,X座標に2を足せばいいだろ?) ・透視投影も要素毎に相応の結果になる計算をするぜ!(そっちの方が俺には直感的に解りやすいので!) …とするならば,同次座標は不要. 回転も「回転行列」なる行列が必須なわけじゃない. (どういう方法で計算しようが最終的に回転した位置に来さえすればいいのだから) 計算効率とか扱い易さとか何やかんやの理由に基づいて決めればいい.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問