C# 如何提高加载纹理的性能?

C# 如何提高加载纹理的性能?,c#,directx,textures,directx-11,sharpdx,C#,Directx,Textures,Directx 11,Sharpdx,我目前正在为我的游戏项目寻找性能优化。初始化过程的瓶颈是加载模型的纹理。加载和指定大纹理最多需要100毫秒。这是个问题,因为我有很多。我分析了我的代码,发现大部分时间(约96%)都花在调用CopyPixels上(见下文) 我附加了用于导入下面所有纹理的函数。此函数的工作原理类似于一个符咒,它基于官方的SharpDX示例主示例代码。首先,我从我的自定义文件格式加载图像字节(大纹理大约需要2毫秒)。然后,我创建了格式转换器,并使用它将像素复制到数据流中。但是,复制像素的速度非常慢 有没有更快的方法实

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

我附加了用于导入下面所有纹理的函数。此函数的工作原理类似于一个符咒,它基于官方的SharpDX示例主示例代码。首先,我从我的自定义文件格式加载图像字节(大纹理大约需要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文件吗?它支持压缩和未压缩格式–Asesh

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

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

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

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


非常感谢你,阿塞什

看起来您正在使用位图。您考虑过使用DDS文件吗?它支持压缩和未压缩格式。我的纹理都是PNG文件。在我的内容管道中,我将所有数据(模型几何体、纹理、动画等)打包到资源包中,并在需要时在运行时加载它们。因此,我存储PNG文件的字节,并使用上面的函数处理它们。你认为另一种源文件格式会更好吗?嗯,我会试试。我们使用压缩(DXT5)DDS文件进行纹理处理。此外,DDS文件支持mipmaps,我很高兴能给你一些建议:)你能分享DDS导入器代码吗?我能找到的唯一参考代码是SharpDx.Toolkit.Graphics中现在废弃的代码。