3

私は、ユーザーが裏返しに見えるボックス、スカイボックス、またはそのようなものを構築することに取り組んでいます。これを行うには、6 つのクワッドを使用して立方体を作成し、立方体の内部に理論上のカメラを配置して、立方体を画像でテクスチャリングします。ユーザーはマウスを使用して見回すことができ、キューブが回転し、頭を動かしているように見えます。2 つの辺の交点に白い線が表示されるという問題が発生しました。実際のクワッドのサイズを同じに保ちながら、クワッドを引き込もうとしました。クリアカラーが黒であることを確認しましたが、まだ白い線が表示されています。

私が設定した属性は次のとおりです。

glClearColor(0.0, 0.0, 0.0, 0.0); 
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);

glClearDepth(1);
//S is the side length of the cube
float s = 5;
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glHint(GL_POLYGON_SMOOTH, GL_NICEST);

glEnable(GL_POLYGON_SMOOTH);

glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

キューブを作成するコードは次のとおりです。

float s = 5; //S is the side length of each quad
glNewList(m_cube, GL_COMPILE);
    {
        glPushMatrix();
        {
            glEnable(GL_TEXTURE_2D);

            glPushMatrix();
            {

                glBegin(GL_QUADS);
                {

                    //front
                    {
                        glTexCoord2f(0.5f, (1.0f / 3.0f));
                        //       glColor3f(1, 0, 0);
                        glVertex3f(((s / 2.0f)), ((s / 2.0f)),
                                   -((s / 2.0f))); //1

                        glTexCoord2f(0.25f, (1.0f / 3.0f));
                        //       glColor3f(1, 1, 0);
                        glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
                                   -((s / 2.0f))); //2
                        glTexCoord2f(0.25f, (2.0f / 3.0f));
                        //       glColor3f(1, 0, 1);
                        glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
                                   -((s / 2.0f))); //3
                        glTexCoord2f(0.5f, (2.0f / 3.0f));
                        //       glColor3f(1, 1, 1);
                        glVertex3f(((s / 2.0f)), -((s / 2.0f)),
                                   -((s / 2.0f))); //4
                    }

                    //left
                    {
                        glTexCoord2f(0.25f, (1.0f / 3.0f));
                        //       glColor3f(1, 0, 0);
                        glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
                                   -((s / 2.0f))); //2
                        glTexCoord2f(0.0f, (1.0f / 3.0f));
                        //       glColor3f(1, 1, 0);
                        glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
                                   ((s / 2.0f))); //5
                        glTexCoord2f(0.0f, (2.0f / 3.0f));
                        //       glColor3f(1, 0, 1);
                        glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
                                   ((s / 2.0f))); //6
                        glTexCoord2f(0.25f, (2.0f / 3.0f));
                        //       glColor3f(1, 1, 1);
                        glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
                                   -((s / 2.0f))); //3
                    }

                    //right
                    {
                        glTexCoord2f(0.75f, (1.0f / 3.0f));
                        //       glColor3f(1, 0, 0);
                        glVertex3f(((s / 2.0f)), ((s / 2.0f)),
                                   ((s / 2.0f))); //7
                        glTexCoord2f(0.5f, (1.0f / 3.0f));
                        //       glColor3f(1, 1, 0);
                        glVertex3f(((s / 2.0f)), ((s / 2.0f)),
                                   -((s / 2.0f))); //1
                        glTexCoord2f(0.5f, (2.0f / 3.0f));
                        //       glColor3f(1, 0, 1);
                        glVertex3f(((s / 2.0f)), -((s / 2.0f)),
                                   -((s / 2.0f))); //4
                        glTexCoord2f(0.75f, (2.0f / 3.0f));
                        //       glColor3f(1, 1, 1);
                        glVertex3f(((s / 2.0f)), -((s / 2.0f)),
                                   ((s / 2.0f))); //8
                    }

                    //back
                    {
                        glTexCoord2f(1.0f, (1.0f / 3.0f));
                        //       glColor3f(1, 0, 0);
                        glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
                                   ((s / 2.0f))); //5
                        glTexCoord2f(0.75f, (1.0f / 3.0f));
                        //       glColor3f(1, 1, 0);
                        glVertex3f(((s / 2.0f)), ((s / 2.0f)),
                                   ((s / 2.0f))); //7
                        glTexCoord2f(0.75f, (2.0f / 3.0f));
                        //       glColor3f(1, 0, 1);
                        glVertex3f(((s / 2.0f)), -((s / 2.0f)),
                                   ((s / 2.0f))); //8
                        glTexCoord2f(1.0f, (2.0f / 3.0f));
                        //       glColor3f(1, 1, 1);
                        glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
                                   ((s / 2.0f))); //6
                    }

                    //top
                    {
                        glTexCoord2f(.5f, 1.0f);
                        //       glColor3f(1, 0, 0);
                        glVertex3f(((s / 2.0f)), -((s / 2.0f)),
                                   ((s / 2.0f))); //7
                        glTexCoord2f(0.25f, 1.0f);
                        //       glColor3f(1, 1, 0);
                        glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
                                   ((s / 2.0f))); //5
                        glTexCoord2f(0.25f, (2.0f / 3.0f));
                        //       glColor3f(1, 0, 1);
                        glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
                                   -((s / 2.0f))); //2
                        glTexCoord2f(.5f, (2.0f / 3.0f));
                        //       glColor3f(1, 1, 1);
                        glVertex3f(((s / 2.0f)), -((s / 2.0f)),
                                   -((s / 2.0f))); //1
                    }

                    //bottom
                    {
                        glTexCoord2f(.5f, (1.0f / 3.0f));
                        //       glColor3f(1, 0, 0);
                        glVertex3f(((s / 2.0f)), ((s / 2.0f)),
                                   -((s / 2.0f))); //4
                        glTexCoord2f(0.25f, (1.0f / 3.0f));
                        //       glColor3f(1, 1, 0);
                        glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
                                   -((s / 2.0f))); //3
                        glTexCoord2f(0.25f, 0.0f);
                        //       glColor3f(1, 0, 1);
                        glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
                                   ((s / 2.0f))); //6
                        glTexCoord2f(.5f, 0.0f);
                        //       glColor3f(1, 1, 1);
                        glVertex3f(((s / 2.0f)), ((s / 2.0f)),
                                   ((s / 2.0f))); //8
                    }

                }
                glEnd();

            }
            glPopMatrix();
            glDisable(GL_TEXTURE_2D);
        }
        glPopMatrix();
    }
    glEndList();

カマラを設定するコードは次のとおりです。

float near_ = 1f;
float far_ = 10.0f;

float halfHeight = near_ * (Radian(m_fov)) / 2.0f;
float halfWidth = (static_cast<float>((m_width)) / static_cast<float>((m_height))) * halfHeight;
glViewport(0, 0, m_width, m_height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glFrustum(-halfWidth, halfWidth, -halfHeight, halfHeight, near_, far_);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

画面にレンダリングするコードは次のとおりです。

void VideoStreamer::render()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

float pitch = clamp(Degree(m_pitch), Degree(-(80.f)), Degree(80.f));
float yaw = wrap(m_yaw, Degree(0), Degree(360));
float roll = wrap(m_roll, Degree(0), Degree(360));
glPushMatrix();
{
    glLineWidth(5);
    glPushMatrix();
    {
        if (1)
        {
            glRotatef(pitch, 1.0, 0.0, 0.0);
            glRotatef(yaw, 0.0, 1.0, 0.0);
            glRotatef(roll, 0.0, 0.0, 1.0);
        }

        glCallList((m_cube));
    }
    glPopMatrix();
}
glPopMatrix();
SDL_GL_SwapBuffers();
}//end render

そして、これが何が起こっているかのスクリーンショットです。青と黒の四角形の間の白い線に注意してください:
ここに画像の説明を入力

これが私が使用しているテクスチャ、解像度600x450ですが、線は複数の解像度で発生します:

ここに画像の説明を入力

私の質問は、どうすればその白い線を取り除くことができますか?

編集:白い線は、上下が左右に交わる場所にのみ表示されます

編集:提案を反映するようにコードを更新しました

4

4 に答える 4

3

コメント部分でこの写真をあげることができなかったので、この写真のように平面の高さを同じに保ちながら、クワッドの長さを長くすることはできますか?

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

GPUの浮動小数点精度はどのくらいでしたか?

float near_ = 0.00000001f; 

だからあなたはすでに試しました:

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

どの画面サブスペース分割手法を使用していますか?

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

仮定:あなたの破線はZファイティングに由来する可能性があります

Zファイティングは、2つ以上のプリミティブがZバッファで同様の値を持っている場合に発生する3Dレンダリングの現象です。これは、2つの面が本質的に同じスペースを占め、どちらも前面にない同一平面上のポリゴンで特によく見られます。影響を受けるピクセルは、 zバッファの精度によって決定される方法で、1つのポリゴンまたは他のポリゴンからのフラグメントで任意にレンダリングされます。また、シーンやカメラが変更されると変化する可能性があり、1つのポリゴンがzテストに「勝ち」、次に別のポリゴンが「勝ち」ます。全体的な効果は、画面のピクセルを着色するために「戦う」2つのポリゴンのちらつきとノイズの多いラスタライズですこの問題は通常、サブピクセルの精度と浮動小数点の制限によって引き起こされます。固定小数点の丸め誤差

于 2012-09-11T16:44:55.937 に答える
3

あなたが見ているのは、テクスチャに実際に白があるということです。そのため、顔の境界にあるフラグメントは、白い部分からフェッチされます (テクスチャで線形フィルター タイプを有効にすると、より明確にわかります)。

それを修正するためにできること:

  1. アンラップされた立方体テクスチャの境界で予想される色を複製します (青の左に赤を追加し、右に黒を追加し、赤と黒の上に青を追加し、下の部分についても同様に...)
  2. または、2D マップではなくキューブマップを使用するようにコードを切り替えてください。それらは立方体面で適切なフィルタリングを提供します
于 2012-09-12T19:46:58.927 に答える
2

問題は、テクスチャにテクスチャリークがあり、側面の間に境界線の色が表示されていたという事実でした。私の計算は正解で、テクスチャテクセルを配置しましたが、修正できる浮動小数点エラーが発生しています。

于 2012-09-12T19:41:52.727 に答える
1

これはシンチレーションにかなり似ており、ほとんどの場合、丸め誤差が原因です。四角形のサイズは完全に妥当に見えますが、ニアプレーンの値は非常に小さいです。これにより、頂点に MVP 行列を掛けると、大きな丸め誤差が発生する可能性があります。ニアプレーンを に設定してみてください.1f

編集それ以外の場合は、頂点作成コードでバグの可能性があるかどうかを確認してください。私が従うのは少し難しかったです - 例えば、上面は以下を使用して計算さ-((s / 2.0f)-.1),れます - なぜあなたは.1を引くのですか?

おそらく、頂点を作成する新しい関数を作成し、値をハードコーディングすることは、これが問題かどうかをテストする簡単な方法でしょう。

于 2012-09-11T16:55:07.090 に答える