Approfondissements sur Molehill



Que procure cette API et que ne procure-t-elle pas?

La nouvelle API 3D est une API bas-niveau (low level) ce qui signifie qu'elle n'est pas aussi accessible que les API flash que l'on a l'habitude d'utiliser. Elle procure un certain nombres de fonctionnalités en s'interfaçant avec les libraires du GPU:

  • vertex buffers et index buffers
  • texturage
  • calcul du tampon de profondeur (z-buffer et depth buffer)
  • calcul de l'aire de rendu (stencil buffer)

Elle permet ainsi d'utiliser au maximum les performances offertes par le GPU, mais aussi d'utiliser leurs shaders standards. Elle offre aussi la création de nos propres shaders.

La nouvelle API 3D ne permet pas l'importation de modèle 3D provenant de logiciels tels que Maya, Blender ou 3DSMax. Ce sont les différents frameworks qui s'en chargeront ou ce sera à nous de le faire. Actuellement, le mode le plus répandu d'importation de modèles 3D est celui fait à partir du format Collada (.DAE) qui est un xml de données. Tout ce qui concerne la gestion de collision, de la caméra ou d'autres choses non mentionnées dans le paragraphe précédent ne sont pas gérées par l'API.

Le Stage3D et le Context3D

L'affichage n'est pas géré de la même manière qu'en flash actuellement. Ainsi, l'ajout d'un objet ne modifie pas l'affichage comme lorsqu'on ajoute un MovieClip dans la display list, il faut en effet passer par une fonction de rendu.

Le nouveau flash player se voit ajouter un nouveau stage, le Stage3D. Les éléments actuels (MovieClip et cie.) ne sont pas intégrables dans le Stage3D.

On ne peut pas ajouter de contenu derrière la scène 3D mais on peut ajouter plusieurs scènes 3D.

classes 3D

La raison pour laquelle le Stage3D s'instancie dans le Stage et que ce n'est pas un simple display object est que sinon, 19% du temps du rendu serait pris par la copie de données entre le CPU et le GPU (voir la vidéo à partir de 17 min).

La classe Context3D est la classe d'entrée de l'API. L'avantage de ce contexte, c'est qu'il est utilisé pour fonctionner sur les différentes cartes graphiques (DirectX 9, Open GL 1.3 et Open GL ES 2.0). C'est l'équivalent de la classe Context sur OpenGl et Device pour DirectX. C'est elle qui permet de générer la scène 3D grâce aux programmes 3D, aux textures 3D, aux vertex buffers et aux index buffers.

Le contenu de l'API qui n'a pas été presenté:

  • context3D.createTexture
  • context3D.createCubeTexture
  • context3D.setTexture
  • context3D.setBlending
  • context3D.setDepthTest
  • context3D.setStencilTest
  • context3D.setRenderToTexture
  • context3D.drawToBitmapData (pour faire des captures d'écran)

Les Vertex buffers et index buffers

En 3D, les primitives sont les points (vertex), lignes et triangles. Un triangle est constitué de 3 vertex et ce sont ces triangles qui seront utilisés pour le rendu graphique. Un modèle 3D (ou mesh) est donc constitué de plusieurs triangles. Pour bien comprendre à quoi servent les vertex buffers, prenons cet exemple.

Dans un cube, nous avons 6 faces chacune constituée de 2 triangles puisqu'il faut 2 triangles pour faire un carré. Ce qui nous fait au total 36 vertex. Ces vertex sont nécessaires pour le rendu du mesh, il faut donc tous les enregistrer dans notre vertex buffer qui est une sorte de tableau dont l'accès est particulier. Puisqu'il sert au rendu, il faut pouvoir le vérouiller pour y effectuer nos modifications pour éviter ainsi de génerer des erreurs de rendu.

Comme nous en avons réellement besoin que de 8 (sommets réels du cube), les index interviennent alors pour utiliser un même vertex plusieurs fois, allégeant ainsi notre vertex buffer et par la même occasion améliore le rendu grâce au cache vertex. L'index buffer est également une sorte de tableau à vérouiller lors des modifications, qui renvoie à un vertex contenu dans le vertex buffer. Ainsi, la création de nos triangles ne se fait plus directement par le vertex buffer, mais en passant par les indices contenus dans l'index buffer.

Un vertex s'instancie sous le format XYZRGBUV.

  • XYZ pour les coordonées.
  • RGB pour les couleurs.
  • UV pour le texture mapping

Je vous propose de regarder cet extrait de code pour mieux comprendre le fonctionnement et le cheminement.

code molehill

AGAL

Pour Adobe Graphics Assembly Language

C'est du bytecode binaire que l'on génère à l'aide de la class AGALMiniAssembler ou avec Pixel Bender 3D. L'AGAL constitue une vingtaine d'opcodes supplémentaires dans le flash player qui seront bien documentés.

Un Vertex Program transforme un ensemble de vertex en un mesh (objet 3D) et le place sur la scène. Il sert aussi pour pré-rendre les lumières et ombres mais implémente aussi le morphing et les animations à partir d'un squelette.

Un Fragment Program agit quant à lui sur les pixels. Il détermine les couleurs des pixels et permet de rendre les lumières et ombres depuis une texture donnée.

Ceux-ci constituent ce qu'on appelle plus généralement les shaders. Les boucles d'instructions et les branchements conditionnels ne sont pas encore supportés par l'AGAL.

L'AGAL se présente de la façon suivante:
C'est un token d'instruction de 196 bits constitué de l'opcode(32 bits), de la destination(32 bits), de la source A(64 bits) et la source B(64 bits). Ces intructions permettent des opérations de type data, arithmétique ou spécial sur les vertex. Il servira concrètement à créer un programme 3D à partir du bytecode généré. Écrire ces programmes demandent de bonnes connaissances en transformations 3D, gestion des lumières et calcul de coordonnées 3D.

Exemple d'instruction :

  var av:AGALMiniAssembler = new AGALMiniAssembler();
  av.assemble(Context3DProgramType.VERTEX,
            "m44 op, va0, vc0\n"   // transform and output 
            "mov v0, val\n"  // copy color  
  );  
      var af:AGALMiniAssembler = new AGALMiniAssembler(); 
   af.assemble(Context3DProgramType.FRAGMENT, 
            "mov oc, v0"  // output color  
  ); 
  

Molehill et haxe

L'introduction de nouveaux opcodes dans le flash player permettra la prise en charge de cette API dans haxe/flash.

Laissez un commentaire:

blog comments powered by Disqus Comments