Need help to optimize Draw cost

i propose a trick
split your objs to batches, group by vertices [ex… 4-100, 100-200, 200-300]
in each batch fill your objs vertex to bigest [yes, it waste but consider your 30k vertices then not that hurt]
render batch use indexbuffer [ignore those trash vertexes above]
use vertexid in shader to get object id [ex id = vertexid%groupbigestvertexnum]
for transparent, since you use orthographics then pull your obj to camera by very small amount based on id and batch, it mean obj that draw later will get closer to camera than ealier [add depth split layer here if needed]
done…

but with lots of transparency it will kill fillrate anyway

I can try. All game objects are derived from abstract base class Entity (simplified version below) :

public abstract class Entity
{
    public Vector2 Size { get; }
    public Vector2 Center { get; }
    public float Angle  { get; }
    public float Depth { get; }
    public Vector2 Scale { get; }
    public float Alpha { get; }
    public Entity HookedOn { get; }
    public Vector2 HookOffset { get; }

    public virtual void Update()
    {
    }

    public virtual void Draw(DrawBatch drawBatch)
    {
    }
}

HookedOn and HookOffset work like this : if Entity2 is hooked to Entity1 (Entity2.HookedOn == Entity1), then
its position should be Entity1.Center + Entity2.HookedOn + Entity2.Center (kind of a Parent/Child relationship).
Then I also have VertexEntity, which is derived from Entity and define some geometry (Vector2[] for vertices and short[] for indices). VertexEntity is overriding Draw to submit its geometry to the graphic card (for now it’s a call to a DrawBatch which will do the sort-by-depth-then-draw-vertices when every object has been batched).
By composing Entities, I can build my game scene. But it seems like it’s not performing well, hence this topic :slight_smile: I’m trying to find a generic way to make this kind of architecture working as fast as possible (when not working with tons of game objects or vertices).

Yeah, I can do that, but the problem of depth sorting can still happen on a single slice, and I have way too many layers to go for 1 layer = 1 slice. I would prefer a “cleaner” solution :sweat_smile:

Yeah, I thought doing that : instead of sorting vertices, just sorting indexes while keeping the same vertex buffer. It will still need to update the IndexBuffer on every draw call, which maybe will have a significant impact on performance, but since it’s an array of short in my case, it might be acceptable. I will try to dig deeper into this approach, thanks for the suggestion !

I didn’t understand everything on what you’re suggesting :sweat_smile:, but I will take a closer look at it if needed, thank you !

After some research and trial-and-error, it seems like fetching texture from vertex shader is not supported by Monogame on OpenGL (and therefore not working on Android). Is there any other way to pass a large amount of data to a shader ? I can’t seem to find an other way to do so…

If you can’t use hardware instancing or VTF, shader parameters are your only option.
I don’t see why the constant limit is such a big problem for you. I understand that having to start a new batch after running out of parameter space is a bit inconvenient, but it’s not the end of the world either.

No, sure, it’s not the end of the world, but before going for that route, I wanted to be sure there is no more convenient way to achieve what I want :slight_smile: