1

OpenGLESで3DiPhoneゲームを実行しています。

それは大きな世界ですが、いくつかの小さな一人称視点のビットを近くにペイントする必要があるため、glFrustumf()がさらに取る深度範囲(zNearとzFar)を減らすことはできません。

サーフェスがZファイティングのために出会うとき、ちらつきを防ぐために少し離してペイントします。また、これが便利で必要な場合に備えて、カメラの距離によって調整する距離が決まるようにしています。

大体は大丈夫ですが、分離によって遠近感が悪くなり、分離を小さくするとちらつきが発生する場合があります。表面をもっと近づけてペイントしたいです。

デプスバッファの精度を上げて、デプス範囲を狭くすることなくサーフェスを近づける方法はありますか?

そうでない場合、これを回避する他の方法はありますか?

私はまだアプリでOpenGLES1.1を使用していますが、それだけの価値がある場合はアップグレードしたいと思っています。

ご協力いただきありがとうございます。


デプスバッファを作成する方法は次のとおりです...

initメソッドの場合:

// Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
glGenFramebuffersOES(1, &defaultFramebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

//Added depth buffer
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);

resizeFromLayerメソッドの場合:

// Allocate color buffer backing based on the current layer size
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

//Added depth buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);

これが私が錐台を作成する方法です...

const GLfloat  zNear = 2.2;
const GLfloat  zFar = 30000;
const GLfloat  fieldOfView = 60.0;
GLfloat size = zNear * tanf(degreesToRadian(fieldOfView) / 2.0);

if (LANDSCAPE) { //for landscape clip & aspect ratio.
    //parameters are: left, right, bottom, top, near, far
    glFrustumf(-size/(backingWidth/backingHeight),
               size/(backingWidth/backingHeight),
               -size, size,
               zNear, zFar);
}
4

3 に答える 3

0

どうやら32ビットの深さのバッファはOpenGLES1.xではサポートされていません。

また、iOSでは16ビットのデプスバッファがサポートされていないようです。そのため、使用は24ビットとして動作していました。そのため、代わりGL_DEPTH_COMPONENT16_OESに使用しても改善は見られませんでした。GL_DEPTH_COMPONENT24_OES

GL_DEPTH_BITSデプスバッファを16ビットに設定しようとした後、これを確認しました。

glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);

GLint depthBufferBits;
glGetIntegerv(GL_DEPTH_BITS, &depthBufferBits );
NSLog(@"Depth buffer bits: %d", depthBufferBits );

出力:

Depth buffer bits: 24

まあ、少なくとも今はわかっています。これが他の誰かに役立つことを願っています。

于 2013-01-29T20:59:33.817 に答える
0

標準的な回答は、の使用を中心に展開しますglPolygonOffset。それは、バッファ内に既にあるものと比較する前に、ポリゴンの深度値にオフセットを追加することです。オフセットは画面の奥行きと角度を考慮して計算されるため、ワールドのサイズとは無関係であり、ペイントされるピクセルのアイデンティティには影響しません。

問題は、それをいつ使用するかを決定することです。たとえば、シーンが統一された広範なデータ構造 (四分木や BSP ツリーなど) を持たない多数の個別のオブジェクトである場合、オブジェクトが非常に近い (相対彼らの距離に)、近くにバンプを与えます。問題が個々のメッシュの内部にあり、より高いレベルの構造がない場合、明らかに問題はより複雑になります。

反対に、シーンが完全にまたは圧倒的に静的である場合は、深度バッファーを必要とせずにほとんどの描画を実行できる BSP ツリーのような構造が有利になる可能性があります。絶望的な結末では、深度書き込みを使用して前後にレンダリングできますが、比較は行われず、移動するオブジェクトを追加のレイヤーとして実行できます。実際には、大規模なオーバードロー (PVS ソリューションが役立ちますが) と、最新の初期深度カリングを使用したフロントツーバック (特に PowerVR のような遅延タイル ベースのレンダラー) が得られるため、簡単に勝つことはできません。

別のアイデアとして、離れたジオメトリを単純化する方法はありますか?

于 2013-01-29T21:35:38.210 に答える
0

私にとってうまくいったのは、遠近の値を調整することでした。far 値と near 値の差によって、深度バッファーの精度が決まります。例によって。far が 10000 で near が 500 だとします。合計の深さは 9500 になります。16 ビットの DepthBuffer では、深さの組み合わせが 65536 通りあります。(この値は、GPU と OpenGl の実装に応じて異なる方法でジオメトリを使用して計算されます) すると、空間の単位ごとに約 65536/9500 ~= 7 の可能な深さが得られます。次に、1/7 ~= .14 の深度精度が得られます。オブジェクト間の距離が 0.14 以下の場合、Z ファイティングが発生する可能性があります。実際にはこれはもっと複雑ですが、考え方は同じです。

多分あなたの遠い値は長すぎて、あなたはそれを必要としません。また、near 値を大きくすると、カメラに近いオブジェクト (より見えるオブジェクト) での Z ファイティングに役立ちます。

于 2013-05-09T21:47:30.557 に答える