0

ロードされたメッシュ、地面、スカイボックスのある小さなシーンがあります。キューブを生成し、頂点の位置をキューブマップテクスチャ座標として使用しています。

水平回転(y軸を中心に)は完全に機能し、ワールドの動きはスカイボックスに合わせられます。(カメラのx軸を中心とした)垂直回転は、他のオブジェクトの動きと一致していないようです。ただし、奇妙なことに、カメラが立方体の面の中心を見ていると、すべてが整列しているように見えます。言い換えれば、動きは非線形であり、いくつかの画像で効果を説明するために最善を尽くします。

まず、私が知る限り、水平方向の動きは正しいです:

前向き:前向き

ほぼ45度で左向き: ほぼ45度で左向き

90Degで左向き: 90度で左向き

そして今、動きにいくらかの矛盾があるように見える垂直方向の動き:

再び前を向く: 再び前向き

この画像のスカイボックスに対する地表プレーンの位置に注意してください。少し左に回転して、太陽が見えないはずなのに見えないようにしました。

少し下向き: 少し下向き

最後に、ビューを表示するための真上にあるビューは、(スカイボックス)立方体の面の中央に正しく配置されます。

真上を向いている: 真上を向いている

これが私の描画コードです。簡潔にするために、グランドプレーンとメッシュの描画は省略されています。(中央の立方体はロードされたメッシュであり、スカイボックスの同じ関数によって生成されないことに注意してください)。

void MeshWidget::draw() {

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glPushMatrix();

    glRotatef(-rot_[MOVE_CAMERA][1], 0.0f, 1.0f, 0.0f);
    glRotatef(-rot_[MOVE_CAMERA][0], 1.0f, 0.0f, 0.0f);
    glRotatef(-rot_[MOVE_CAMERA][2], 0.0f, 0.0f, 1.0f);

    glDisable(GL_DEPTH_TEST);
    glUseProgramObjectARB(shader_prog_ids_[2]);
    glBindBuffer(GL_ARRAY_BUFFER, SkyBoxVBOID);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(Vec3), BUFFER_OFFSET(0));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SkyIndexVBOID);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
    glUseProgramObjectARB(shader_prog_ids_[0]);
    glEnable(GL_DEPTH_TEST);

    glPopMatrix();

    glTranslatef(0.0f, 0.0f, -4.0f + zoom_factor_);

    glRotatef(rot_[MOVE_CAMERA][0], 1.0f, 0.0f, 0.0f);
    glRotatef(rot_[MOVE_CAMERA][1], 0.0f, 1.0f, 0.0f);
    glRotatef(rot_[MOVE_CAMERA][2], 0.0f, 0.0f, 1.0f);

    glPushMatrix();

    // Transform light to be relative to world, not camera.
    glRotatef(rot_[MOVE_LIGHT][1], 0.0f, 1.0f, 0.0f);
    glRotatef(rot_[MOVE_LIGHT][0], 1.0f, 0.0f, 0.0f);
    glRotatef(rot_[MOVE_LIGHT][2], 0.0f, 0.0f, 1.0f);

    float lightpos[] = {10.0f, 0.0f, 0.0f, 1.0f};
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

    glPopMatrix();

    if (show_ground_) {

        // Draw ground...
    }

    glPushMatrix();

    // Transform and draw mesh...

    glPopMatrix();
}

最後に、テクスチャ座標を生成するスカイボックスのGLSLコードを次に示します。

バーテックスシェーダー:

void main()
{
    vec4 vVertex = vec4(gl_ModelViewMatrix * gl_Vertex);

    gl_TexCoord[0].xyz = normalize(vVertex).xyz;
    gl_TexCoord[0].w = 1.0;

    gl_TexCoord[0].x = -gl_TexCoord[0].x;

    gl_Position = gl_Vertex;
}

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

uniform samplerCube cubeMap;

void main()
{
    gl_FragColor = texture(cubeMap, gl_TexCoord[0]);
}

また、すべてのカメラとオブジェクトの回転にクォータニオンを使用することが役立つかどうかも知りたいです。

さらに情報(または画像)が必要な場合は、お問い合わせください!

4

1 に答える 1

0

ビュースペースベクトル(vVertex)ではなく、ワールドスペースベクトル(gl_Vertex?)に基づいてスカイボックステクスチャルックアップを生成する必要があると思います。

スカイボックスの座標は、描画する前にモデルマトリックスの変換が表示されないため(カメラの回転のみ)、ワールドスペースですでに定義されていると想定しています。その場合、頂点のワールドスペース位置に基づいてスカイボックステクスチャをサンプリングする必要があります。カメラで変換する必要はありません。すでにカメラで頂点を変換しているので、ルックアップベクトルも変換する必要はありません。

に置き換えnormalize(vVertex)てみてnormalize(gl_Vertex)、それが状況を改善するかどうかを確認してください。

また、x = -xのことを取り除くかもしれませんが、テクスチャが元々間違った方向に回転していたという事実を補うために入れられたのではないでしょうか。

また、すべてのカメラとオブジェクトの回転にクォータニオンを使用することが役立つかどうかも知りたいです。

どのように助けますか?マトリックスの使用に勝る新しい機能はありません。マトリックスとクォータニオンのどちらのパフォーマンスが優れているかについては、どちらの方法でも議論を聞いていますが、それらを使用する必要はないと思います。

于 2012-05-31T05:50:35.680 に答える