Forums Développement Multimédia

Aller au contenu

Jeu - Optimisation des textures - VRAM Limitations

CODE Actionscript

9 réponses à ce sujet

#1 eKimiya

    Ceinture Noire

  • Members
  • PipPipPipPipPipPipPip
  • 423 messages

Posté 10 July 2012 - 17:16 PM

Bonjour à tous !

Je suis sur le développement d'un jeu utilisant le Stage3D (et Starling), et je suis confronté au limitations d'utilisation du GPU...
C'est mon premier jeu utilisant le GPU, et je n'y connaissait pas grand chose avant de commencer... Du coup l'apprends =)

J'ai trouver le tableau ci-dessous :

Resource | Number allowed | Total memory
Textures | 4096 | 128 MB

Du coup première question : comment calculer la mémoire actuellement utilisée par mon application ?


Mon problème :

Dans le jeu, il pourra y avoir jusqu’à 40 personnages différents sur la carte. Ces personnages auront différentes "poses" (déplacement, attaque... etc), en gros 10 poses différentes... x2 pour le personnage de face et de dos (donc 20 poses). Donc 20 animation qui ferait entre 10 et 15 images clés.

Aujourd'hui les animations sont exporter en swf, puis quand le jeu se charge, il va chercher les assets, découpe les animations image par image pour en faire des textures... (ceci car certaines partie de du personnage est personnalisable par l'utilisateur, donc je trouvais cette méthode plutôt pratique !).


Le problème... c'est que j’explose la VRAM !!! J'arrive très rapidement à la limite des 350MB max (... GG moi ?...) .

Je viens donc demander votre aide, si certain d'entre vous on déjà travailler sur des jeux demandant beaucoup d'assets différents... Comment organisez-vous vos textures ?

J'ai l'impression que ma méthode de chargement de swf n'est certainement pas la bonne... Passer par des sprites-sheets directement est plus malin (même si c'est moins pratique, ça c'est pas grave) ?

C'est un jeu au tour par tour. Pensez vous qu'il est possible de créer les textures au moment de la sélection du personnage par l'utilisateur ? cela ne prend pas trop de temps (il faudrait éviter des secondes de chargement à chaque clic :/) ? Je coup je chargerais, déchargerais, chargerais, déchargerais... au fur et à mesure...



Voilà... merci à ceux qui auront prit le temps de lire ! Si vous avez des solutions...

Merci !!

#2 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 10 July 2012 - 21:13 PM

Hello !

Citation

comment calculer la mémoire actuellement utilisée par mon application ?
Excellente question, merci de l'avoir posé... ^^

Citation

Pensez vous qu'il est possible de créer les textures au moment de la sélection du personnage par l'utilisateur ?
Pourquoi ca ne serait pas possible ?
Je doute que ca prenne plus de 10ms donc ca ne devrait pas se remarquer :)

Tiens nous au courant !

++

#3 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 11 July 2012 - 09:29 AM

Salut,

De ce que j'ai lu et compris, chaque création de texture uploade la texture dans la VRAM. La solution serait donc effectivement de libérer les textures non enployées, grâce à la méthode dispose()
http://forum.starlin...oo-many-atlases
http://forum.starlin...s-initalisation

L'utilisation des atlas de texture semble recommandée, pour la rapidité du rendu, mais aussi pour l'économie de mémoire, puisque cela permet d'utiliser des bitmapdata dont la taille est une puissance de 2, même si chaque image clé de l'animation d'un personnage n'a pas une telle taille.
Ceci ne rend pas obligatoire d'utiliser des spritesheets: tu peux générer les bitmaps qui serviront d'atlas à partir de tes swf à l'exécution. On a parlé ici de générer des atlas: http://forums.mediab...ger-de-textures

J'ai lu aussi que si cela ne nuit pas à la qualité de ton rendu, ne pas utiliser les mipmaps économise beaucoup de mémoire: http://wiki.starling...ou_need_mipmaps

#4 eKimiya

    Ceinture Noire

  • Members
  • PipPipPipPipPipPipPip
  • 423 messages

Posté 11 July 2012 - 10:07 AM

Merci pour vos réponses !

Je vais regarder ça ces prochains jours, et je reviendrais vers vous =)


Pour le calcul de l'occupation VRAM, ça semble être quelque chose comme :

Texture RGBA : largeur * hauteur * 4 bytes

Mes textures serait du 256*256 (si je prend une puissance de 2), donc ça donne :

256 * 256 * 4 = 262144 bytes = 0.25 MB.
128 / 0.25 = 512 Textures MAX (si on veut rester en dessous des 128MB).

​ça vous parait juste ?



#5 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 12 July 2012 - 09:50 AM

Il ne faut pas oublier les mip maps. Je crois qu'en gros il faut que tu fasses x2 ou +50% sur chaque texture si tu utilises le mip mapping.

#6 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 12 July 2012 - 10:01 AM

Citation

Je crois qu'en gros il faut que tu fasses x2 ou +50% sur chaque texture si tu utilises le mip mapping.

en fait c'est 33%

Citation


So, for a 512×512 texture, this means a total of nine textures get generated. Each of the different textures is called amip level, and it's often indicated with the letter d (where d goes from 0 to 8 in this case).

Now, this might seem a horrible waste of GPU memory: to use nine actual texture images for every single texture of every object. But think of this: the mip level textures are smaller than the main full-size texture. And if you calculate the total space occupied by the full mipmapped texture (all the nine levels in this example), you'll see that it is only 33% times bigger than the single full size texture:

512×512 + 256×256 + 128×128 + ….1×1 < 512×512 * (1 + 1/3)

So, it's not that much of a waste of GPU memory as if you were using nine times the memory. You're just using 1.33 times the memory.


tout est détaillé là (pour les mip maps) : http://www.adobe.com...mipmapping.html

#7 eKimiya

    Ceinture Noire

  • Members
  • PipPipPipPipPipPipPip
  • 423 messages

Posté 12 July 2012 - 10:03 AM

Pour l'instant pas de mip mapping pour moi !
Je crois avoir lu que c'était +33% en plus pour les mip maps... Dans tous les cas c'est vrai qu'il faut penser à prendre ça en compte quand on en utilise... Pas négligeable !

#8 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 12 July 2012 - 10:15 AM

Cela dit, je ne sais pas s'il est vraiment pertinent de se préoccuper de l'occupation en mémoire des éléments car la mémoire disponible dépend du poste du client, qui est très variable (c'est bien d'en avoir conscience cela dit)

Essaye plutôt d'optimiser la structure de ton projet en vue d'utiliser uniquement ce qui est nécessaire quand c'est nécessaire :)

Dans ton cas particulier, je pense que je créerais une texture vide une seule fois au début du jeu dans laquelle j'uploaderai le bitmapData de la pose voulue à chaque tour. Puisque c'est du tour par tour, si j'ai bien compris on a besoin que d'une texture à la fois donc pas besoin d'en créer plus que nécessaire :)


EDIT : Je ne sais pas trop ou en est le framework Starling, mais je pense qu'il faut plus le voir comme un exemple simple et concret d'utilisation de Stage3D que comme un vrai produit fini dans le sens ou Starling est hyper lourd.

Tout est un peu trop simpliste, rien n'est géré par le GPU (le strict miminimum)..Quand j'avais lu le code au mois de novembre, j'avais eu l'impression de voir une compilation de tout ce qu'il ne fallait pas faire pour optimiser son code (déclaration des variables dans les boucles ; utilisation à outrance,y compris dans les boucles ,onEnterFrame, de variables statiques ; un drawTriangle par DisplayObject....).

J'ai lu le code de l'extension permettant de gérer les particules avec Starling la semaine dernière, toutes les particules sont géré via un seul drawTriangle, ce qui est déjà mieux, mais rien est géré par le GPU ce qui est pourri (pour te donner une idée, on peut faire bouger 1000 particules avec Starling a 60 fps ; en passant par un Shader on peut en faire bouger 21 000 par appel de drawTriangle et en ayant absolument aucun calcul coté CPU.

Bref, si tu cherches à optimiser ton projet, n'utilise pas Starling :)


Si tu n'as pas le courage de tout coder par toi même, tu peux essayer ce framework (il n'est pas parfait, mais il est continuellement optimisé/amélioré et permet plus de chose que Starling)
https://github.com/nulldesign/nd2d

ou celui là qui est assez prometteur (mais la v 1.0 n'est pas encore sorti donc il vaut mieux attendre un peu)
http://blog.flash-core.com/?p=1155

++

#9 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 13 July 2012 - 12:11 PM

Citation

J'ai lu le code de l'extension permettant de gérer les particules avec Starling la semaine dernière, toutes les particules sont géré via un seul drawTriangle, ce qui est déjà mieux, mais rien est géré par le GPU ce qui est pourri (pour te donner une idée, on peut faire bouger 1000 particules avec Starling a 60 fps ; en passant par un Shader on peut en faire bouger 21 000 par appel de drawTriangle et en ayant absolument aucun calcul coté CPU.

Le problème c'est que pour animer ces particules, il faut modifier le shader :) Bonne chance pour faire de l'AGAL là dessus... Pour ce genre de trucs :

- Il faut pouvoir customiser les formules de position/couleur/rotation des particules par exemple. Dans minko on fait ça en proposant une interface IParticleSystem qui a des méthodes genre "getPosition(time : SFloat) : SFloat". Ce genre de méthodes sont ensuite appelé par le shader qui s'occupe de tout le reste. C'est super pratique !

- Avec un éditeur, genre le shaderlab, tu peux avoir un éditeur de courbes pour ce genre de choses; cf cette vidéo à 1'35



Citation

Tout est un peu trop simpliste, rien n'est géré par le GPU (le strict miminimum)..Quand j'avais lu le code au mois de novembre, j'avais eu l'impression de voir une compilation de tout ce qu'il ne fallait pas faire pour optimiser son code (déclaration des variables dans les boucles ; utilisation à outrance,y compris dans les boucles ,onEnterFrame, de variables statiques ; un drawTriangle par DisplayObject....).

Ca c'est vraiment pas bien fait effectivement. Le fait de batcher les objets c'est très dur en 3D. Il y'a des moyens très différents de faire ce genre de choses (intancing). Mais en 2D c'est "facile". Donc effectivement si le moteur ne le gère pas, alors il n'est pas très bon et n'offrira que des performances très moyennes par rapport à ce qui est possible.

Citation

Dans ton cas particulier, je pense que je créerais une texture vide une seule fois au début du jeu dans laquelle j'uploaderai le bitmapData de la pose voulue à chaque tour.

Oui un petit algo de TextureAtlas, basé sur un quad tree, permet de faire ça. Tu as un exemple là :

https://github.com/a...TextureAtlas.as

Il suffit juste ensuite de mofier les UVs des quads que tu dessines en fonction du résultat de l'allocation de la texture dans l'atlas. Ca permet vraiment de rendre plein de quads différents avec une seule texture et donc les meilleures performances. Par contre, impossible de gérer les spritesheets comme ça :(

Modifié par Jean-Marc Le Roux, 13 July 2012 - 12:12 PM.


#10 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 13 July 2012 - 14:31 PM

Citation

Bonne chance pour faire de l'AGAL là dessus...
D'accord pour dire que l'AGAL est peu lisible, que le shaderLab est beaucoup plus sexy...
Mais bon, c'est tout de même loin d'être infaisable...

Le Shader de particule dont je parles plus haut, c'est moi qui l'ai codé, et ça m'a pris plus ou moins une demi journée sans être un expert en création de Shader (j'ai du en coder une douzaine tout au plus, et je n'en avais jamais codé il y a 4 mois). Plus j'en code et plus c'est facile et rapide d'en coder :)

Citation

Le problème c'est que pour animer ces particules, il faut modifier le shader
Je ne comprend vraiment de quoi tu parles, en ce qui me concerne j'update une seule constante, qui contient la valeur de getTimer() et qui me permet, via quelque calcul coté AGAL, d'animer le shader.

Citation

Il faut pouvoir customiser les formules de position/couleur/rotation des particules
Dans le cadre de la création d'un ShaderLab / Minko , c'est pertinent de pouvoir customiser les formules parce qu'on parle d'une anim qui va en "générer" d'autre. Mais dans le cadre d'un "projet de tout les jours" on a rarement besoin d'autant de potentialité, et un Shader qui fait ce qu'on veut et pas autre chose suffit la plupart du temps.

Tout dépend ce qu'on fait, dans le cadre du developpement d'un jeu complex en 3D, ce que je dis ne tient plus.

EDIT:

Citation

Par contre, impossible de gérer les spritesheets comme ça :(
A moins de faire en sorte que chaque image du spriteSheet de chaque perso/anim fasse exactement la même taille (ce qui n'est pas forcément un problème si le repère de chaque displayObject est centré), auquel cas tu peux relativement facilement, et à moindre coût via copyPixels, mettre à jour le bitmapData source et le réuploader à chaque frame.

C'est un peu lourd, mais si tu dois animer 100 perso (par exemple) différent sur le même écran, que chaque anim de chaque perso nécessite une texture entière pour stocker le spritesheet, et que tu n'as pas assez de ram sur ton ordi pour stocker les 100 textures, cette approche pourrait être une solution.



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)