錐台変換の基本を理解するための助けが必要です。主に、深さがどのように機能するか。
以下は、768x1024 のビューポートを使用しています。直交投影と 768x768 (z のデフォルトは 0) の正方形を平行移動やスケーリングなしで使用すると、glViewport(0, 0, 768, 1024)
この正方形のビューポートがフレームの幅を簡単に埋めます。
プロジェクトを錐台に変更し、z 変換をいじると、遠近法が変更されたため、正方形が適切にスケーリングされます。
このような環境での同じ正方形は次のとおりです。
この z 変換と、錐台行列の近距離パラメーターと遠距離パラメーターを操作して、それに応じて正方形の変化が画面上で明らかなサイズになるようにすることができます。罰金。
しかし、私が把握できないのは、画面上のサイズとこれらの深度パラメーターの間の明らかな関係です。
たとえば、上記の最初の例の画像のように、錐台を使用したいが、フレームの幅を正方形で埋めたいとします。これを達成する方法は?
z 変換が平面と一致した場合、near
基本的に「カメラの真正面」に正方形があり、フレームがいっぱいになると思います。しかし、私はこれを達成する方法を理解できません。私の近くが で1
あり、私の z 移動が-1
である場合、正方形は近くの平面自体(右?!) に正しく配置され、フレームの幅を埋める必要があります (錐台の左右の平面が正射影と同じである場合)。 .
ここに一連のコードを貼り付けて、何をしているのかを示すことができますが、ここでの概念は明確だと思います。ニアプレーンが実際にどこにあるか、その上に何かを配置する方法を理解したいだけです。これは、フラスタムがどのように機能しているかを理解するのに役立ちます。
さて、ここに私が使用している関連コード、 wherewidth=768
とheight=1024
.
私の頂点シェーダーはシンプルですgl_Position=Projection*Modelview*Position;
したがって、私の射影行列(錐台)は次のとおりです。
Frustum(-width/2, width/2, -height/2, height/2, 1,10);
この関数は次のとおりです。
static Matrix4<T> Frustum(T left, T right, T bottom, T top, T near, T far)
{
T a = 2 * near / (right - left);
T b = 2 * near / (top - bottom);
T c = (right + left) / (right - left);
T d = (top + bottom) / (top - bottom);
T e = - (far + near) / (far - near);
T f = -2 * far * near / (far - near);
Matrix4 m;
m.x.x = a; m.x.y = 0; m.x.z = 0; m.x.w = 0;
m.y.x = 0; m.y.y = b; m.y.z = 0; m.y.w = 0;
m.z.x = c; m.z.y = d; m.z.z = e; m.z.w = -1;
m.w.x = 0; m.w.y = 0; m.w.z = f; m.w.w = 1;
return m;
}
私の正方形は、デフォルトの z=0 の 2 つの 2D 三角形で、x の範囲は左から -768/2、右端は 768/2 です。正射影を使用して、上の最初の画像が示すように、正方形は明らかに適切に機能しています。(この質問の錐台投影に切り替えましたが)
正方形を描くために、Modelview を次のように変換します。
Translate(0, 0, -1);
使用:
static Matrix4<T> Translate(T x, T y, T z)
{
Matrix4 m;
m.x.x = 1; m.x.y = 0; m.x.z = 0; m.x.w = 0;
m.y.x = 0; m.y.y = 1; m.y.z = 0; m.y.w = 0;
m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0;
m.w.x = x; m.w.y = y; m.w.z = z; m.w.w = 1;
return m;
}
ご覧のとおり、平行移動は正方形を近平面に配置する必要がありますが、次のようになります。
-1.01 の代わりに変換すると、ほぼクリッピングを避けるために、結果は同じになります。移動しない場合、つまり z=0 の場合、ご想像のとおり、カメラの後ろにあるため、正方形は表示されません。