Forums Développement Multimédia

Aller au contenu

- - - - -

Au sujet des performances...

CODE Actionscript

7 réponses à ce sujet

#1 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 03 November 2011 - 02:46 AM

Hello !

Depuis 1 mois que le FP11 est sorti, j'ai fait pas mal de test avec Molehill from scratch, et il y a quelque chose qui m'étonne beaucoup dont je n'arrive pas à expliquer la cause. J'ai pensé que ça venait de mon code, mais Minko se comporte de la même manière (et j'ai confiance dans le code de Minko :) )

Quand je regarde cette démo :
http://aerys.in/mink...ase/citroen-ds3

Tout s'affiche hyper vite (60 fps je suppose), même sur l'ordi que j'utilise au bureau qui dispose d'une carte graphique ne supportant pas le GPU (radeon HD 2450). Le FPS reste constant si je zoom ou si je dézoom. Bref, c'est parfait !

Pourtant si, avec le même PC, je lance le code de ce tuto
http://hub.aerys.in/...-spinning-cubes

avec 10 pour variable 'CUBE_SIZE' , afin de créer 10 000 cubes , je ne sais pas quel est le framerate mais plus proche de 20 que de 60 alors qu'il y a 6*2*10 000 = 120 000 triangles , soit 30 000 de moins que pour la voiture. (les 10 000 cubes sont contenus dans le même TransformGroup et ne tournent pas sur eux même ; la seule animation est la camera qui bouge en fonction de la souris (je lance bien le code en 'release') )

Jusqu'a présent je n'ai jamais travaillé avec un objet3D créé à partir de 3DSMax (ou equivalent), j'ai toujours créé mes meshs dynamiquement , du coup je me demande vraiment ce qui explique une telle différence. Y a t il un bout de code magique à ajouter pour optimiser les performances ?


Merci d'avance !

EDIT : en fait c'est 1000 cubes, pas 10 000, donc bien moins de triangles ...

#2 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 03 November 2011 - 10:15 AM

Voir le messagetlecoz, le 03 November 2011 - 02:46 AM, dit :

avec 10 pour variable 'CUBE_SIZE' , afin de créer 10 000 cubes , je ne sais pas quel est le framerate mais plus proche de 20 que de 60 alors qu'il y a 6*2*10 000 = 120 000 triangles , soit 30 000 de moins que pour la voiture. (les 10 000 cubes sont contenus dans le même TransformGroup et ne tournent pas sur eux même ; la seule animation est la camera qui bouge en fonction de la souris (je lance bien le code en 'release') )

Les performances sont influencées par deux choses :
- la complexité du rendu (nombre de triangles, + complexité des shaders) va se faire ressentir sur le GPU
- le nombre d'objets dans la scène va se faire ressentir sur le CPU

C'est pour cela que :

- nous allons proposer des moyen de mieux partitionner l'espace pour permettre d'avoir des scènes plus larges (= avec plus d'objets) sans que cela coûte autant en CPU
- Minko propose déjà tout ce qu'il faut pour combiner plusieurs meshs en un seul (voir la méthode Mesh.merge et les classes AtlasTexture/AtlasUVModifier). C'est très très très efficace pour toute la géométrie statique. Pour voir un exemple "fait main", tu peux regarder le code de la démo Google Globe qui merge des milliers de cubes dans un seul mesh

Globalement, les mêmes limitations sont constatables sur les autres moteurs 3D d'après nos tests, pourtant de nombreuses features - assez couteuses en CPU justement - n'existent pas. La VM Flash et le compilateur sont également responsable en très grande partie de certains problèmes de scalabilité. Concernant les shaders en particulier, il y'a un petit goulot d'étranglement CPU/mémoire déjà connu que nous tentons actuellement de régler avec un pipeline de rendu plus flexible. Ca devrait être dispo dans la v2.

L'outil d'import/export disponible avec la v2 devrait également permettre d'optimiser la scène pour merger autant que possible la géométrie statique. Je ne sais pas si on aura le temps de mettre cette option, mais c'est définitivement prévu qu'elle soit disponible, si ce n'est dans cette version alors elle le sera dans la suivante.

a+

#3 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 03 November 2011 - 10:55 AM

Merci beaucoup pour ta réponse.

Je comprend ce que tu dis, pourtant dans les faits, cela ne me parait pas aussi logique (je ne parles pas de Minko en particulier, mais des anims molehill en générale).

Citation

Les performances sont influencées par deux choses :
- la complexité du rendu (nombre de triangles, + complexité des shaders) va se faire ressentir sur le GPU
- le nombre d'objets dans la scène va se faire ressentir sur le CPU

Il y a quelques jours, j'ai créé cette anim from scratch
http://www.machinbid...tTemp/molehill/

Il s'agit du nombre max de plane que l'on peut faire rentrer dans un seul VertexBuffer. Tout est dessiné en 1 seul appel à Context3D.drawTriangles ; toutes les planes partagent le même objet Texture et sont "statique" (dans le sens ou elles ne bougent pas, c'est le conteneur qui bouge). Le Shader est ultra simple (il tient en 2 lignes).Mon anim est construite un peu comme dans Minko dans le sens ou toute les propriétés de chaque objet sont partagées et reposent sur un modèle unique.

Théoriquement, cela me parait être l'équivalent d'une anim utilisant Mesh.merge (si j'ai bien compris). Pourtant , sur le poste sur lequel je travaille au bureau, c'est le jour et la nuit entre ta démo de voiture a 150 000 polygone qui tourne à 60 FPS et mon anim à 32 000 polygones qui oscille entre 15 et 20 fps (avec une bonne carte graphique, ca tourne à 60 ; mais ta démo de voiture tourne parfaitement sur tout les postes sur lequel je l'ai testé du coup je suppose que ca devrait être possible de faire la même chose avec 5 fois moins de polygones...)

J'ai remarqué que les performances étaient différente en fonction de si on a ou pas des triangles qui se superposent (c'est aussi valable dans Minko : si on créé 1000 cube placé aléatoirement dans une petite zone, ça rame plus que si on les place aléatoirement dans une zone plus grande (parce que la probabilité de chance que des poly se recouvent est plus faible) ; mais cela n'explique pas tout car même en prenant soin d'espacer chacune de mes 16 000 plane , je suis très loin d'égaler la vitesse d'affichage de ta voiture. :(

En tout cas, je vais regarder de près le code du google-globe.
Merci encore !

EDIT : Je vais essayer de refaire exactement la même anim en utilisant Minko + Mesh.merge pour voir si c'est mon Shader qui est moisi (ce n'est pas impossible, j'ai pris celui de Starling :twisted: :lol: )


Citation

il y'a un petit goulot d'étranglement CPU/mémoire déjà connu que nous tentons actuellement de régler avec un pipeline de rendu plus flexible. Ca devrait être dispo dans la v2.

L'outil d'import/export disponible avec la v2 devrait également permettre d'optimiser la scène pour merger autant que possible la géométrie statique. Je ne sais pas si on aura le temps de mettre cette option, mais c'est définitivement prévu qu'elle soit disponible, si ce n'est dans cette version alors elle le sera dans la suivante.
:Hola:

#4 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 04 November 2011 - 00:24 AM

Normalement, un seul draw call ne devrait avoir aucun impact sur le CPU (sauf si peut-être Context3D.enableErrorChecking est à "true").

Donc à priori, le goulot d'étranglement est au niveau GPU. Es-tu sûr d'utiliser le triangle culling? L'impact sur le GPU dépend effectivement de :
  • la complexité des shaders
  • de l'overdraw (le fait de redessiner là ou certains pixels ont déjà été mis dans le back/z buffer)

Si tu as un shader de deux lignes, ça veut dire que tu animes tes plans en modifiant le vertex buffer depuis du code AS3 exécuté sur le GPU ? Si c'est le cas alors c'est ça qui cause les problèmes de performances.

#5 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 04 November 2011 - 00:58 AM

Bonsoir ,

Citation

Es-tu sûr d'utiliser le triangle culling?

Oui et non, je l'ai mis sur 'NONE'

Citation

Si tu as un shader de deux lignes, ça veut dire que tu animes tes plans en modifiant le vertex buffer depuis du code AS3 exécuté sur le GPU ?

Dans l'anim, aucun rectangle ne bougent donc les valeurs contenues dans le VertexBuffer ne sont pas modifiées. Seule la camera bouge (une matrix3d), c'est vraiment comme si j'avais un objet3D unique très très long, composé de plusieurs planes ; avec une camera qui démarre devant l'objet et qui le remonte progressivement.

Si je donne un mouvement a chaque plane (et que je modifie donc en permanence les données contenues dans le vertexBuffer), ça rame nettement plus et j'arrive seulement à en afficher 5000 en conservant les 60 fps. Mais ça, je peux le comprendre parce que j'ai l'habitude d'utiliser le CPU.

Pourquoi le GPU galère à afficher un seul objet par contre, je ne comprend pas...

Mais à vrai dire peu importe, mon code est surement moisi :)

L'objectif aujourd'hui serait d'arriver à faire ça dans Minko et que ça marche (et apriori ça devrait car le code du globe ressemble à ce que j'ai fait (sauf qu'il tourne vite :lol: ) , il y a surement un problème avec le shader que j'utilise car je ne maitrise pas du tout cette partie).

J'ai essayé d'utiliser Mesh.merge, mais pour l'instant je n'y arrive pas.
Quelque chose doit m'échapper car le résultat de mon 'merge' se présente sous la forme d'un seul cube (ayant pourtant un vertexStream.length > 10 000 ).

#6 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 04 November 2011 - 19:00 PM

Voir le messagetlecoz, le 04 November 2011 - 00:58 AM, dit :

J'ai essayé d'utiliser Mesh.merge, mais pour l'instant je n'y arrive pas.
Quelque chose doit m'échapper car le résultat de mon 'merge' se présente sous la forme d'un seul cube (ayant pourtant un vertexStream.length > 10 000 ).

Mesh.merge() fait exactement ce que ça dit. Ca concatène la géométrie.
Donc si tu merges 10 000 CubeMesh.cubeMesh, ça ne sert à rien.
Chaque mesh a ses vertices définis en espace local, donc tu obtiendras 10 000 cubes centrés en (0,0) et de côté 1.
Donc un seul cube à l'écran.

C'est pour ça que la démo du Globe est intéressante, elle montre comment modifier la géométrie en plus de simplement la merger.

a+

#7 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 04 November 2011 - 19:16 PM

Citation

Donc si tu merges 10 000 CubeMesh.cubeMesh, ça ne sert à rien.

Ah d'accord je comprend mieux ce qui ce se passe :)
N'y a t il pas moyen (à part reconstruire une méthode merge, ce qui n'est pas vraiment un problème cela dit) d'appliquer la transformation (translation/scale/rotation) avant d'effectuer le merge ?

#8 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 06 November 2011 - 17:12 PM

Voir le messagetlecoz, le 04 November 2011 - 19:16 PM, dit :

Ah d'accord je comprend mieux ce qui ce se passe :)
N'y a t il pas moyen (à part reconstruire une méthode merge, ce qui n'est pas vraiment un problème cela dit) d'appliquer la transformation (translation/scale/rotation) avant d'effectuer le merge ?

Tu peux facilement le faire en t'inspirant de celle présente dans la démo du Google Globe, c'est pour ça que j'en parlais :)

a+



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

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