Speeding up sprites...

BlitzMax Forums/MiniB3D Module/Speeding up sprites...

jkrankie(Posted 2010) [#1]
I'm using Sprites with collisions for bullets in my game, but i'm finding them to be the cause of quite a bit of slowdown. From reading through the forums, i spotted that Simon had mentioned he'd implemented a batching system for Sprites in iMiniB3D that he had yet to add to MiniB3D. What are the chances this could be added? Or how easily could i add it myself (baring in mind i'm pretty rubbish at OpenGL coding)

Just to clarify, i don't need the sprites for particles as i've already written something for that, it's purely for TSprites that need collisions.

Cheers
Charlie


jkrankie(Posted 2010) [#2]
Ok, i *think* i've got a handle on this now after taking a look at the iMiniB3d source. I'll have a go at it later on today. It looks like rather than just adding the sprite meshes to the main entitiy list, they are added to their own list, but i haven't worked out where yet...

Cheers
Charlie


jkrankie(Posted 2010) [#3]
Right, it looks like the existing method/functions i need to be dealing with are in tcamera.bmx and t global, where i need to add a few lines. I'll also need to add the sprite batch class.

updateentityrender
rendercam

Are there any gotchas i need to look out for i wonder...

Cheers
Charlie


jkrankie(Posted 2010) [#4]
Right, i've confused myself completely! there are too many structural differences between MB3D and iMB3D that i can't get my head around!

Cheers
Charlie


Kryzon(Posted 2010) [#5]
Hmm, try using a single surface system. People did that with Blitz3D alone (look at ParticleCandy's performance, it's awesome).
So you can get a crude version going only using pure MiniB3D commands (it won't be the best solution but it would be definitely faster than 1 surf for each sprite).

I also want to create a good single surface particle system for my MiniB3D projects, but time is precious!

I think one essencial thing to understand is that special matrix mat_sp that is exclusive to sprite-entities. Once I get my head around that I should be able to go further (if anybody would like to share any insights, don't hesitate!).
If I'm thinking correctly, that mat_sp is nothing more than the inverse camera matrix so the mesh can point towards it correctly, the fundamental feature of sprites.

Problem is, how to turn every quad by that matrix within a single surface?
The sprite functionallity works as it is because every quad is a different entity, so the matrix acts on a quad-level.
But what about an entire surface of quads?

EDIT: could you benchmark the slowdown that regular sprites caused in your program? the "before" and "after"?


Sledge(Posted 2010) [#6]
I'm using Sprites with collisions for bullets in my game, but i'm finding them to be the cause of quite a bit of slowdown.
Are you sure it's the rendering that is the bottleneck and not the collision system?


Robert Cummings(Posted 2010) [#7]
sprites typically have one state change per sprite, so it will very fast be the bottleneck on any system but only if he's using different images per sprite. Else its probably fill rate.

The clue is he is using them for bullets, right? well that only one state change if its just the one bullet texture... so perhaps it is fillrate?


jkrankie(Posted 2010) [#8]
I'm using several different images for bullets.

Cheers
Charlie


Kryzon(Posted 2010) [#9]
I think one essencial thing to understand is that special matrix mat_sp that is exclusive to sprite-entities. Once I get my head around that I should be able to go further (if anybody would like to share any insights, don't hesitate!).
If I'm thinking correctly, that mat_sp is nothing more than the inverse camera matrix so the mesh can point towards it correctly, the fundamental feature of sprites.

Problem is, how to turn every quad by that matrix within a single surface?
The sprite functionallity works as it is because every quad is a different entity, so the matrix acts on a quad-level.
But what about an entire surface of quads?


Can anybody help me with this?


jkrankie(Posted 2010) [#10]
Actually, the game space is 2D, with an orthographic camera so the sprites only need to be facing in one direction. I suppose that *might* be helpful...

Cheers
Charlie


Kryzon(Posted 2010) [#11]
That's great, but I'd still like to know what anyone has to say for the problem above.


Sledge(Posted 2010) [#12]
That's great, but I'd still like to know what anyone has to say for the problem above.
This might be dumb, but I'd question why you are trying to build an optimised system on top of MiniB3D. As I understand it, the fastest (fixed function) way to render sprites in OpenGL is to express them as a vertex array and cane through it with glDrawArrays(). If optimising sprite rendering is really *that* important then surely sidestepping MiniB3D's class hierarchy is going to be preferable to reverse-engineering it. ie Build a reduced 2D system that does only what you require, only in the order you require it, and drop into it as needed.


Kryzon(Posted 2010) [#13]
I'm not looking for 2D\orthographic sprites, if that is what you are saying. I'm speaking of sprites as they are known in the Blitz3D universe: quad meshes that always face the camera, and can have 3D transformations applied to them.

I didn't quite get what you meant with sidestepping the class hierarchy. In the same way single-surface particles were achieved with Blitz3D (with individual vertex manipulation), the same can be achieved in mB3D (and it "should" be achieved, since single surface is much faster than 1 surf for each particle).
I want to know if someone can explain to me how does that mat_sp matrix work, and how could one apply that matrix in a mesh that has more than just one quad. From then on, I could build my own sprite class that acts as a single surface holder for all the 3D particles.
I don't know if a Vertex Array is needed, since mB3D already uses VBOs for high polygon meshes. It's probably the theory that's the tricky part.


jkrankie(Posted 2010) [#14]
If you're just after faster particles, you could try this code i posted before, just rename the texture file. I can render about 25,000 blended, textured quads at 60fps on my Mac Mini.



However, it doesn't take into account anything done by minib3d.

Cheers
Charlie


Sledge(Posted 2010) [#15]
I'm not looking for 2D\orthographic sprites...I didn't quite get what you meant with sidestepping the class hierarchy.
I meant minimizing state changes with "raw" OpenGL calls rather than manipulating the entity system to do so. Just a thought.


klepto2(Posted 2010) [#16]
Hi, I'm currently not at home, but i will post a small sample as soon as i'm home. The keyword are pointsprites. if you're interrested in really fast sprites you will love it. The downside is the missing ability to scale them properly.

Here is a small screen with minib3d using pointsprites (150001 sprites at 43fps on a ATI Radeon X800)



Another way to speed up the the existing sprites would be to use shaders to manipulate the orientation instead of doing it via cpu.


jkrankie(Posted 2010) [#17]
That looks cool!

The only issue with point sprites is that they won't work on many laptops as they are usually OpenGL 1.4 or less.

Didn't you have a fast sprite thing in your extended version Klepto2? I'll have to have a look...

Cheers
Charlie


klepto2(Posted 2010) [#18]
In my old extended Version was a single Surface Particle System which you can try to use. A fast sprite system was planned but not really finished.

An alternative would be to check for the ARB_PointSprite extension and use pointsprites or single surface according to the result.

As a side note, you should not use Sprites for collision. Try Linepicking instead. Ok, it depends on your needs but i think the major slowdown will be caused by collision detection for this many sprites not the sprite alignment itself.


jkrankie(Posted 2010) [#19]
I'm only using the collisions for when the sprites hit the arena walls, so yes i guess it does seem a bit much to be using collisions for this. I'll see if i can work out how to do linepicking...

I'll dig out the extended version (i'm sure i've got it somewhere...) and see if the SS sprites make a difference.

Cheers
Charlie


jkrankie(Posted 2010) [#20]
Where abouts in the extended version code would i find the SS sprite stuff? I can't find it!

Cheers
Charlie


Kryzon(Posted 2010) [#21]
From what I noticed from demos, Point Sprites seem to grow smaller the closer the camera is (this won't happen to quads). Is there a way to disable that?


_Skully(Posted 2010) [#22]
I've found that encapsulating the parameter data into an array referenced by constants speeds things up quite a bit. I used this in my particle system. Using this method there is one lookup for the array reference and then just an offset within it for each parameter. The code doesn't look pretty but its easy to offset using getters/setters but use the constant-array reference for sprite updates.


klepto2(Posted 2010) [#23]
The SSS part is not included directly in minib3dext it is a seperate module (something with particles) also contined in the package at www.minib3d.com .

@Kryzon: Yes, thats the reason why i haven't continued it. the best way is really to go the shader way but this have other consequences (using shaders will deactivate most of the fixed function pipeline).


Kryzon(Posted 2010) [#24]
I see Klepto2, thanks for the posts.

Another way to speed up the the existing sprites would be to use shaders to manipulate the orientation instead of doing it via cpu.

This definitely sounds like a good way. I'll investigate further (it wouldn't be much of a cost because I'll replace most of the fixed function anyway).


SLotman(Posted 2010) [#25]
Point sprites doesn't work for billboards, which is what B3D sprites actually are.

For particle systems it's fine - since particles always faces the camera, but for trees or other things that actually should be parallel to a plane (ex: if the camera goes up, it shouldn't face the camera) it won't help at all.