You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity编辑器全景纹理拼接性能优化问询:批量PNG格式全景图生成提速方案

优化Unity编辑器中纹理全景拼接的性能方案

我明白你现在在Unity编辑器里批量拼接纹理成全景图时遇到了头疼的性能问题——要处理上千个关卡,每个关卡3-5张图,原来的逐像素循环直接把编辑器卡得动弹不得。你已经通过批量获取像素、单次SetPixels把性能提升了一倍,但显然还需要更快的方案对吧?

更高效的实现方案

下面是比你当前优化版本更快的实现,主要针对内存拷贝效率和减少不必要的LINQ开销做了优化:

byte[] MergeTexturesToBytes(List<Texture2D> textures)
{
    if (textures == null || textures.Count == 0) return null;

    int singleWidth = textures[0].width;
    int totalWidth = singleWidth * textures.Count;
    int height = textures[0].height;

    // 使用Color32而非Color,内存占用仅为Color的1/4(每个像素4字节 vs 16字节)
    Texture2D result = new Texture2D(totalWidth, height, TextureFormat.RGBA32, false);
    Color32[] resultPixels = new Color32[totalWidth * height];

    for (int y = 0; y < height; y++)
    {
        int rowStartInResult = y * totalWidth;
        int rowStartInSingle = y * singleWidth;

        for (int t = 0; t < textures.Count; t++)
        {
            Color32[] texPixels = textures[t].GetPixels32();
            // 直接使用Array.Copy进行内存块拷贝,比LINQ的Skip/Take快得多
            Array.Copy(texPixels, rowStartInSingle, 
                      resultPixels, rowStartInResult + t * singleWidth, 
                      singleWidth);
        }
    }

    result.SetPixels32(resultPixels);
    result.Apply();
    byte[] pngBytes = result.EncodeToPNG();
    
    // 编辑器中记得手动释放Texture2D资源,避免内存泄漏
    UnityEngine.Object.DestroyImmediate(result);
    
    return pngBytes;
}

关键优化点解析

  • 改用Color32数组:Color是由四个float组成的结构体,每个像素占16字节;而Color32是四个byte组成,每个像素仅4字节。内存占用减少75%,拷贝速度自然更快,同时GetPixels32/SetPixels32的底层实现也比GetPixels/SetPixels更高效。
  • 替换LINQ为Array.Copy:你的当前优化版本用了Skip(offset).Take(width),LINQ方法会产生额外的枚举器和临时对象,不仅增加GC,还降低了拷贝效率。Array.Copy是底层的内存块拷贝操作,性能远高于LINQ。
  • 提前计算索引偏移:把行起始索引、纹理偏移这些值提前计算好,避免在循环内重复计算,减少CPU的计算开销。
  • 手动释放资源:在编辑器环境下,创建的Texture2D不会自动回收,所以最后用DestroyImmediate手动销毁,避免长期运行后出现内存泄漏。

额外的编辑器级优化建议

如果要处理上千个关卡,还可以做这些优化:

  • 分批次处理:不要一次性处理所有关卡,每次处理10-20个关卡后调用EditorUtility.UnloadUnusedAssets(),并让编辑器有时间响应事件,避免完全卡死。
  • 使用多线程:在Unity编辑器中,可以利用Task.Run把纹理拼接的逻辑放到后台线程(注意:Unity的Texture2D对象操作不能在后台线程做,但GetPixels32返回的数组是可以在后台处理的——你可以先批量把所有纹理的像素数据读取到数组,再在后台拼接,最后回到主线程创建Texture2D并保存)。
  • 避免重复创建Texture2D:如果所有关卡的纹理分辨率相同,可以复用同一个结果Texture2D,不用每次都创建新的对象。

内容的提问来源于stack exchange,提问作者fafase

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:32:41