まず基本的なことを考えてみましょう。
通常、次の手順を通して、あなたの地元の三角形の頂点を変換したい:標準GLでlocal-space coords-> world-space coords -> view-space coords -> clip-space coords
は、最初の2つの変換はGL_MODELVIEW_MATRIX
を介して行われ、第三は、GL_PROJECTION_MATRIX
を介して行われます
これらのモデルビュー変換は、通常適用したい(変換、スケール、回転など)多くの興味深い変換に対して、で頂点を表現するときにベクトル - 行列乗算として表現できるようになります。通常、頂点V = (x, y, z)
は、このシステムでは(x, y, z, 1)
と表されます。
頂点V_localを平行移動し、次に回転させ、次に平行移動を行いたいとします。各変換は行列*で表すことができます。それらをT1、R1、T2と呼ぶことにしましょう。 各頂点に変換を適用したい:V_view = V_local * T1 * R1 * T2
。行列乗算は連想的であり、我々はすべてのために一度だけ計算することができるM = T1 * R1 * T2
。
このようにして、Mを頂点プログラムに渡し、V_view = V_local * M
を計算すればよいだけです。最後に、典型的な頂点シェーダは、頂点位置を単一の行列で乗算します。その1つの行列を計算するすべての作業は、オブジェクトをローカル空間からクリップ空間に移動する方法です。
Ok ...多くの重要な詳細を見てみました。
まず、私が今まで説明したことは、通常はクリップ空間ではなく、ビュー空間までの変換を実際にカバーするだけです。しかし、ハードウェアは、頂点シェーダの出力位置がその特別なクリップ空間で表現されることを期待しています。重要な計算なしにクリップ空間座標を説明するのは難しいので、私はそれを残しておきますが、重要なのは、頂点をそのクリップ空間にもたらす変換は、通常、同じタイプの行列乗算として表現できるということです。これは古いgluPerspective、glFrustumとglOrthoが計算するものです。
第2に、これは頂点の位置に適用されます。法線を変換する数学は多少異なります。これは、法線を変換後に垂直に保ちたいからです(参考のために、一般的な場合はモデルビューの逆転置による乗算が必要ですが、多くの場合、単純化することができます)
第3に、4D座標を頂点シェーダに送ることはありません。一般に、3Dのものを渡します。 OpenGLは、頂点シェーダが余分な座標を追加する必要がないように、これらの3次元座標(または2-D、btw)を4-D座標に変換します。各頂点を拡大してw
の座標として1を追加します。
だから、すべてのオブジェクトをまとめてまとめるには、オブジェクトに適用するすべての変換に基づいて、それらのマジックM行列を計算する必要があります。シェーダの内部では、各頂点の位置にその行列を掛けて頂点シェーダの位置出力に渡す必要があります。典型的なコードは、多かれ少なかれ(これは古い命名法を使用している)である。
mat4 MVP;
gl_Position=MVP * gl_Vertex;
*実際の行列は、特にこれらの各機能のmanページには、ウェブ上で発見することができます:rotate、translate、scale、perspective 、ortho
その非常にトーゴの答えをありがとう!私が見逃した詳細は、glDrawElementsの呼び出しの間にMVP行列を変更することができるということです()。これらの非常に一般的な行列の仕様をプログラマに残すためにkhronosから変わった動き。彼らはすぐにgluまたは同様の方法に彼らの方法を見つけることを願って... – Wonko
これはミドルウェアのためです。 GL3.2は、高速コーディングにはあまり表現力がありません。しかし、以前のバージョンは、実際のアプリケーションでは抽象度が間違っていました。それには国家管理の枠組みが必要でした。 また、行列を保持したいとします。これは、ドライバがすべての行列スタックを保持しなければならないこと、それを必要とする_all_シェーダ(頂点だけではない)にそれらを渡す方法、M、MV、MVP、IT(MV)、IT )。最悪の部分?一度に多くの行列操作を実行することで、効率的に数学を行うことができる唯一のアプリケーションです。 GLはそれを効率的に行うことはできません。 – Bahbar