0

フレームバッファにアタッチされたテクスチャをカスタム深度バッファとして使用しています。最初のレンダリング パスでは、深度値を保存するようにテクスチャにレンダリングします。2 番目のレンダリング パスでは、このテクスチャからルックアップを行い、フラグメントをレンダリングするか破棄するかを決定します。

これはうまく機能しますが、デバイス (iPad 3) では、深度値がテクスチャに書き込まれるときに発生する何らかの丸め誤差に起因すると思われる厄介なアーティファクトがいくつかあります。テクスチャなどに固定値を書いてみた0.5のですが、テクスチャから読み返すと より0.03高いか低いか0.5

深度値を 3 つの RGB 値に「エンコード」します (4 番目のコンポーネント、アルファまたはwは無視されます)。

const highp vec4 packFactors = vec4(1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0);
const highp vec4 cutoffMask  = vec4(1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 0.0);

void main() {
    highp float depth = ...
    ...
    highp vec4 packedVal = fract(packFactors * depth);
    packedVal.x = depth;      // undo effect of fract() on x component
    gl_FragColor = packedVal - packedVal.yzww * cutoffMask;
}

このようにして、深さを格納するために 3x8 ビットの精度を取得します ( http://www.rojtberg.net/348/powervr-sgx-530-does-not-support-depth-texturesに触発されました)

他のフラグメント シェーダー (2 番目のレンダリング パス) では、次のようにテクスチャから読み取ります。

    highp vec4 depthBufferLookup = texture2D(depthTexture, vDepthTex);
    highp float depthFromDepthBuffer = dot(depthBufferLookup, vec4(1.0) / packFactors);

packFactors最初のシェーダーと同じ値を使用します。

この手順でまともな精度が得られると思いますが0.03、値が の場合よりも大きな誤差がある0.5と、かなり使い物にならなくなります。

ヒントはありますか?

ところで、私は次のテクスチャタイプを使用しています:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
4

0 に答える 0