2017-03-23 7 views
1

Je suis actuellement à la recherche d'optimisations de performances pour mon projet de jeu. Le goulot d'étranglement de mon processus d'initialisation est le chargement des textures de mes modèles. Le chargement et l'attribution d'une grande texture prennent jusqu'à 100ms. C'est un problème, parce que j'en ai beaucoup. J'ai analysé mon code et j'ai découvert que la plupart du temps (environ 96%) est passé à l'appel de CopyPixels (voir ci-dessous).Comment améliorer les performances de chargement des textures?

J'ai attaché la fonction que j'utilise pour importer toutes mes textures ci-dessous. Cette fonction fonctionne comme un charme et est basée sur les codes d'exemple officiels SharpDX-samples-master. Tout d'abord, je charge les octets image de mon format de fichier personnalisé (qui prend environ 2 ms pour les grandes textures). Ensuite, je crée le convertisseur de format et l'utilise pour copier les pixels dans le flux de données. Cependant, la copie des pixels est très lente.

Existe-t-il un moyen plus rapide d'atteindre la même chose?

public static Resources.Texture ImportTexture(Resources.AResourceManager resourceManager, string resourcePackFileName, int bytePosition, out string resourceItemName) 
{ 
    // Load image bytes from file. 
    FileReader fileReader = new FileReader(); 
    DataTypes.Content.ResourceItem resourceItem = fileReader.ImportTextureFromCollection(resourcePackFileName, bytePosition); 
    resourceItemName = resourceItem.Name; 

    // Create texture. 
    Resources.Texture tex = null; 
    using (SharpDX.WIC.BitmapDecoder bitmapDecoder = new SharpDX.WIC.BitmapDecoder(resourceManager.ImagingFactory, new MemoryStream(resourceItem.Data, false), SharpDX.WIC.DecodeOptions.CacheOnDemand)) 
    { 
     using (SharpDX.WIC.FormatConverter formatConverter = new SharpDX.WIC.FormatConverter(resourceManager.ImagingFactory)) 
     { 
      formatConverter.Initialize(bitmapDecoder.GetFrame(0), SharpDX.WIC.PixelFormat.Format32bppPRGBA, SharpDX.WIC.BitmapDitherType.None, null, 0.0, SharpDX.WIC.BitmapPaletteType.Custom); 

      SharpDX.DataStream dataStream = new SharpDX.DataStream(formatConverter.Size.Height * formatConverter.Size.Width * 4, true, true); 

      // This takes most of the time! 
      formatConverter.CopyPixels(formatConverter.Size.Width * 4, dataStream); 

      // Creating texture data structure. 
      tex = new Resources.Texture(formatConverter.Size.Width, formatConverter.Size.Height, formatConverter.Size.Width * 4) 
      { 
       DataStream = dataStream 
      }; 
     } 
    } 

    return tex; 
} 
+0

On dirait que vous utilisez des bitmaps. Avez-vous envisagé d'utiliser des fichiers DDS à la place? Il prend en charge les formats compressés et non compressés. – Asesh

+0

Mes textures sont toutes des fichiers PNG. Dans mon pipeline de contenu, j'emballe toutes les données (géométrie du modèle, textures, animations, etc.) dans des packs de ressources et les charge au moment de l'exécution quand j'en ai besoin. Donc, je stocke les octets des fichiers PNG et les traite avec la fonction ci-dessus. Pensez-vous qu'un autre format de fichier source serait mieux? – Endgegner85

+0

Eh bien, je voudrais essayer. Nous utilisons des fichiers DDS compressés (DXT5) pour la texturation. En outre, les fichiers DDS supportent aussi les mipmaps – Asesh

Répondre

1

On dirait que vous utilisez bitmaps. Avez-vous envisagé d'utiliser des fichiers DDS à la place? Il prend en charge les formats compressés et non compressés - Asesh

Asesh avait raison. Au début, j'étais sceptique, mais j'ai fait quelques recherches et trouvé un article plus ancien qui stipule qu'une texture PNG moyenne prend moins de mémoire sur le disque dur qu'une texture DDS comparable. Cependant, les textures PNG doivent être converties à l'exécution, ce qui est plus lent que l'utilisation de textures DDS. J'ai passé la nuit dernière à chercher des outils de conversion appropriés et après avoir testé quelques trucs (comme un plug-in pour GIMP), j'ai utilisé le Compressonator d'AMD pour convertir toutes mes textures PNG en textures DDS. Les nouveaux fichiers prennent même moins de mémoire sur mon disque dur que les fichiers PNG (1,7 Go au lieu de 2,1 Go).

Ma méthode de chargement de texture que je présentais dans la publication initiale fonctionnait encore et était légèrement plus rapide. Cependant, j'ai décidé de coder un importateur DDS basé sur plusieurs échantillons de code que j'ai trouvés en ligne. Le résultat: Une grande texture ne prend que 1 ms au lieu de 103 ms à importer. Je pense que vous pouvez améliorer cela. :-D

Merci beaucoup, Asesh!

+0

Heureux de pouvoir vous donner des suggestions :) – Asesh

+0

Pouvez-vous partager le code d'importateur DDS? Le seul code de référence que j'ai pu trouver est le code maintenant abandonné dans SharpDx.Toolkit.Graphics. – NathanAldenSr