zeb
zeb

Reputation: 1125

Efficiently update Uniform Buffer Objects with instancing and culling

I've successfully updated my rendering engine to use uniform buffer objects and instancing. The problem is that, since I do a first frustum culling pass every frame in order to know the objects I need to draw, I have to update the buffers every frame because the objects I draw could change every time, and this isn't the most efficient thing.

How could I make this more efficient?

The only thing I could think of is to not do the frustum culling so all the buffers remain static and I don't need to update them all the times, but not doing frustum culling I'd end up draw a lot of unnecessary objects.

Upvotes: 3

Views: 1570

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43369

Updating uniform buffers is fairly cheap, to be honest. You are quite limited in size and that prevents you from doing anything too crazy.

What you need to focus on to make this efficient is actually accommodating incomplete commands that are queued up. You are more likely to run into problems where the driver/GPU is forced to stop working on the next frame/command due to poor data write patterns than you are to run into data transfer rate limitations. The problem is always going to be avoiding situations where you might write to portions of data that are still in use by the GPU (it is often working on data 1-2 frames behind the CPU).

You have multiple options depending on your target version, and the OpenGL Wiki has a general overview of buffer streaming approaches.


You will have to do some performance testing to say for sure, but I suspect that CPU-side frustum culling combined with buffer orphaning of your instance UBO will give good results. Rather than reusing any data from previous frames, you would just stream the entire instance UBO from CPU to GPU each frame and let the GPU discard the old UBO when it finishes each frame.

Upvotes: 2

Related Questions