4

非表示のエッジを削除してオブジェクトのエッジを描画したい。適用したいアイデアは、最初にオブジェクトの面を深度バッファーにレンダリングし、次に2番目のパスで深度テストを有効にしてエッジを描画することです。

すべての三角形のエッジが表示されるわけではないため、エッジは個別に保存されます(単純な例:立方体では、対角線のエッジは表示されませんが、クワッドは2つの三角形としてレンダリングされるため表示されます)。したがって、面はを使用しGL_TRIANGLESて描画され、エッジはGL_LINES別の頂点バッファを使用して描画されます。

問題は、この設定では非表示のエッジが部分的に表示され、表示されているエッジが部分的に非表示になることです。どうすれば適切な結果を得ることができますか?

  • 深度テストなし:

    深度テストなし

  • 深度テストあり:

    深度テストあり

  • デプスバッファにレンダリングされる面:

    顔のみ

オブジェクトを描画するために、色と深度のバッファがアタッチされたフレームバッファを使用します。

// Color buffer setup.
glBindTexture(GL_TEXTURE_2D, objectEdges);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 360, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);

// Depth buffer setup.
glBindRenderbuffer(GL_RENDERBUFFER, objectFaces);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 640, 360);

// Framebuffer setup.
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                       GL_TEXTURE_2D, objectEdges, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
                          GL_RENDERBUFFER, objectFaces);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
assert(glGetError() == GL_NO_ERROR);

この設定は問題なく機能します。オブジェクトを次のように描画します。

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_TRUE);
glBindVertexArrayOES(vertexArray_faces);
glDrawArrays(GL_TRIANGLES, 0, vertexCount_faces);
glBindVertexArrayOES(0);

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_FALSE);
glBindVertexArrayOES(vertexArray_edges);
glDrawArrays(GL_LINES, 0, vertexCount_edges);
glBindVertexArrayOES(0);

glDisable(GL_DEPTH_TEST);

使用されるシェーダーは、標準のモデル-ビュー-プロジェクション頂点シェーダーであり、すべてのフラグメントに対して白を出力するフラグメントシェーダーです。

GLKMatrix4 projectionMatrix = 
    GLKMatrix4MakePerspective(
        GLKMathDegreesToRadians(65.0f), 640.0 / 360.0f, 0.01f, 10.0f);
GLKMatrix4 modelViewMatrix = 
    GLKMatrix4MakeLookAt(0.2f, 0.4f, 0.2f, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
4

1 に答える 1

7

線の深さの値が塗りつぶされたプリミティブとは少し異なる方法で計算されるという問題が発生しています。あなたがやろうとしていることが、いわゆる「ポリゴン オフェスト」が存在する理由の 1 つです。全体は、付録の公式プログラミングガイドに記載されています:「隠線の削除」

于 2011-11-24T12:49:46.423 に答える