Advertisement

Removing one "instance" in a sequence of instanced objects

Started by April 25, 2018 10:18 AM
2 comments, last by swiftcoder 6 years, 9 months ago

Hey, I am semi-new to 3d-programming and I've hit a snag. I have one object, let's call it Object A. This object has a long int array of 3d xyz-positions stored in it's vbo as an instanced attribute. I am using these numbers to instance object A a couple of thousand times. So far so good. 

Now I've hit a point where I want to remove one of these instances of object A while the game is running, but I'm not quite sure how to go about it. At first my thought was to update the instanced attribute of Object A and change the positions to some dummy number that I could catch in the vertex shader and then decide there whether to draw the instance of Object A or not, but I think that would be expensive to do while the game is running, considering that it might have to be done several times every frame in some cases. 

I'm not sure how to proceed, anyone have any tips?

2 hours ago, Achivai said:

At first my thought was to update the instanced attribute of Object A and change the positions to some dummy number that I could catch in the vertex shader and then decide there whether to draw the instance of Object A or not

That idea doesn't work very well for vertex shaders because it still need to spawn all those vertex shaders that will just be culled anyway. This is a way to introduce vertex bottleneck.

What you could do is assemble your instance buffer dynamically. These are two separate ways to do it:

  • For every mesh, you allocate an instance buffer large enough to hold all matrices and fill those before the draw, then draw.
  • For every mesh, you have all the instance matrices statically every time in a buffer. You can also have an "instance index buffer". Before the draw happens, you would only allocate the instance index buffer (which is a lot less data than allocating a matrix array) and fill them. This way the shader would have an indirection lookup of the instance index buffer first and that indexes inside the matrix array which you only filled once.

For allocation I mention here, I like to use a ring buffer and linearly allocate from it. This ensures that allocation is happening at constant time, the perf hit will be the amount of data that you are copying into it. It is essential if you are doing allocation in the middle of the render loop.

Advertisement

The order of instanced objects shouldn't be all that important, so you can just do a swap-delete (swap the item to be deleted with the last item, and then render one less item next frame).

Since you don't care about the removed item, that boils down to overwriting the removed item with the last item in the buffer, and reducing the instance count by one.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement