4

マルチパス、マルチ RT ピンポン レンダリングで奇妙な問題が発生します

3 つのシェーダーと 1 つの FBO を使用していますが、どの段階でもエラーは発生しません。私はopengl 4を使用しているため、glBegin/glEndは使用していません。変換には独自のマトリックスを使用し、レンダリングには頂点バッファーを使用しています

このテストの一般的な考え方は、3 つの異なる色を 3 つの個別の fbo 添付ファイルにレンダリングすることです (最初のパスで vbo を 2 回レンダリングするのは効率的ではないことは理解していますが、これは他のソースの問題を理解するのに役立つだけです)。テクスチャの別のセットを fbo にバインドし、最初のセットをサンプラーとして使用します。最後のパスは、結果をバック バッファーにブレンドすることです。

奇妙なのは、出力が両方の四角形が赤く表示されることです (これらの値は 2 番目のシェーダーから取得されるため)。

2 番目のサンプラーから常に取得するように 2 番目のシェーダーの関数 SamplePix を変更すると、両方とも緑色に表示され、3 番目からルックアップするとすべて黄色に表示されますが、1 つからしか読み取れないようです。

今のところ、各サンプラーから読み取ることができる理由を説明できないようですが、ループが正しく検索されないようです (シェーダー 2)。

また、シェーダー 2 でサンプリングされたテクスチャのレンダリングに切り替えると、2 番目のパスで黒いクワッドが表示されます (画像 2)

うまくいけば、誰かが問題に光を当てることができます。(最初のパスの後に同期フェンス オブジェクトを追加しようとしましたが、違いはありませんでした)

赤

テクスチャ サンプル:

テックス

// initial setup of shaders and vertex buffers ommitted for now (in separate source files)

// fbo setup like so
const int DepthLayers = 3;

bool InitFBO()
{
// width and height 768pixels
    for (int j=0; j<DepthLayers; j++)
    {
        const int idx = j + (DepthLayers*i);

        glGenTextures(1, &g_FBOManager.m_fboTex[ idx ]);
        glBindTexture(GL_TEXTURE_2D, g_FBOManager.m_fboTex[ idx ]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        //no mipmaps
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, g_XMLSettings->WWidth(), g_XMLSettings->WHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);


        //depth
        glGenTextures(1, &g_FBOManager.m_fboDepthTex[ idx ]);
        glBindTexture(GL_TEXTURE_2D, g_FBOManager.m_fboDepthTex[ idx ]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //no mipmaps
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE/* GL_COMPARE_R_TO_TEXTURE*/);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

        glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, g_XMLSettings->WWidth(), g_XMLSettings->WHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);


        glBindTexture(GL_TEXTURE_2D, g_FBOManager.m_fboDepthTex[idx]);
        pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, g_FBOManager.m_fboDepthTex[idx], 0);

        glBindTexture(GL_TEXTURE_2D, g_FBOManager.m_fboTex[idx]);
        // attach a texture to FBO color attachment point
        pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_FBOManager.m_fboTex[idx], 0);


        // check FBO status
        pglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_FBOManager.FboId(i) );
        if(!CheckFramebufferStatus())
        {
            return false;
        }
    }

    BindFrameBuffer(-1);    // unbind fbo

    if (GLGETERROR("1", fileBuf, lineBuf)) ;    // check for glErrors

    return true;    // all ok
}


// code to init second set of textures before the render loop

    const int w = g_XMLSettings->WWidth();  //res: 768 square
    const int h = g_XMLSettings->WHeight();
    glGenTextures(bufCount, &ttex[0]);  
    for (int i=0; i<bufCount; ++i)
    {
        glBindTexture(GL_TEXTURE_2D, ttex[i]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    }

const int bufCount = 3;

void EnableTexture1()
{
    glActiveTextureARB(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, g_BackTexture);
    glUniform1iARB(g_pPassAShader->m_clr_idx, 0);
}

void RenderLoop()
{

    GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };

    glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);       
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glUseProgramObjectARB(g_pPassAShader->m_glContext);

    EnableTexture1();

    //... code omitted to set transform matrix and supply to shader


    if (!BindFrameBuffer(0))
        assert(0);

    const GLuint DTex = g_FBOManager.GetDepthTexture(0);

    glBindTexture(GL_TEXTURE_2D, DTex);
    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, DTex, 0);
    for (UINT i=0; i<bufCount; ++i)
    {
        glBindTexture(GL_TEXTURE_2D, g_FBOManager.GetTexture(i));
        pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, g_FBOManager.GetTexture(i), 0);
        if (!CheckFramebufferStatus())
            assert(0);
    }
    glDrawBuffers(bufCount,buffers); 
    // this is very important! if we don't clear it won't get written to
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    glDisable(GL_BLEND);

    EnableTexture1();

    RenderVertexCache(0);

    //... code omitted to set transform matrix and supply to shader

    // render the second quad to other FBO tex
    RenderVertexCache(0);

    DisableShader(0);
    BindFrameBuffer(-1);    // unbinds fbo

//pass 2
    if (!BindFrameBuffer(0))
        assert(0);

    // bind other set of textures to the fbo
    for (UINT i=0; i<bufCount; ++i)
    {
        glBindTexture(GL_TEXTURE_2D,ttex[i]);
        pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, ttex[i], 0);
        if (!CheckFramebufferStatus())
            assert(0);
    }
    glDrawBuffers(bufCount,buffers); 
    // this is very important! if we don't clear it won't get written to
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT  );
    // bind our set from prev pass to the samplers as input
    glUseProgramObjectARB(g_pPassBShader->m_glContext);

    for (UINT i=0; i<bufCount; ++i)
    {
        glActiveTextureARB(GL_TEXTURE0+i);
        glBindTexture(GL_TEXTURE_2D,g_FBOManager.GetTexture(i));
        glUniform1iARB(g_pPassBShader->m_intex_idx[i], i);
    }


    VertexBufferManager2::RenderUsingOrthoEx(g_pPassBShader);   // renders a full screen quad

    DisableShader(0);
    BindFrameBuffer(-1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// pass 3
    glUseProgramObjectARB(g_pPassCShader->m_glContext);
    for (UINT i=0; i<bufCount; ++i)
    {
        glActiveTextureARB(GL_TEXTURE0+i);
        glBindTexture(GL_TEXTURE_2D, ttex[i]);
        glUniform1iARB(g_pPassCShader->m_intex_idx[i], i);
    }

    VertexBufferManager2::RenderUsingOrthoEx(g_pPassCShader);



    if (GLGETERROR("at1", fileBuf, lineBuf)) ;  // reports any glErrors

}

// the three shaders (fragment shaders only)
// vertex shaders transfer uv's and transform vertices (version set to 410 in all)

// shader for pass1
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#version 410

uniform sampler2D   g_ClrMap;
in vec2         g_InterpUV;     // supplied by vshader
out vec4        g_FBOLayers[ 3 ];

void main(void)
{   
    vec4 tex = texture(g_ClrMap, g_InterpUV);   // if we set fbo from texture only first texture renders
    g_FBOLayers[0] = vec4(1,0,0,.5);
    g_FBOLayers[1] = vec4(0,1,0,1);
    g_FBOLayers[2] = vec4(1,1,0,1);
}


// shader pass 2
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#version 410

uniform sampler2D   g_inLayers0;
uniform sampler2D   g_inLayers1;
uniform sampler2D   g_inLayers2;
in vec2         g_InterpUV ;
out vec4        g_FBOLayers[ 3 ];
vec2            fTextureSize;

vec4 SamplePix(in int buf, in vec2 tCoords, in float lod)
{
    if (buf==1)
        return textureLod(g_inLayers1, tCoords, lod);
    else if (buf==2)
        return textureLod(g_inLayers2, tCoords, lod);
    return textureLod(g_inLayers0, tCoords, lod);
}

void main(void)
{   
    ivec2 iCoords = ivec2(int(gl_FragCoord.x),int(gl_FragCoord.y));
    ivec2 iTextureSize = textureSize(g_inLayers0,0);
    fTextureSize = vec2(float(iTextureSize.x), float(iTextureSize.y));
    vec2 coords = vec2(gl_FragCoord.x/iTextureSize.x,gl_FragCoord.y/iTextureSize.y);

    for(int i=0; i<3; ++i)
    {
        g_FBOLayers[i] = vec4(0.,0.,0.,0.); 
    }
    int j = 0;
    for(; j < 2; ++j)
    {
        g_FBOLayers[j] = SamplePix(j,coords,0); 

    }

}

// shader pass 3    
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#version 410

uniform sampler2D   g_inLayers0;
uniform sampler2D   g_inLayers1;
uniform sampler2D   g_inLayers2;
in vec2         g_InterpUV ;
out vec4        g_PixColour;

vec4 tFetch(in int buf, in ivec2 tCoords, in int lod)
{
    if (buf==1)
        return texelFetch(g_inLayers1, tCoords, lod);
    if (buf==2)
        return texelFetch(g_inLayers2, tCoords, lod);

    return texelFetch(g_inLayers0, tCoords, lod);
}

void main(void)
{   
    ivec2 iCoords = ivec2(int(gl_FragCoord.x),int(gl_FragCoord.y));
    ivec2 iTextureSize = textureSize(g_inLayers0,0);
    vec2 coords = vec2(gl_FragCoord.x/iTextureSize.x,gl_FragCoord.y/iTextureSize.y);

    vec4 colour =  vec4(0.,0.,0.,0.);
    int i = 0;
    for(; i <2; ++i) // 3rd texture omitted for now
    {
        vec4 texel = tFetch(i,iCoords,0);
        if(texel.a + colour.a <= 1.0)
        {
            colour.rgb += (texel.rgb*texel.a);
            colour.a += texel.a;

        }
        else
        {
            texel.a -= (texel.a + colour.a) - 1.0;
            colour.rgb += (texel.rgb*texel.a);
            colour.a += texel.a;    
            break;      
        }

    }

    g_PixColour = colour;

}
4

0 に答える 0