Bindless gbuffer linked list per pixel

this is more of a general discussion about an advanced opengl concept…
I was checking out nvidias nsight profiling tutorial and about 3 minutes in he quickly breaks down the concept of a bindless gbuffer using a linked list per-pixel structure system… automatically… my mind is blown.
I start looking up everything I can about the subject… there was only one article that came to mind about bindless gbuffer and it only utilized bindless textures to be looked up in the final stage using uv. That’s cool, but not exactly what one’s imagination is hoping for when thinking about bindless deffered pipelines…

But this system looks to be a further building onto Order Independent Transparancy.
I found some excellent code from gangliao that shows some really beautiful concepts on its own… the main idea seems that instead of multiple render target “layers”… you use a complex data structure per-pixel, sort the order based on depth, and then render yer little heart out.
Some other fun stuff in gangliao’s fragment shader

layout (early_fragment_tests) in;

I’ve been meaning to check “early_fragment_tests” out… but as I’ve personally been playing a lot with raymarching on full screen quads, things get tricky with how to use this in my pipeline, the need for it in this shader has me curious… if I get this right, it’s a really fancy feedback shader… notice the use of subroutines, which I love to use btw.
If I understand this right, gangliao made a fancy feedback system shader that changes its functionality via subroutines but maintains the data bindings via structure buffer…

struct NodeType {
  vec4 color;
  float depth;
  uint next;
};

it fills the structure buffer using atomicCounterIncrement and imageAtomicExchange and keeps the “tree” via uint next.

pass 1 fills the buffer, pass 2 sorts and renders…

The nsight video presents using this technique as a true gbuffer system using modern opengl bindless, which I’ve been infatuated with lately… their description of the “Node” looks something like this…

struct GBufferNode{
    vec3 eyePosition;
    float alpha;
    vec3 eyeNormal;
    uint material;
    vec2 uv;
    GBufferNode *pNext;
};

Besides the obvious amount of more data needed for a gbuffer, I noticed that a big difference is the last variables… uint next; vs… GBufferNode *pNext;
Isn’t this the bindless technique what allows us to recycle the bound data in separate shaders for the next passes? They describe their method ass a 3 pass system…
pass 1 generate and collect per fragment
pass 2 sort by depth
pass 3 shade and composite
I’ve been looking at various complex deffered pipelines but I’m really enjoying the concept of this. And transparancies are included… big perk in my book. Anyone else think this is pretty neat? Thoughts? Can’t wait to try this out in Cinder.

Hi @Malfunkn,

I actually have ported gangliao’s demo to cinder 2 years ago, I made this repo public in case you need it: https://github.com/philcn/OrderIndependentTransparency

I haven’t looked into the bindless GBuffer approach, however I think this one (using SSBO and atomics) is very straightforward to implement, allows more flexible payload which can potentially save some bandwidth, but suffers from atomics contention. His use of subroutines is probably just a way to combine two frag shaders into one, you can totally code them separately without using subroutines.

2 Likes

No f$&#%@ way… you’re awesome. definitely going to scope this out… cheers!