なぜ近くの三角形が消える傾向があるのですか?


8

裏面カリングを有効にしたところ、奇妙な動作に気づきました。三角形のすべての頂点がビューの外側にあり、そのうちの2つが背後にあると(私はそうです)、三角形が消えます。

それを見るには、ここにGIFがあります。

ここに画像の説明を入力してください

投影行列が2つの頂点の順序を逆にし、それらが私の後ろに落ちて、三角形の曲がり方を変えたのではないかと思います。

しかし、すべての頂点が見えない場合にのみ三角形が消える理由は不明です...

可能であれば、この問題を回避するにはどうすればよいですか?

それが問題ならLinuxで開発します。

更新:

裏面カリングによるものではない可能性が指摘されています。無効にしたので、実際に再現できます。立方体は20×20で、垂直視野は90°です。垂直方向の見かけのサイズは、ウィンドウをほぼ埋めます。

更新2:

では、コードの関連部分を投稿します。投影とビューマトリックスは、自分の関数を使用して設定されます。

void createViewMatrix(
    GLfloat matrix[16],
    const Vector3 *forward,
    const Vector3 *up,
    const Vector3 *pos
)
{
    /* Setting up perpendicular axes */
    Vector3 rright;
    Vector3 rup = *up;
    Vector3 rforward = *forward;

    vbonorm(&rright, &rup, &rforward); /* Orthonormalization (right is computed from scratch) */

    /* Filling the matrix */
    matrix[0] = rright.x;
    matrix[1] = rup.x;
    matrix[2] = -rforward.x;
    matrix[3] = 0;

    matrix[4] = rright.y;
    matrix[5] = rup.y;
    matrix[6] = -rforward.y;
    matrix[7] = 0;

    matrix[8] = rright.z;
    matrix[9] = rup.z;
    matrix[10] = -rforward.z;
    matrix[11] = 0;

    matrix[12] = -vdp(pos, &rright);
    matrix[13] = -vdp(pos, &rup);
    matrix[14] = vdp(pos, &rforward);
    matrix[15] = 1;
}

void createProjectionMatrix(
    GLfloat matrix[16],
    GLfloat vfov,
    GLfloat aspect,
    GLfloat near,
    GLfloat far
)
{
    GLfloat vfovtan = 1 / tan(RAD(vfov * 0.5));

    memset(matrix, 0, sizeof(*matrix) * 16);
    matrix[0] = vfovtan / aspect;
    matrix[5] = vfovtan;
    matrix[10] = (near+far)/(near-far);
    matrix[11] = -1;
    matrix[14] = (2*near*far)/(near-far);
}

この呼び出しで設定された射影行列:

createProjectionMatrix(projMatrix, VERTICAL_FOV, ASPECT_RATIO, Z_NEAR, 10000);

(VERTICAL_FOV = 90、ASPECT_RATIO = 4.0 / 3、Z_NEAR = 1)

レベル描画は単純です:

void drawStuff()
{
    GLfloat projectView[16];

    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    createViewMatrix(viewMatrix, &camera.forward, &camera.up, &camera.pos);

    multiplyMatrix(projectView, viewMatrix, projMatrix); /*< Row mayor multiplication. */

    glUniformMatrix4fv(renderingMatrixId, 1, GL_FALSE, projectView);
    bailOnGlError(__FILE__, __LINE__);

    renderLevel(&testLevel);
}

キューブは壁ごとにレンダリングされます(これを最適化することは別の話になります):

    for (j = 0; j < 6; j++)
    {
        glBindTexture(GL_TEXTURE_2D, cube->wallTextureIds[j]);
        bailOnGlError(__FILE__, __LINE__);

        glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, (void*)(sizeof(GLuint) * 4 * j));
        bailOnGlError(__FILE__, __LINE__);
        glUniform4f(extraColorId, 1, 1, 1, 1);
        bailOnGlError(__FILE__, __LINE__);
    }

頂点シェーダー:

#version 110

attribute vec3 position;
attribute vec3 color;
attribute vec2 texCoord;

varying vec4 f_color;
varying vec2 f_texCoord;

uniform mat4 renderingMatrix;

void main()
{
    gl_Position =  renderingMatrix * vec4(position, 1);
    f_color = vec4(color, 1);
    f_texCoord = texCoord;
}

フラグメントシェーダー:

#version 110

varying vec4 f_color;
varying vec2 f_texCoord;

uniform sampler2D tex;

uniform vec4 extraColor;

void main()
{
    gl_FragColor = texture2D(tex, f_texCoord) * vec4(f_color) * extraColor;
}

深度バッファーは、有効にすることで簡単に設定できます。


ここで、あなたが話している三角形がわかりません。
Trevor Powell

@TrevorPowell立方体の正方形の面は2つの三角形で構成され、正方形の半分は2番目の写真で消えます。
Calmarius

私は理解した。しかし、どの正方形を参照していますか?2番目の画像のどのビットを見ているのか、2番目の画像のどの頂点が最初の画像のどの頂点に対応するのかわかりません。右端の青い壁が近くのクリップ面を通過しているように見えますか?それとも、一番右の白い壁について話していますか?または何?
Trevor Powell

1
これを引き起こしているコードを教えてください。
akaltar 2013

1
したがって、画面の下部にある頂点が見えなくなると、三角形が消えるように見えます。これは間違いなく裏面カリングを有効にしたときにのみ発生しましたか、それともその後気付いた可能性がありますか?立方体の面は、見ることができる部分に比べて非常に大きいですか(算術オーバーフローの可能性を考えています)?別のハードウェアで試す可能性はありますか(ドライバーのバグである可能性があります)?
GuyRT 2013

回答:


6

同様の問題はしばしばクリッピングによって引き起こされますが、ここではニアプレーンは問題ではありません。もしそうなら、消失は三角形ごとではなくピクセルごとになります。

アニメーションでは、3つの頂点すべてが画面の外に出た瞬間に三角形が完全に消えます。アルゴリズムは、すべての頂点が非表示になっているときに三角形が非表示になるという誤った仮定に基づいている場合があります。

これは良い錐台カリング実装について話している記事です。


すべての頂点がビューの外に出ても、三角形は常に消えるわけではありません。これはOpenGLのタスクをクリッピングしていませんか?
Calmarius 2013

@Calmariusダニジャーが言っていることは、それがあなたの錐台カリングアルゴリズムの問​​題であるということです。正直なところ、それはドライバーの問題/バグだと思います。
concept3d 2013

@Calmarius concept3dは正しいかもしれませんが、Mesaを使用していて、問題の原因となるバグがある可能性があります。公式のNvidiaまたはAMDドライバーを搭載したマシンでコードを実行できますか?
danijar 2013

@danijarたぶん、休暇後に仕事に戻るとき。内蔵のビデオカードだけが組み込まれている、追加のビデオカードがない古いスクラップコンピュータを使用しています。
Calmarius

4

これまでのところ、それはOpenGLドライバーの問題のようです。これをテストして確認する他のコンピュータはありません。

ソフトウェアによるレンダリングを強制すると

$ export LIBGL_ALWAYS_SOFTWARE=1

問題はなくなります。おそらく、Mesaのバグを見回す必要があります。


私はこれを受け入れます。問題は私のデスクトップボックスでも他のコンピューターでも起こりません。
Calmarius 14年

-1

これは純粋にカメラのニアクリッピングプレーンに関連しており、裏面カリングには関連していません。Uはニアクリッピングプレーンを減らす必要があり、クリッピングはオフになります。


注意深く見ると、三角形が単純に消えていることがわかります。これは、近くのクリッピング平面とは関係ありません。
Calmarius

-1

三角形は、カメラの錐台の近くの平面のために消えています。近くの平面よりもカメラに近いものはすべて自動的にクリップされます。あなたはあなたの近くの飛行機をカメラの場所のさらにもっと近くに置く必要があるだけです。ニアプレーンを構成する方法は、グラフィックライブラリまたはエンジンによって異なります。OpenGLのでは、例えば、あなたはのzNearパラメータ設定する必要がありgluPerspectiveでは

void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);

はい、そのように見え、裏面カリングとは何の関係もありません。
concept3d 2013

3
これにより、近くのクリッピング平面と交差する三角形全体が消えますか?断片の一部を切り取ってはいけませんか?

3
これだとは思わない。そのカメラはまっすぐ前を向いているように見え、それらの壁は垂直です。つまり、近くのクリッピング平面を横切ることによってクリッピングされるものはすべて、これらの浅い角度ではなく、垂直線を画面上に作成する必要があります。表示されている画像は、三角形が誤って間引かれているように見えます。
Trevor Powell、

@TrevorPowellはい、あなたは正しいと思います。投票を取り消しました。
concept3d 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.