【问题标题】:How to improve the performance of loading textures?如何提高加载纹理的性能?
【发布时间】:2017-03-26 21:52:40
【问题描述】:

我目前正在为我的游戏项目寻找性​​能优化。我初始化过程的瓶颈是加载模型的纹理。加载和分配大型纹理最多需要 100 毫秒。这是一个问题,因为我有很多。我分析了我的代码,发现大部分时间(大约 96%)都花在了 CopyPixels 的调用上(见下文)。

我在下面附加了用于导入所有纹理的功能。这个函数就像一个魅力,基于官方的 SharpDX-samples-master 示例代码。首先,我从自定义文件格式加载图像字节(大纹理大约需要 2 毫秒)。然后,我创建格式转换器并使用它将像素复制到数据流中。但是,复制像素非常慢。

有没有更快的方法来达到同样的效果?

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;
}

【问题讨论】:

  • 看起来您正在使用位图。您是否考虑过使用 DDS 文件?它支持压缩和未压缩格式
  • 我的纹理都是PNG文件。在我的内容管道中,我将所有数据(模型几何、纹理、动画等)打包到资源包中,并在需要时在运行时加载它们。所以,我存储了 PNG 文件的字节,并使用上面的函数处理它们。您认为另一种源文件格式会更好吗?
  • 好吧,我会试一试。我们使用压缩 (DXT5) DDS 文件进行纹理处理。此外,DDS 文件也支持 mipmaps

标签: c# directx textures directx-11 sharpdx


【解决方案1】:

看起来您正在使用位图。您是否考虑过使用 DDS 文件?它同时支持压缩和未压缩格式 – Asesh

阿塞什是对的。起初,我持怀疑态度,但我做了一些研究,发现一篇较早的文章指出,平均 PNG 纹理在硬盘驱动器上占用的内存少于可比较的 DDS 纹理。但是,PNG 纹理需要在运行时进行转换,这比使用 DDS 纹理要慢。

昨晚我一直在寻找合适的转换工具,在测试了一些东西(例如 GIMP 插件)后,我使用 AMD 的 Compressonator 将我所有的 PNG 纹理转换为 DDS 纹理。与 PNG 文件相比,新文件在我的硬盘驱动器上占用的内存更少(1.7 GB 而不是 2.1 GB)。

我在最初的帖子中介绍的纹理加载方法仍然有效并且速度稍快。但是,我决定根据我在网上找到的几个代码示例编写一个 DDS 导入器。

结果:导入大型纹理只需 1 毫秒而不是 103 毫秒。我认为你可以改进。 :-D

非常感谢,阿塞什!

【讨论】:

  • 很高兴我能给你建议:)
  • 你能分享一下 DDS 进口商代码吗?我能找到的唯一参考代码是 SharpDx.Toolkit.Graphics 中现已废弃的代码。
猜你喜欢
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多