当前位置: 代码网 > it编程>软件设计>搜素引擎 > Unity性能优化 - 动态图集

Unity性能优化 - 动态图集

2024年08月06日 搜素引擎 我要评论
Unity 动态图集是 Unity 引擎中用于处理游戏纹理优化的一种技术。本文介绍了什么是动态图集,动态图集的优缺点,以及提供了一套完整的代码供大家参考。

一、什么是动态图集:

二、动态图集的优缺点:

 unity 动态图集的优点包括:

 unity 动态图集的缺点包括:

三、动态图集的实现方案:

本文不过多阐述关于动态图集的原理,直接上一个简单的demo来让大家来理解动态图集。

下面是动态图集的管理类:

using system.collections.generic;
using unityengine;

public class dynamicatlasmanager : monobehaviour
{
    public int atlassize = 2048;
    public textureformat textureformat = textureformat.rgba32;
    public bool usemipmaps = false;

    private static dynamicatlasmanager _instance;
    public static dynamicatlasmanager instance
    {
        get
        {
            if (_instance == null)
            {
                gameobject go = new gameobject("dynamicatlasmanager");
                _instance = go.addcomponent<dynamicatlasmanager>();
            }

            return _instance;
        }
    }

    private dictionary<string, texture2d> _atlasdictionary;
    private dictionary<string, rect> _spriterects;
    private dictionary<string, sprite> _originalspritescache;

    void awake()
    {
        _atlasdictionary = new dictionary<string, texture2d>();
        _spriterects = new dictionary<string, rect>();
        _originalspritescache = new dictionary<string, sprite>();
    }

    public void addspritestodynamicatlas(string atlasname, sprite[] sprites)
    {
        if (sprites == null || sprites.length == 0) return;

        texture2d atlas;
        if (_atlasdictionary.containskey(atlasname))
        {
            atlas = _atlasdictionary[atlasname];
        }
        else
        {
            atlas = new texture2d(atlassize, atlassize, textureformat, usemipmaps);
            atlas.filtermode = filtermode.bilinear;
            _atlasdictionary.add(atlasname, atlas);
        }

        for (int i = 0; i < sprites.length; i++)
        {
            if (!_originalspritescache.containskey(sprites[i].name))
            {
                _originalspritescache.add(sprites[i].name, sprites[i]);
            }
        }

        int xoffset = 0;
        int yoffset = 0;
        int maxheight = 0;

        for (int i = 0; i < sprites.length; i++)
        {
            sprite sprite = sprites[i];
            texture2d spritetexture = sprite.texture;

            if (xoffset + sprite.rect.width > atlas.width)
            {
                xoffset = 0;
                yoffset += maxheight;
                maxheight = 0;
            }

            // copy the texture using copytexture method
            graphics.copytexture(spritetexture, 0, 0, (int)sprite.rect.x, (int)sprite.rect.y, (int)sprite.rect.width, (int)sprite.rect.height, atlas, 0, 0, xoffset, yoffset);

            _spriterects[sprite.name] = new rect(xoffset, yoffset, sprite.rect.width, sprite.rect.height);

            xoffset += (int)sprite.rect.width;
            maxheight = mathf.max(maxheight, (int)sprite.rect.height);
        }
    }


    public sprite getspritefromdynamicatlas(string atlasname, string spritename)
    {
        if (!_atlasdictionary.containskey(atlasname) || !_spriterects.containskey(spritename))
        {
            return null;
        }

        texture2d atlas = _atlasdictionary[atlasname];
        rect spriterect = _spriterects[spritename];

        // get the original sprite
        if (!_originalspritescache.containskey(spritename))
        {
            return null;
        }

        sprite originalsprite = _originalspritescache[spritename];

        // calculate the border of the new sprite based on the original sprite's border
        vector4 border = originalsprite.border;

        // create the new sprite with the correct border
        return sprite.create(atlas, spriterect, new vector2(0.5f, 0.5f), originalsprite.pixelsperunit, 0, spritemeshtype.tight, border);
    }
}

 下面是动态图集的demo代码:

using unityengine;
using unityengine.ui;

public class dynamicatlasdemo : monobehaviour
{
    public sprite sprite1;
    public sprite sprite2;
    public sprite sprite3;
    public image image1;
    public image image2;
    public image image3;

    private dynamicatlasmanager _dynamicatlasmanager;

    void start()
    {
        _dynamicatlasmanager = dynamicatlasmanager.instance;

        // add sprites to the dynamic atlas
        _dynamicatlasmanager.addspritestodynamicatlas("demoatlas", new sprite[] { sprite1, sprite2, sprite3 });

        image1.sprite = _dynamicatlasmanager.getspritefromdynamicatlas("demoatlas", sprite1.name);
        image2.sprite = _dynamicatlasmanager.getspritefromdynamicatlas("demoatlas", sprite2.name);
        image3.sprite = _dynamicatlasmanager.getspritefromdynamicatlas("demoatlas", sprite3.name);
    }
}

优化前的draw call数量:5

优化后的draw call数量:3

 

 

备注:

上面的动态图集只是一个简单的方案,可以根据项目需求进行扩展和优化。

欢迎大家点赞评论关注三连,性能优化持续更新中。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com