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 8 of 8

Thread: VBO + octree + shaders ?

  1. #1
    Intern Contributor
    Join Date
    Oct 2005
    Location
    Belgium, Liège
    Posts
    70

    VBO + octree + shaders ?

    Hello all!

    I'm can't figure out how to sort this problem out.

    > I have to use an frustum-culled octree structure to render my geometry, BUT I have to use vertex arrays or VBO's (of course). How should I store data to make this possible and efficient?

    > I'm using several shaders to render my scene. I don't want to perform unneeded switches as it's killing performance. Right now I'm storing data according to the shader to use, and render all faces of one specific shader at the same time; and so on for all shaders. How could I combine my shaders with the octree and VBO?

    Thanks a lot for your help, it'll be greatly appreciated!

    HT
    Don't tell me what's in, tell me how to write
    Don't tell me how to win this fight
    Isn't your life, it isn't your right to take the only thing that's
    Mine

  2. #2
    Junior Member Regular Contributor
    Join Date
    Feb 2001
    Posts
    134

    Re: VBO + octree + shaders ?

    For storing data, it usually depends on the size of the scene. If its a small scene (around 60k triangles), I believe a single VBO batch is good enough. You can bind the scene VBO before starting the drawing of any node. If you have a bigger scene, you can break the VBOS per octree leaf node and when you are about to draw a leaf node, first bind its VBO and then draw. So you will have geometery and associated VBO per leaf node.

    For the shading tree, you can have a shader list per octree node. Each shader object of the list should have a texture/material list. Each object of the material list should have a list of faces (for the node that use the material).

    So efectively you will
    - Frustum cull your octree nodes
    - Sort your visible nodes front to back
    - Bind the VBO of the current leaf node
    - For each shader in the leaf node shaderlist, bind the shader
    - For each material in the shader material list, bind the material
    - glDrawElement... for drawing the faces of the leaf node using this material

    Hope you get the idea.

    Fastian

  3. #3
    Intern Contributor
    Join Date
    Oct 2005
    Location
    Belgium, Liège
    Posts
    70

    Re: VBO + octree + shaders ?

    Hi, thanks for your feedback

    I get the idea but I'm still concerned about the frequent shader switch:

    ---------------------
    for each node
    bind VBO
    for each shader
    glDrawElement(faces using this shader)
    end for
    end for
    ---------------------

    It means if I have, say, 6 shaders and 25 visible nodes, I'll have to switch my active shader 150 times per frame, which is not acceptable.

    I think I'll have to do this: one VBO per leaf AND per shader type, then loop through my octree and find what to render, and put what to render in a sorted batch list:

    ---------------------
    for each node
    for each shader
    add VBO ref to list
    end for
    end for

    sort list by shader

    for each list item
    bind list item VBO
    glDrawElements(list item)
    end for
    ---------------------

    Do you find this acceptable?

    HT
    Don't tell me what's in, tell me how to write
    Don't tell me how to win this fight
    Isn't your life, it isn't your right to take the only thing that's
    Mine

  4. #4
    Junior Member Regular Contributor
    Join Date
    Feb 2001
    Posts
    134

    Re: VBO + octree + shaders ?

    hmmm... Again that actually depends on your geometry type. If your node size is reasonably big and you have an indoor scene, you probably won't be rendering more than 2-3 visible nodes per frame (as the rest will be occluded). The shader switch for these would be limited and you won't need to switch so many VBOs per frame. Again depending on the size of data, if some of the VBOs are in system memory, switching between them could cause a major stall.

    Maybe I am not getting what you are trying to do here. Do you mean you sort everything based on shader, then sort everything based on distance. If that is the case, that is OK as long as there is no issue of VBO data coming from system memory.

  5. #5
    Intern Contributor
    Join Date
    Oct 2005
    Location
    Belgium, Liège
    Posts
    70

    Re: VBO + octree + shaders ?

    As you said, it depends on the geometry type. I'm intending to render a large outdoor scene.

    The guess now is to know what's worst: frequent shader change OR frequent VBO binding... I think I'll have to test different node sizes for the octree.

    HT
    Don't tell me what's in, tell me how to write
    Don't tell me how to win this fight
    Isn't your life, it isn't your right to take the only thing that's
    Mine

  6. #6
    Advanced Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    872

    Re: VBO + octree + shaders ?

    try this...
    1. create materials (shaders) list. each shader should have array of batches
    2. create octree. each node should have list of batches sorted by material ID
    Code :
    batch 0: material_ID, primitive type, start index,  count
    batch 1: material_ID, primitive type, start index, count
    batch 2: material_ID, primitive type, start index, count
    ...
    3. create one big vertex VBO (holding 1M vertices in VBO is not problem on todays hw)
    4. create VBO with all triangles sorted by nodes and sorted by batches...
    node 0(b0,b1,b2..)
    node 1(b0,b1,b2,...)

    Rendering:
    1. frustum cull your octree nodes
    2. for each visible node notify materials with batches in node, based on material ID in batch
    3. for each notifyed material, enable it's shaders and render batches (you can use glMultiDrawElements)

    To speedup rendering:
    1. render zfill
    2. render axis aligned bbox (from nodes) with occlusion queries.
    3. remove occluded nodes from list of visible nodes

    If you need to spread dataset on several VBO's you can add VBO id in each node in each batch. Materials should have separate list if batches for each VBO id.
    Now... you have bunch of materials and few VBO's. So.. render loop can be:
    Code :
    for each VBO_ID in VBO set
    {
     bind VBO(VBO_ID) & pointers
     for each material in materials set 
        render batches(VBO_ID)
    }
     
    or 
     
    for each material in materials set 
    {
      for each VBO_ID in VBO set
      {
         bind VBO(VBO_ID) & pointers
         render batches(VBO_ID)
      }
    }
    One of this two render loops are faster... you have to test it...

    yooyo

  7. #7
    Intern Contributor
    Join Date
    Oct 2005
    Location
    Belgium, Liège
    Posts
    70

    Re: VBO + octree + shaders ?

    So you mean, using this technique, that I have to notify all visible material with batches, then AFTER each material visibility has been processed, I loop through all materials (preferabily sorted I guess) and only switch once per material type? I think that's what I understood.

    > in each octree node: shader (material) list with faces (batch referencing big VBO)
    > frustum cull and everything
    > put each visible face into render-list (sorted by shader/material)
    > draw render-list

    I think this should minimize VBO binding and shader change. Further feedback will greatly be appreciated

    HT
    Don't tell me what's in, tell me how to write
    Don't tell me how to win this fight
    Isn't your life, it isn't your right to take the only thing that's
    Mine

  8. #8
    Advanced Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    872

    Re: VBO + octree + shaders ?

    Yes.. To clarify few things... You will have a bunch of materials. In some frame, only some materials will be used. This materials will be notify by octree frustum culling.

    Take a look in glMultiDrawElements spec to figure how to send several batches to render using single draw call.

    My suggestion is to create array of pairs (uint offset, int count) in each material. When engine notify material, it will simple add new batch (new pair) in array.

    yooyo

Posting Permissions

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