Gna !
Non j'ai pas grand-chose à rajouter à ton explication @lx, c'est tout très bien.

A noter quand même que t'as pas parlé de la possibilité d'émettre des particules en screen-space ! En gros là tu rends une scène avec un deferred rendering classique, même pas besoin de t'emmerder à déplier tes UVs et compagnie. Au final t'as un GBuffer avec couleur et distance (ZBuffer) donc tu peux aisément recréer la position 3D de la particule avec la bonne couleur et vogue la galère...
Bon par contre avec ce système tu n'as pas les backfaces ou les concavités mais c'est déjà sympa.
Je vais quand même montrer un exemple de mesh dont les UVs sont dépliés :

C'est la tête que tout le monde utilise pour faire du subsurface scattering et qu'on peut trouver là :
http://www.ir-ltd.net/infinite-3d-head-scan-released.On voit bien que toutes les parties de la tête sont représentées dans cette texture. Pas de recouvrements, pas de mirroring : chaque triangle est mappé sur un endroit unique de la texture.
Inversement, chaque pixel de la texture est donc mappé sur un triangle unique du mesh.
Tu peux obtenir ce genre de dépliage à partir de n'importe quel mesh en utilisant un plug-in comme Pelting (dépeçage

) dans Maya ou Unwrap UV dans MAX.
A partir d'un tel mesh, comme disait @lx, il te "suffit" ensuite de baker les particules dans une texture. La taille de la texture dictera le nombre de particules.
Pour ce faire, il faut rendre le mesh dans la texture en utilisant les UVs des triangles (qui sont uniques comme on l'a dit, pas de recouvrement) comme position dans le clip space.
En gros, généralement dans le vertex shader on fait (en HLSL) :
Out.Position = mul( float4( In.VertexPosition, 1.0 ), ModelViewProj );
Ici au contraire on fait :
Out.Position = float4( 2.0 * In.UV - 1.0, 0.0, 1.0 );
Et dans le pixel shader tu écris (en multiple render targets, car tu as besoin de plusieurs infos):
* Position 3D originale sur le mesh (dans la 1ère render target)
* Couleur (dans la 2nde render target)
* Ce que tu veux... Moi j'écrivais aussi la normale parce que je lightais les particules.
Seule la première render target va évoluer, les suivantes sont des informations fixes. A moins que tu veuilles faire changer la couleur des particules avec leur durée de vie, ce genre de chose.
Il faut bien comprendre que tu ne fais ça qu'une seule fois au départ : tu bakes les particules de ton mesh.
Ensuite, toutes tes particules sont en fait représentées par chaque pixel de tes render targets, et là comme disait @lx, tu vas dessiner N point où chaque point (grâce au SV_VertexID) va aller sampler la texture dans le vertex buffer pour retrouver position, couleur, normale, etc.
Chais pas trop quoi dire d'autre sans paraphraser @lx 36 fois, ce que j'ai déjà fait.
L'idée principale et qu'il faut bien comprendre est que tout se fait dans des render targets : tu animes tes particules en faisant un va-et-vient entre 2 render targets, la première est la source qui contient les positions courantes, la seconde est la destination qui va contenir la nouvelle position. Et là, tout est permis pour calculer l'animation : attraction, vitesse, gravité, curl noise, etc.
Et pour ce qui est de l'attraction des particules vers un mesh, c'est ce qu'@lx disait : tu fais une interpolation de ta position courante avec une position target (une texture contenant les positions des particules sur le mesh attracteur), et tes particules vont tout naturellement aller se coller sur le mesh attracteur.
Chuis un peu fatigué, j'espère que j'ai été clair. Sinon tu as toujours mon code source que tu peux pomper ici :
http://wiki.patapom.com/index.php/NuajC'est un peu le bordel en ce moment alors je sais même pas si l'exemple des particules fonctionne encore. Le projet s'appelle "DemoNoiseParticles" en tout cas.