Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: VertexArray vs Instancing questions for 2D isometric project [SOLVED]  (Read 1024 times)

0 Members and 1 Guest are viewing this topic.

Ray1184

  • Newbie
  • *
  • Posts: 7
    • View Profile
Hello everyone,
I was not sure whether to post a new topic here or in the apposit graphics session, but is a more logical issue then technical.
I'm developing my own engine for a 2D isometric game.
In the game I've 2 layers for rendering

- first layer is static (like floor, walls etc...), there's no interaction and no depth sorting needed. So it will be a simple VertexArray, with inside all tiles positions and texCoords
- second layer is interactive and will contains movable and all type of objects that can change drawing order based on their positions.

My doubts incur with second layer. My idea was to use sprites instead of VertexArray, because in this case I can create mores instance with the same sprite and different transformations. But in my case this is not so simple, because many of my objects are not a single image, but a chunk of tiles (base tile is 16x16px). Here the problem comes with depth sorting. Using a VertexArray allows me to sort all tiles render order and push all vertices inside the VertexArray without groing crazy (and I don't even have to think about how to solve the depth sorting problem for convex figures), but unfortunately I cannot do instancing. If I need to render 100 trees for example, I need to push 100xN vertices inside the array, instead of using one with 100 different transformations.

In a nutshell:

Using VertexArray for all interactive objects and actors (even player and npcs)

PROS:
  • depth management is much simpler
  • only 1 draw call

CONS:
  • For each instance of my abstract entity, I need to upload vertices and texCoords to GPU

Using chunk of sprites (or small VertexArrays) for each interactive objects and actors (even player and npcs)

PROS:
  • I can upload only one sprite/va per instance and using transformations

CONS:
  • more difficult to determine whether a VertexArray must be rendererd before or after another one
  • objects with convex shapes must be "sliced" in simpler objects

From this consideration I'm more likely for the first solution, but I don't want to overload the GPU too much and lose the possibility of instancing.

Do you have any advice for an hybrid solution? Split convex objects is not a problem, but understand how to compare different instances of same va/sprite chunk and above all understand if this approach could cause slowdowns.

Thanks so much

Ray
« Last Edit: March 10, 2024, 09:36:14 am by Ray1184 »

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: VertexArray vs Instancing questions for 2D isometric project
« Reply #1 on: February 22, 2024, 08:42:12 pm »
SFML sprites aren't really instanced once you get to the GPU though. Effectively a sprite isn't that different from a vertex array with 4 vertices. They both end up calling the same internal draw function for an array of vertices.
So if your trees take 4 vertices each, the vertex array style has 100x4 vertices + 1 transform using 1 draw call. The sprite style has 100x4 vertices + 100 transforms using 100 draw calls. SFML is just hiding the sprite vertices from you, they are still being sent 4 at a time for each draw call to the GPU.

There are ways for a GPU to do real sprite instancing with shaders, but SFML doesn't use those.

But the best thing to do would be make a quick mockup of both styles and time them (such as try 1000 simple trees). The difference may not be enough to worry about in the complexity of your scenes.

Ray1184

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: VertexArray vs Instancing questions for 2D isometric project
« Reply #2 on: February 22, 2024, 08:59:00 pm »
Thank you so much for your answer, in this case I will go with first solution, for sure painless.
I was also thinking of working more at a low level by implementing a sort of depth buffer in a shader, but at this point perhaps I'm complicating things unnecessarily, considering that my scene won't be that complicated