(History blog)
I had thought these would be very easy, I had a sound plan for the sprite animation which was implemented smoothly. The textures for a sprite were setup with the frames being placed side by side in the bitmap. The shader received a framenumber and the width of each frame image, then added width*framenumber to the texturecoordinate x. The billboarding and rendering though, ended up being the most terrible system of code ive ever developed.
These where some things I had to take into account when designing the system:
1. sprites must be part of the scene depth buffer (that ruled out using spritebatch)
2. point sprites are crappy (mostly because I could not get them to work ;))
3. sprites do not need to be lit by scene lights
4.sprites will need to be able to have collision tests on each one
5.there will be thousands of sprites
6.sprites are part of larger sprite objects, the sprite objects have linear animations they perform on their child sprites
The method I chose was:
1. keep a single quad for each type of sprite
2.calculate a billboard rotation matrix
3. go through each spriteobject in a active grid area and:
1.update the animated locations of the childsprites
2. maintain of worldmatrix stack that include the animation translations and rotations from the sprite object animations, set rotation to identity, add the billboard rotation, render, and pop stack back to animation object to process the next child sprite
This turned out to be the most slow, crappy, useless, just plain wrong way to handle these billboard-sprites. With any decent amount of sprites on screen my framerate would drop to 40 or lower due to the tons of small draw calls.
After much considering I conluded the only way to do this is do the billboarding and position animation in a shader. Though this way uses more graphics memory being you have a buffer of all child quads in a sprite object. In order to do the bilboarding the rotation center of each quad must be known by the shader. Being the billboards do not need to be lit by the scene, normal was used to hold the position of the rotation center.
Bascialy the same process was used but this time in the shader. so a whole sprite object could be rendered all at once, giving the shader the billboardmatrix, worldmatrix for object, and position animation data to calculate for the child quads. This improved method was many times faster and works quite well. Framerate is minimaly effected by the volumn of sprites rendered.
So, a big lesson was learned implementing this system of billboarded sprites, using many draw calls is very very slow.
Monday, March 12, 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment