Voilà le résultat d’une petite partie de ma journée sur mon moteur a particule. Pas mal de changement, car même si l’archi globale reste la même, la technique de render change du tout au tout !
J’ai d’abord porté mon optimisation sur l’arrêt d’utilisation de sprites uniques pour particules. C’était clairement trop couteux en calcul
J’ai donc opté pour un tableau qui contiendrai des entiers signés plutôt qu’un tableau de points, en raison du bench que j’avais fait plus tôt. Dans l’optique d’optimisation, je me suis posé la question de savoir ce qui serait le plus rapide (sachant qu’une particule nécéssite 8 entiers signés) :
- un Array contenant un autre Array pour chaque particule (une particule / entrée) :
particules[0] = [posX, posY, speedX, speedY, accelX, accelY, mass, color] - Un ByteArray contenant tous les entiers de particules à la suite :
particules.writeInt(posX); particules.writeInt(posY); particules.writeInt(speedX); particules.writeInt(speedY); particules.writeInt(accelX); particules.writeInt(accelY); particules.writeInt(mass); particules.writeInt(color); - Un Vector (flash10) d’arrays rejoignant la première proposition.
- Un Vector (flash10) de ints rejoignant la 2nde proposition.
La première idée m’est apparue… en premier
… J’avais envie de faire simple, et un tableau paraissait bon. Mais comme mon bench Number vs Point avait fait naître le doute, j’ai essayé de faire quelques benchs “Array vs ByteArray”.
Pour bien être certain de pas me gourer, j’ai fais 2 benchs, l’un chronométrant l’ajout de données aux tableaux, et un second incrémentant chaque entrée du tableau avec une valeur (pas forcément 1).
for (var c:int = 0; c < iterations; c++)
{
arr.push([0, 0]);
}
for (var a:int = 0; a < iterations; a++)
{
ba.writeInt(a);
ba.writeInt(a);
}
Là, étonnement, la différence n’est super flagrante qu’a partir d’un million d’itérations (je m’attendais a moins).
Viens ensuite le fameux test d’incrémentation.
for (var d:int = 0; d < num; d++)
{
arr[d][0] += incr;
arr[d][1] += incr;
}
Pour le bytearray, j’ai utilisé 2 méthodes. La première était “ohmygodesque” :
var replace:int;
for (var b:int = 0; b < num; b++)
{
replace = ba.readInt();
ba.position -= 4;
ba.writeInt(replace);
}
Après un léger contournement, on arrive a un truc potable :
for (var b:int = 0; b < (num * 4); b += 4)
{
ba.writeInt(((ba[b] << 24) + (ba[b + 1] << 16) + (ba[b + 2] <<
+ ba[b + 3]) + incr);
}
Avec la première méthode de remplacement de bytearray, on arrive à :
////////////////////////////////////// bench speed with 1000000 couple of ints ////////////////////////////////////// bytearray 2ints push : 0.673s bytearray ints replace : 2.309s ////////////////////////////////////// array 2ints push : 1.600s array ints replace : 0.504s //////////////////////////////////////
Avec la 2nde :
////////////////////////////////////// bytearray 2ints push : 0.673s bytearray ints replace : 0.753s ////////////////////////////////////// array 2ints push : 1.600s array ints replace : 0.504s //////////////////////////////////////
Donc le tableau était clairement indiqué. Après, je me suis souvenu de la conf’ sur flash player 10 où il avait été dit que la nouvelle classe Vector était super de la mort mieux qu’un Array. Alors j’ai pris des Vectors d’Array (aka Vector.<Array>).
A ce propos, vu que j’utilise Vector, les démos ne sont visible qu’avec un flash player a jour (v10).
Ensuite, comme j’ai laché l’idée que j’avais de pouvoir manipuler des Sprite en tant que particules, il fallait choisir une méthode de rendering.
J’avais le choix de déplacer le “curseur graphique” du container du moteur, et de faire des moveTo() lineTo() sur chaque particule, avant et après calculs, où de tout placer dans un bitmapdata.
Trève de blabla, j’ai fait les 2, mais le premier est tellement couteux en CPU pour le nombre de particules affichées que ca en devient indécent. On prendra donc focus sur la méthode avec le bitmapdata. Voici les premiers résultats avec 2500 particules, à 30fps :
Avec un petit blurfilter, et des particules blanches, et un attracteur fait un peu a l’arrache ca donne ca :
Voili voilou !
Comments (2)
C’est tout beau tout jolie ca.
On retrouve l’idée de StartMonkey : http://starmonkey.free.fr/joins/qsd.php?qsd=starmonkey008
Ainsi que Nicoptere :
http://www.nicoptere.net/blog/index.php/2008/07/03/42-champ-de-vecteurs
Tu devrais pouvoir trouver des points de comparaison, sauf que leurs travaux ont du etre réaliser pour FP 9, voir même en AS2 pour ceux de StartMonkey ( je pense).
merci bien !
J’avais envie d’un moteur a particule depuis longtemps, et j’avoue avoir été inspiré par les travaux de nicoptere !
L’usage du FP10 n’était qu’en vue d’optimiser le temps, avec Vector, sinon quel interet
?