Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 14

Thread: subroutines and multiple render targets

Hybrid View

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    24

    subroutines and multiple render targets

    I wonder how to use a shader with subroutines and multiple render targets. I have a fragment shader which contains a few subroutines. (I posted only relevant pieces of the code).

    Code :
    #version 420
     
    in vec3 data1;
    in vec3 data2;
     
    layout (location = 0) out vec4 fragColor;
    layout (location = 1) out vec3 target1;
    layout (location = 2) out vec3 target2;
     
     
    subroutine void RenderPassType();
    subroutine uniform RenderPassType RenderPass;
     
    subroutine (RenderPassType)
    void first()
    {
     
    }
     
    subroutine (RenderPassType)
    void second()
    {
    	target1 = data1;
    	target2 = data2;
    }
     
    subroutine (RenderPassType)
    void third()
    {
    	//some computations
    	fragColor = result
    }

    I created two fbo's which contain rendering targets (textures).

    First:
    Code :
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
    Second:
    Code :
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex2, 0);

    A data for glDrawBuffers:
    Code :
    GLenum drawBuffers1[] = {GL_NONE, GL_NONE, GL_NONE,);
    GLenum drawBuffers2[] = {GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1);

    Rendering:

    Code :
    //bind the first fbo
    //bind the first subroutine
    glDrawBuffers(3, drawBuffers1);
    ...
    //unbind the first fbo
     
     
    //bind the second fbo 
    //bind the second subroutine
    glDrawBuffers(3, drawBuffers2);
    ...
    //unbind the second fbo
     
    ...

    The above code works, but I wonder if it is the only right way to use subroutines together
    with multiple render targets. Is something which I can do better (more efficient) ?

    Do I have to use (location = 0) for the default framebuffer output ?

    When I first bind the second fbo and subroutine and next the first fbo and subroutine glDrawBuffers
    clears all textures. What can I do about it ?

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    985
    If you have multiple color outputs then you have to write a value to all of them, otherwise the ones that you don't write any value to become undefined.
    Think about it this way: if you don't output any color to a particular color output, a write to that color output still will happen, just an implementation dependent value value may be written there.
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

  3. #3
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    24
    Ok, but I want to use my fragment shader with subroutines for a deferred rendernig. Then a render loop looks like this:

    1. gbuffer stage
    2 for each light:
    (additive blending)
    - shadow map stage
    - shading stage

    The first subroutine destroys render targets(GL_NONE). How to solve it ?

  4. #4
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    985
    First, why would you like to use the same shader for all of these? I think it's fine if you switch shaders 3 times in a frame. You try to be overzealous on batching things together.

    In fact, for the shadow map rendering stage you don't even need a fragment shader, thus if you have one, that will actually cost you a lot in performance.
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

  5. #5
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    In fact, for the shadow map rendering stage you don't even need a fragment shader, thus if you have one, that will actually cost you a lot in performance.
    Not unless you're using a compatibility profile.

    Quote Originally Posted by OpenGL 4.3 core specification, Ch 15:
    If the current fragment stage program object has no fragment shader, or no fragment program object is current for the fragment stage, the results of fragment shader execution are undefined.
    The fragment depth is part of the results of fragment shader execution. And thus it is undefined. And having an empty fragment shader doesn't lose you any performance.

  6. #6
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    985
    Quote Originally Posted by Alfonse Reinheart View Post
    If the current fragment stage program object has no fragment shader, or no fragment program object is current for the fragment stage, the results of fragment shader execution are undefined.
    Exactly, fragment shader execution is undefined, but per-fragment operations are not, thus depth testing and depth writing IS defined.

    You don't need a fragment shader for depth-only rendering, not even in core profile.

    Quote Originally Posted by Alfonse Reinheart View Post
    The fragment depth is part of the results of fragment shader execution. And thus it is undefined. And having an empty fragment shader doesn't lose you any performance.
    The fragment depth output by a fragment shader is, of course, makes no sense without a fragment shader, but you don't need a fragment shader to output a depth, you have a fixed function one.

    Also, having an empty fragment shader DOES cost your performance. Depth testing and depth write is done by fixed function hardware which can have a throughput of many pixels per clock, especially with hierarchical Z, not to mention that no shader cores are needed to be used. While if you have a fragment shader you'll have to launch shaders on your shader engines and even if they do nothing, it will still cost you several clocks per tile (unless the driver is smart enough to just ignore your empty fragment shader in which case you'll get the same results).
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •