Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: Layered rendering

  1. #1
    Junior Member Newbie
    Join Date
    May 2015
    Posts
    12

    Post Layered rendering

    Hello everyone, I'm beginner in OpenGL and I have a little problem that I can't solve ! (I'm sorry for my english i'm french x) )

    I can't make a layered rendering work. I would like to capture different layers from the scene compared to the depth of the scene. I would like tohave different textures from the scene at specific depths in order to apply different Blur effect at each layers.

    I use a geometry shader with gl_Layer.

    This is my function who create a Texture 2D Array:

    Code :
    void Texture::initGLTexture2DArray(int bytesperpixel, int width, int height, int layerCount) {
        glAssert(glGenTextures(1, &mTexId));
        glAssert(glActiveTexture(GL_TEXTURE0));
        glAssert(glBindTexture(GL_TEXTURE_2D_ARRAY, mTexId));
        glAssert(glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, bytesperpixel, width, height, layerCount, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL));
        glAssert(glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
        glAssert(glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
        glAssert(glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE));
        glAssert(glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE));
    }

    And I tried to this two functions to add the array at my framebuffer:

    Code :
    void FBO::attachTextureArray(GLenum attachment, Texture *texture) {
        glAssert(glFramebufferTexture(GL_FRAMEBUFFER, attachment, texture->getId(), 0));
    }
    // Using it like this
        fboLayered_->attachTextureArray(GL_COLOR_ATTACHMENT0, textureLayered);
     
     
    void FBO::attachTextureArray2(GLenum attachment, Texture *texture, GLuint layer) {
        glAssert(glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture->getId(), 0, layer));
    // Using it like this
        fboLayered_->attachTextureArray2(GL_COLOR_ATTACHMENT0, textureLayered, 0);
        fboLayered_->attachTextureArray2(GL_COLOR_ATTACHMENT1, textureLayered, 1);
    }

    And this is my render loop:

    Code :
    glm::mat4 modelViewMatrix = camera_->getModelViewMatrix();
        glm::mat4 projectionMatrix = camera_->getProjectionMatrix();
     
        //
        // Important note before modifying this method :
        // see MyRenderer::setViewport for FBO configurations
        //
        glm::mat4x4 viewToWorldMatrix = glm::inverse(modelViewMatrix);
     
        // draw the scene
     
        fboLayered_->useAsTarget(width_, height_);
        glAssert(glDrawBuffers(1, bufs));
        glAssert(glClearColor(0.1, 0.1, 0.1, 1.));
        glAssert(glClearDepth(1.0));
        glAssert(glDepthFunc(GL_LESS));
        glAssert(glDisable(GL_BLEND));
     
        fboLayered_->clear(FBO::ALL);// to clear all attached texture
     
        // render ambient and normal
        ambientPass(ambientAndNormalLoop_, modelViewMatrix, projectionMatrix, viewToWorldMatrix);
     
        // setup per light rendering : blend each pass onto the previous one
        glAssert(glDrawBuffers(1, bufs));
        glAssert(glDepthFunc(GL_LEQUAL));
        glAssert(glEnable(GL_BLEND));
        glAssert(glBlendFunc(GL_ONE, GL_ONE));
        glAssert(glDepthMask(GL_FALSE));
     
        // render for each light
        lightsPass(mainDrawLoop_, modelViewMatrix, projectionMatrix, viewToWorldMatrix);
     
        // restore parameter
        glAssert( glDisable(GL_BLEND) );
        glAssert( glDepthFunc(GL_LESS) );
        glAssert( glDepthMask(GL_TRUE) );
     
        std::cout << gpuTimers_ << std::endl;
     
    }

    Just a last thing the FBOs configuration. I've 2 FBO one to render a "normal" mode and the other to obtain what I would like to.

    Code :
    void MyRenderer::setViewport(int width, int height)
    {
        width_ = width;
        height_ = height;
     
        camera_->setScreenWidthAndHeight(width_, height_);
        //Renderer::setViewport(width, height);
     
        fbo_->setSize(width_, height_);
     
        if (textures_[DEPTH_TEXTURE]->getId() != 0)
            textures_[DEPTH_TEXTURE]->deleteGL();
        textures_[DEPTH_TEXTURE]->initGL(GL_DEPTH_COMPONENT24, width_, height_, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
        if (textures_[NORMAL_TEXTURE]->getId() != 0)
            textures_[NORMAL_TEXTURE]->deleteGL();
        if (textures_[COLOR_TEXTURE]->getId() != 0)
            textures_[COLOR_TEXTURE]->deleteGL();
     
        if (textureLayered->getId() != 0)
            textureLayered->deleteGL();
     
        textures_[NORMAL_TEXTURE]->initGL(GL_RGBA32F, width_, height_, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        textures_[COLOR_TEXTURE]->initGL(GL_RGBA32F, width_, height_, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     
        // Init Texture 2D Array
        textureLayered->initGLTexture2DArray(GL_RGB32F, width, height, 2);
     
        fbo_->bind();
        fbo_->attachTexture(GL_COLOR_ATTACHMENT0, textures_[COLOR_TEXTURE]);
        fbo_->attachTexture(GL_COLOR_ATTACHMENT1, textures_[NORMAL_TEXTURE]);
        fbo_->attachTexture(GL_DEPTH_ATTACHMENT, textures_[DEPTH_TEXTURE]);
        fbo_->check();
        fbo_->unbind();
     
        fboLayered_->setSize(width, height);
        fboLayered_->bind();
        fboLayered_->attachTextureArray(GL_COLOR_ATTACHMENT0, textureLayered);
        fboLayered_->check();
        fboLayered_->unbind();
     
        FBO::bindDefault();
        glAssert (glDrawBuffer(GL_BACK); );
        glAssert (glReadBuffer(GL_BACK); );
    }

    I am using a 3D engine given by my professor so I don't really know if you have enought information to see where my problem come from. I'm blocked for severals day I tried everything I found on different forum... :/.

    And this is my shaders: dofambientfrag.txt
    dofambientgeom.txt
    dofambientvert.txt
    dofphongfrag.txt
    dofphonggeom.txt

    Thank you for your help!

    Brioche

  2. #2
    Junior Member Newbie
    Join Date
    May 2015
    Posts
    12
    I think I found the solution. Everything works well but it's when i'm drawing the texture. I tried with my normal fbo and it works well but it is not layer rendering, so I think to draw it I have to draw layer by layer but I didn't find how to do it.
    Can someone explain me how can I draw my result which is the texture 2D array stored in my layered framebuffer layer by layer, or just draw the layer I want to draw?

    Thank you in advance for your help!

  3. #3
    Junior Member Newbie
    Join Date
    May 2015
    Posts
    12
    up?

    I just would like to know how to render only one layer from my layered texture (I'm a pure beginner ) x)

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,105
    Quote Originally Posted by brioche View Post
    I just would like to know how to render only one layer from my layered texture
    You can use glFramebufferTextureLayer() to attach a single layer of a layered texture (e.g. a 2D array texture) to a framebuffer. The result is a non-layered framebuffer (i.e. setting gl_Layer has no effect).

    If you use glFramebufferTexture() with a 2D array texture, the framebuffer will be layered, and the layer is specified by writing to gl_Layer in the geometry shader. If no geometry shader is present or it doesn't write to gl_Layer, rendering will use layer zero.

  5. #5
    Junior Member Newbie
    Join Date
    May 2015
    Posts
    12
    Thank you for your answer but I did the second way with geometry shader. But my layered texture is in my layered FBO. Now I would like to draw it on my display using a new shader program to apply for example a blur effect, but I won't draw all the layers but just one layer on by one. My goal is to draw all the layers, layer by layer unsing shader programs with different Blur effect on each layer.
    Isn't there a way to just get the first layer of my layered texture and draw it on the screen with a new shader program?

  6. #6
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,105
    Quote Originally Posted by brioche View Post
    Thank you for your answer but I did the second way with geometry shader. But my layered texture is in my layered FBO. Now I would like to draw it on my display using a new shader program to apply for example a blur effect, but I won't draw all the layers but just one layer on by one. My goal is to draw all the layers, layer by layer unsing shader programs with different Blur effect on each layer.
    Isn't there a way to just get the first layer of my layered texture and draw it on the screen with a new shader program?
    To use it as a source, bind the texture with glBindTexture(GL_TEXTURE_2D_ARRAY), then access it in the fragment shader via a sampler2DArray uniform variable. The texture() overload for a sampler2DArray takes a vec3 as its second argument, where the third component is rounded to the nearest integer to obtain the layer.

    Alternatively, if you're assuming OpenGL 4.3 or later, you can use glTextureView to create a texture view which treats a single layer of a 2D array texture as a 2D texture. The view can then be bound to a texture unit and accessed via a sampler2D uniform variable in the shader.

  7. #7
    Senior Member Regular Contributor
    Join Date
    Mar 2015
    Posts
    296
    mark it.
    which is the texture 2D array stored in my layered framebuffer layer by layer, or just draw the layer I want to draw?
    I have just had a suggestion. if you store your texture layered, you must have an ID for each texture. then you may render the relative id for each layer. I don't know if it is right.

  8. #8
    Senior Member Regular Contributor
    Join Date
    Mar 2015
    Posts
    296
    GClements has replied. his will be right. mine can be ignore.

  9. #9
    Junior Member Newbie
    Join Date
    May 2015
    Posts
    12
    Thank you for your help I will try it and keep you aware of the result

    Thanks !

  10. #10
    Junior Member Newbie
    Join Date
    May 2015
    Posts
    12
    It works thanks !

    But i have a little problem, as I told you I have all my textures which is different parts of the scene at different depth intervals. I would like to apply different leve of Blur effect on each layers. I though I could make different shaders with different Blur effect and draw the first layer and the the second and .... And it will render all the scene with different Blur effect. But I only have the last layer drawn.

    Is there a way to draw without erasing the layers drawn before and just replace it if the layer is nearer than the other? Or can I do it with only one shader which could be able to select the right layer to draw?

    I'm really sorry I just began opengl some weeks ago and I would like to finish it for today x).

    Thank you for you help again

Page 1 of 3 123 LastLast

Similar Threads

  1. Layered rendering FBO
    By someRand in forum OpenGL: Advanced Coding
    Replies: 2
    Last Post: 06-03-2018, 06:49 PM
  2. Learning Layered Rendering
    By hailin in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 06-16-2017, 12:28 AM
  3. Layered Rendering with Renderbuffers
    By Admiral Habor in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 12-24-2015, 07:52 AM
  4. Layered rendering
    By imported_Groovounet in forum OpenGL: Advanced Coding
    Replies: 14
    Last Post: 08-23-2010, 04:10 AM
  5. layered rendering
    By fpoletti in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 04-20-2009, 03:39 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean