0

錐台変換の基本を理解するための助けが必要です。主に、深さがどのように機能するか。

以下は、768x1024 のビューポートを使用しています。直交投影と 768x768 (z のデフォルトは 0) の正方形を平行移動やスケーリングなしで使用すると、glViewport(0, 0, 768, 1024)この正方形のビューポートがフレームの幅を簡単に埋めます。

ここに画像の説明を入力

プロジェクトを錐台に変更し、z 変換をいじると、遠近法が変更されたため、正方形が適切にスケーリングされます。

このような環境での同じ正方形は次のとおりです。

ここに画像の説明を入力

この z 変換と、錐台行列の近距離パラメーターと遠距離パラメーターを操作して、それに応じて正方形の変化が画面上で明らかなサイズになるようにすることができます。罰金。

しかし、私が把握できないのは、画面上のサイズとこれらの深度パラメーターの間の明らかな関係です。

たとえば、上記の最初の例の画像のように、錐台を使用したいが、フレームの幅を正方形で埋めたいとします。これを達成する方法は?

z 変換が平面と一致した場合、near基本的に「カメラの真正面」に正方形があり、フレームがいっぱいになると思います。しかし、私はこれを達成する方法を理解できません。私の近くが で1あり、私の z 移動が-1である場合、正方形は近くの平面自体(右?!) に正しく配置され、フレームの幅を埋める必要があります (錐台の左右の平面が正射影と同じである場合)。 .

ここに一連のコードを貼り付けて、何をしているのかを示すことができますが、ここでの概念は明確だと思います。ニアプレーンが実際にどこにあるか、その上に何かを配置する方法を理解したいだけです。これは、フラスタムがどのように機能しているかを理解するのに役立ちます。


さて、ここに私が使用している関連コード、 wherewidth=768height=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 の場合、ご想像のとおり、カメラの後ろにあるため、正方形は表示されません。

4

2 に答える 2

5

錐台行列でm.w.wは、1 ではなく 0 にする必要があります。これで問題が解決します。

しかし、間違いはあなたのせいではありません。それは私のせいです!実は私が最初にそのコードを書いたのですが、残念ながらそれは増殖してしまいました。これは私の本 ( iPhone 3D Programming )の正誤表で、最初に登場した場所です。

これは罪悪感がすごい!

于 2013-03-11T23:13:02.673 に答える
2

ニアが 1 で z トランスレーションが -1 の場合、正方形はニア プレーン自体に正しく配置されているはずです (右?!)。

はい

、フレームの幅を埋めます(錐台の左右の平面は正射影と同じです)。

必ずしもそうではありません。近い平面には、glFrustum のleftrightbottom、およびtopパラメーターで指定された範囲があります。正確にこれらの境界に向かう四角形は、近平面距離に配置されると、ビューポートにぴったりと収まります。

于 2013-03-11T12:26:43.863 に答える