2

後処理効果を 3D エンジンに統合中です。WebGLでFrameBufferオブジェクトを使用して深度データをキャプチャすると、障害が発生しました。FrameBuffer へのカラー データのキャプチャに問題はありません。ただし、 Chrome/Firefox で Depth 拡張機能を有効にしても、Depth データを取得できません。

var DepthEXT = webGLContext.getExtension( "WEBKIT_WEBGL_depth_texture" ) ||
                webGLContext.getExtension( "MOZ_WEBGL_depth_texture" );

構成の問題かどうかを確認するためにさまざまな設定を試しましたが、何を試しても白いテクスチャしか表示されません。投稿の最後のスクリーンショットは、テクスチャとしてレンダリングされたカラー アタッチメントとテクスチャとしてレンダリングされた深度アタッチメントを示しています。FrameBuffer の初期化に問題がありますか、それともこの問題を解決するために他の場所を探す必要がありますか?

以下は、FrameBuffer オブジェクトを初期化するための私のコードです。

    // Frame Buffer
    this.m_frameBuffer = gl.createFramebuffer();
    gl.bindFramebuffer( gl.FRAMEBUFFER, this.m_frameBuffer );

    // Render Buffer
    this.m_renderBuffer = gl.createRenderbuffer();
    gl.bindRenderbuffer( gl.RENDERBUFFER, this.m_renderBuffer );
    gl.renderbufferStorage( 
        gl.RENDERBUFFER,
        gl.DEPTH_COMPONENT16,
        sharedRenderer.canvasDOMElement.width,
        sharedRenderer.canvasDOMElement.height );

    // Diffuse Component
    this.m_diffuseComponentTexture = gl.createTexture();
    gl.bindTexture( gl.TEXTURE_2D, this.m_diffuseComponentTexture );

    gl.texParameteri( 
        gl.TEXTURE_2D,
        gl.TEXTURE_MAG_FILTER,
        gl.LINEAR );

    gl.texParameteri( 
        gl.TEXTURE_2D, 
        gl.TEXTURE_MIN_FILTER, 
        gl.LINEAR );

    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

    gl.texImage2D( 
        gl.TEXTURE_2D,
        0,
        gl.RGBA,
        sharedRenderer.canvasDOMElement.width,
        sharedRenderer.canvasDOMElement.height,
        0,
        gl.RGBA,
        gl.UNSIGNED_BYTE, 
        null );

    // Depth
    this.m_depthComponentTexture = gl.createTexture();
    gl.bindTexture( gl.TEXTURE_2D, this.m_depthComponentTexture );

    gl.texParameteri( 
        gl.TEXTURE_2D,
        gl.TEXTURE_MAG_FILTER,
        gl.NEAREST );

    gl.texParameteri( 
        gl.TEXTURE_2D, 
        gl.TEXTURE_MIN_FILTER, 
        gl.NEAREST );

    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

    gl.texImage2D( 
        gl.TEXTURE_2D,
        0,
        gl.DEPTH_COMPONENT,
        sharedRenderer.canvasDOMElement.width,
        sharedRenderer.canvasDOMElement.height,
        0,
        gl.DEPTH_COMPONENT,
        gl.UNSIGNED_SHORT, 
        null );

    // FrameBuffer
    // Diffuse
    gl.framebufferTexture2D( 
        gl.FRAMEBUFFER,
        gl.COLOR_ATTACHMENT0, 
        gl.TEXTURE_2D, 
        this.m_diffuseComponentTexture, 
        0 );

    // Depth
    gl.framebufferTexture2D( 
        gl.FRAMEBUFFER,
        gl.DEPTH_ATTACHMENT, 
        gl.TEXTURE_2D, 
        this.m_depthComponentTexture, 
        0 );

    // RenderBuffer
    gl.framebufferRenderbuffer( 
        gl.FRAMEBUFFER,
        gl.DEPTH_ATTACHMENT, 
        gl.RENDERBUFFER, 
        this.m_renderBuffer );


    // Unbind buffers and textures
    gl.bindTexture( gl.TEXTURE_2D, null );
    gl.bindRenderbuffer( gl.RENDERBUFFER, null );
    gl.bindFramebuffer( gl.FRAMEBUFFER, null );

現在のシーンを FrameBuffer にレンダリングするコードを次に示します。

CBRenderer.prototype.renderSceneToGBuffer = function( sceneToRender, GBufferTarget, deltaSeconds )
{
        CBMatrixStack.clearMatrixStackAndPushIdentityMatrix();

        this.applyProjectionMatrix();

        GBufferTarget.bindGBufferFrameBuffer();

        this.renderer.enable( this.renderer.DEPTH_TEST );
        this.renderer.depthMask( true );
        this.renderer.clearDepth( 1.0 );
        this.renderer.clearColor( 0.1, 0.1, 0.1, 0.0 );

        this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );

        sceneToRender.render( deltaSeconds );

        this.renderer.flush();

        GBufferTarget.m_dirty = false;
        GBufferTarget.unbindGBufferFrameBuffer();

        this.renderer.clearColor( 0.0, 0.0, 0.0, 0.0 );
        this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );

        this.renderer.bindTexture( this.renderer.TEXTURE_2D, null );
}

ここに画像の説明を入力

4

1 に答える 1

4

セットアップの最後に、FBO にデプス テクスチャがアタッチされていません。ある時点で、テクスチャを深度アタッチメントとして設定します。

// Depth
gl.framebufferTexture2D( 
    gl.FRAMEBUFFER,
    gl.DEPTH_ATTACHMENT, 
    gl.TEXTURE_2D, 
    this.m_depthComponentTexture, 
    0 );

しかし、その直後に、代わりにレンダー バッファーを深度アタッチメントとして設定します。

// RenderBuffer
gl.framebufferRenderbuffer( 
    gl.FRAMEBUFFER,
    gl.DEPTH_ATTACHMENT, 
    gl.RENDERBUFFER, 
    this.m_renderBuffer );

各 FBO 接続ポイントに接続できるターゲットは 1 つだけです。したがって、2 番目の呼び出しは、最初の呼び出しで設定したものを置き換えて、新しい深度アタッチメントを設定します。したがって、これが終了m_depthComponentTextureすると、もう FBO に関連付けられていません。

深度テクスチャを使用したい場合、深度レンダバッファも作成する理由がわかりません。必要なのは 2 つのうちの 1 つだけです。後でサンプリングする必要がない場合は、通常、深度にレンダーバッファーを使用します。結果からサンプリングしたい場合は、代わりにテクスチャが必要であり、レンダーバッファはもう必要ありません。

于 2014-11-16T01:41:26.400 に答える