Strange issue with multi-pass, multi RT RT in GLSL

I see a strange problem with the multi-pass ping-pong multi-RT renderer

I use 3 shaders and FBO, I do not get errors at any stage. I use opengl 4, so I do not use glBegin / glEnd, I use my own matrices for conversion, and I use vertex buffers for rendering

The general idea of ​​this test is to display three different colors for three separate fbo attachments (I understand that this is not an efficient rendering of vbo twice in the first pass, but this is only to help me understand the problem in some other source) Then I associate a separate texture set with fbo and use the first set as samplers. The final run consists in mixing the results in a reverse buffer

It is odd that both squares appear red when the first one should be red and the second green (since these values ​​come from the second shader).

If I change the SamplePix function in the second shader to always take from the second sampler, both look green, and if the search comes from the third, then everything looks yellow, but it seems to only be read from it.

At the moment, I can’t explain why I can read from each sampler, but the loop doesn’t seem to look right (in shader 2)

Also, if I switch to rendering the texture selected in shader 2, I see a black square in the second pass (image 2)

Hope someone can shed some light on the problem. (I also tried to add an object with synchronization after the first pass, but this did not affect)

red

Texture example:

tex

// 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 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
source share

Source: https://habr.com/ru/post/1438306/


All Articles