SYSTÈME D’INSTANCING
TIMOTHÉE RAULIN
PLAN
PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
PROBLÈME
Situation
 Nombre d’objets à l’écran
 Nombre d’objets dans le
monde
 Temps de « fabrication » du
contenu d’une zone
 M...
 En moyenne 10 000 draw call dès qu’on dezoom
 Batching dynamique …
 Mauvais frame rate (CPU bound) mais régulier
 Édi...
 Lent
 Mémoire gigantesque
 Très lent en fait!
 Bon frame rate mais grosse saccade + out of memory
 Pas éditeur frien...
PLAN
PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
 Encodage dans une texture
 Décodage au vertex-shader
 Implémentation
 Performance
 Mémoire
SOLUTION UTILISÉE
 1 pixel = 4 * 8 bits ou 2 * 16 bits
 2 * 8 bits = 16 bits => 65536
• 1 => 255 (8 bits) ou 65535 (16 bits)
 Encodage d’...
int valueIn0_1_8bit = System.Math.Max(0, System.Math.Min(255, (int)(valueIn01 * 255.0f)));
UnityEngine.Color32 color = new...
 Strip de mesh : Pour chaque mesh de chaque type de décors, on
prépare un mesh qui est une répétition de copie de ce mesh...
 On utilise la version de UnityEngine.Graphics.DrawMesh avec 9
paramètres dont un MaterialPropertyBlock
 MaterialPropert...
X lo X hi Y lo Y hi Z lo Z hi Fx lo Fx hi Fz lo Fz hi Up lo Up hi X lo X hiUp lo Up hi
Instance 0 Instance 1 Instance 2 In...
 A partir d’un ensemble de groupe d’objets disparates, on
fabrique un ensemble de groupe d’objets de même type
 On les e...
 La consultation de la texture au vertex-shader est gratuite!
• Il faut être GPU bound pour le voir
• Il faut vraiment be...
 Ca pique!! Chaque type d’objet est répliqué, parfois plusieurs
centaines de fois
 En cause certaines limitations de Uni...
 Pour le debug et la mise au point, pouvoir switcher entre
« Unity pur » et « instancing », le premier définissant la
réf...
TA TA TATATA * *AIR CONNU
PLAN
PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
 Nombre de draw call réduit
 Temps de régénération et coût de stockage d’une zone réduit
 Zéro alloc ou presque en réut...
PLAN
PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
 Travailler avec des valeurs entières permet d’avoir des indices
et donc des tableaux d’objets consultables
 Il n’est pa...
traulin@amplitude-studios.com
MERCI
Prochain SlideShare
Chargement dans…5
×

[Paris Unity3D meetup] - Système d’instancing dans endless legend reskin

758 vues

Publié le

Présentation du système d’instancing dans endless legend reskin lors du 10e meetup Unity3D le 17 mars 2015
http://www.meetup.com/Paris-Unity/events/220950443/

Publié dans : Logiciels
0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
758
Sur SlideShare
0
Issues des intégrations
0
Intégrations
2
Actions
Partages
0
Téléchargements
8
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

[Paris Unity3D meetup] - Système d’instancing dans endless legend reskin

  1. 1. SYSTÈME D’INSTANCING
  2. 2. TIMOTHÉE RAULIN
  3. 3. PLAN PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
  4. 4. PROBLÈME
  5. 5. Situation  Nombre d’objets à l’écran  Nombre d’objets dans le monde  Temps de « fabrication » du contenu d’une zone  Mémoire nécessaire pour stocker le contenu d’une zone Objectifs  Performance CPU/GPU  Mémoire CPU/GPU  Temps réel PROBLÈME
  6. 6.  En moyenne 10 000 draw call dès qu’on dezoom  Batching dynamique …  Mauvais frame rate (CPU bound) mais régulier  Éditeur friendly UNITY. DE BASE
  7. 7.  Lent  Mémoire gigantesque  Très lent en fait!  Bon frame rate mais grosse saccade + out of memory  Pas éditeur friendly UNITY.COMBINEMESH
  8. 8. PLAN PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
  9. 9.  Encodage dans une texture  Décodage au vertex-shader  Implémentation  Performance  Mémoire SOLUTION UTILISÉE
  10. 10.  1 pixel = 4 * 8 bits ou 2 * 16 bits  2 * 8 bits = 16 bits => 65536 • 1 => 255 (8 bits) ou 65535 (16 bits)  Encodage d’un objet avec 3 pixels: • 3 * 16 bits => x, y, z ( 1 + ½ pixels) • 2 * 16 bits => Orientation + scale 2d (xz ) (1 pixel) • 1 * 16 bits => scale Y (½ pixel )  D’autres encodages possibles (plus de pixels & bits) ENCODAGE | DÉCODAGE
  11. 11. int valueIn0_1_8bit = System.Math.Max(0, System.Math.Min(255, (int)(valueIn01 * 255.0f))); UnityEngine.Color32 color = new UnityEngine.Color32((byte)valueIn0_1_8bit, …, … ,… ); int valueIn0_1_16bit = (int)System.Math.Max(0, System.Math.Min(65535, (int)(valueIn01 * 65535.0f))); int lowBits = 255; int highBits = 255 << 8; UnityEngine.Color32 color = new UnityEngine.Color32((byte)(valueIn0_1_16bit & lowBits), ((byte)((valueIn0_1_16bit & highBits) >> 8), …, …) float4 texContent = tex2Dlod(_EncodedContentTexture, texCoord); float valueIn0_1 = texContent.x; float valueIn0_255 = 255 * texContent.x; //on récupère exactement la valeur valueIn0_1_8bit float4 texContent = tex2Dlod(_EncodedContentTexture, texCoord); float valueIn0_65535 = texContent.x * 255 + texContent.y * 255 * 256; //on récupère exactement la valeur valueIn0_1_16bit float valueIn0_1 = valueIn0_65535 / 65535; FORMULES  Encoder en 8 bits - un float entre 0 et 1  Encoder en 16 bits  Décoder en 8 bits  Décoder en 16 bits
  12. 12.  Strip de mesh : Pour chaque mesh de chaque type de décors, on prépare un mesh qui est une répétition de copie de ce mesh. Dans le strip de mesh, on ajoute la composante couleur où l’on encode l’index de la copie dans la série  On encode l’affichage d’un groupe d’objet de même type en une bande de pixel  On transmet au vertex-shader l’endroit où il faut commencer à lire et le nombre d’objet qu’il faut décoder tree tree4tree0 tree1 tree2 tree3 tree4 tree5 tree6 DÉCODAGE AU VERTEX-SHADER
  13. 13.  On utilise la version de UnityEngine.Graphics.DrawMesh avec 9 paramètres dont un MaterialPropertyBlock  MaterialPropertyBlock : contiendra ce qui change par DrawMesh : le _StartUV, le MeshCount, la bounding box, etc…  UnityEngine.Shader.SetGlobalXXX : pour ce qui ne change pas par draw, en particulier la texture de contrôle IMPLÉMENTATION 1/2
  14. 14. X lo X hi Y lo Y hi Z lo Z hi Fx lo Fx hi Fz lo Fz hi Up lo Up hi X lo X hiUp lo Up hi Instance 0 Instance 1 Instance 2 Instance 3 Instance 4 Shader parameters _ControlTex _StartUV _ObjectCount float instanceIndex = 255 * vertex.color.x; int pixelCountPerInstance = 3; float2 baseTexCoord = _StartUV.xy + float2(_ControlTex_TexelSize.x * (pixelCountPerInstance * instanceIndex), 0) + _ControlTex_TexelSize.xy * 0.5f; float4 controlValue0 = tex2Dlod (_ControlTex, float4(baseTexCoord, 0, 0)); float4 controlValue1 = tex2Dlod (_ControlTex, float4(baseTexCoord + float2(_ControlTex_TexelSize.x, 0), 0, 0)); float4 controlValue2 = tex2Dlod (_ControlTex, float4(baseTexCoord + float2(2 * _ControlTex_TexelSize.x, 0), 0, 0)); float valueX01 = (controlValue0.x * 255 + controlValue0.y * 255 * 256) / 65535; (…) float3 pos = lerp(_MinBBox.xyz, _MaxBBox.xyz, float3(valueX01, valueY01, valueZ01)); (…) float visible = step(colorIndex, _ObjectCount – 0.5); controlValue0 controlValue1 controlValue2 _ControlTex … … … Zoom +
  15. 15.  A partir d’un ensemble de groupe d’objets disparates, on fabrique un ensemble de groupe d’objets de même type  On les encode dans la texture de contrôle  On envoie les commandes de rendu avec DrawMesh IMPLÉMENTATION 2/2
  16. 16.  La consultation de la texture au vertex-shader est gratuite! • Il faut être GPU bound pour le voir • Il faut vraiment beaucoup de vertex alors que généralement le coût principal vient des pixels • Même dans ce cas là, on a seulement quelques % de différence  Remplir une texture sans mip-map à partir d’un tableau de color32, n’est pas très cher PERFORMANCES
  17. 17.  Ca pique!! Chaque type d’objet est répliqué, parfois plusieurs centaines de fois  En cause certaines limitations de Unity  Ajuster la taille des strips de mesh  Optimiser le layout mémoire • Encoder la normale dans la couleur • Encoder la tangeante dans la normale MÉMOIRE
  18. 18.  Pour le debug et la mise au point, pouvoir switcher entre « Unity pur » et « instancing », le premier définissant la référence  Nécessite une autre manière de regrouper les meshs pour certains éléments  Animation : manipuler quelques pixels pour bouger un objet DIVERS
  19. 19. TA TA TATATA * *AIR CONNU
  20. 20. PLAN PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
  21. 21.  Nombre de draw call réduit  Temps de régénération et coût de stockage d’une zone réduit  Zéro alloc ou presque en réutilisant les buffers de stockage  Empreinte mémoire importante à t=0 mais quasi constante par la suite  Animation de certains éléments facilitée  Nécessite une certaine infrastructure et un certain investissement pour la mise au point RÉSULTATS
  22. 22. PLAN PROBLÈME SOLUTION RÉSULTATS PLUS LOIN
  23. 23.  Travailler avec des valeurs entières permet d’avoir des indices et donc des tableaux d’objets consultables  Il n’est pas prohibitif de faire au pixel shader ce genre d’opération  On peut produire le contenu de texture d’encodage à partir d’un rendu et donc animer au GPU PLUS LOIN
  24. 24. traulin@amplitude-studios.com MERCI

×