I started implementing instanced rendering in my 3D engine, but I quickly stumbled upon some issues that I'm not sure whats the best practice to work around.
When I setup my scene, I capture the amount of instances for every mesh and I write the transformation matrices first into a dynamic list and finally into an "instance buffer" (UBO) which is sent to the shaders and indexed by gl_InstanceID
to fetch the correct transform. This is working perfectly.
So when I apply frustum culling per instance, what I do now is that once I found out that an instance should be culled, I remove this transformation matrix from the dynamic list and therefore I keep the transformation matrices of just the active instances which end up getting drawn from the glDrawElementsInstanced
.
Obviously inserting and removing elements from this dynamic list is expensive and I want to get rid of it. So I was thinking that I'll implement a fixed length list this time consisting of per-instance structs to hold instance data something like this:
struct InstanceData {
float worldMatrix[16];
bool isOccluded;
/* and more */
};
However this leads to another problem. In this case, since the draw call will render a fixed amount of instances all the time, regardless if they are visible or not, I'll have to discard the vertices in the shader, and I don't think that this is optimal either.
I've thought of other ways as well, such as sorting the instances based on their occlusion status on every frame, but then I'll have to pay the price for the sorting.
Is there any common practice to deal with instanced data? I fear that I should experiment with all the options and find what suits me best x.x
Thanks in advance