在运行时合并纹理

时间:2015-01-29 06:43:23

标签: unity3d textures

有没有办法"烘烤"一个纹理到另一个,除了使用SetPixels()? 现在我试图使用类似的东西,但它太慢了:

public static Texture2D CombineTextures(Texture2D aBaseTexture, Texture2D aToCopyTexture, int x, int y)
{
    int aWidth = aBaseTexture.width;
    int aHeight = aBaseTexture.height;

    int bWidth = aToCopyTexture.width;
    int bHeight = aToCopyTexture.height;

    Texture2D aReturnTexture = new Texture2D(aWidth, aHeight, TextureFormat.RGBA32, false);

    Color[] aBaseTexturePixels = aBaseTexture.GetPixels();
    Color[] aCopyTexturePixels = aToCopyTexture.GetPixels();

    int aPixelLength = aBaseTexturePixels.Length;
    for(int y1 = y, y2 = 0; y1 < aHeight && y2 < bHeight ; y1++, y2++)
    {
        for(int x1 = x, x2 = 0 ; x1 < aWidth && x2 < bWidth; x1++, x2++)
        {
            aBaseTexturePixels[x1 + y1*aWidth] = Color.Lerp(aBaseTexturePixels[x1 + y1*aWidth], aCopyTexturePixels[x2 + y2*bWidth], aCopyTexturePixels[x2 + y2*bWidth].a);
        }
    }

    aReturnTexture.SetPixels(aBaseTexturePixels);
    aReturnTexture.Apply(false);

    return aReturnTexture;
}

问题是,我需要在2d表面(血液,敌人的尸体等)上显示很多精灵,并且只是实例化每个精灵会大大降低fps。

1 个答案:

答案 0 :(得分:0)

如果您在实例化预制件时担心fps掉落,那么您肯定应该构建一个对象池系统。所以你将拥有一个系统:

  1. 实例化池中的所有对象并使其远离主摄像机
  2. 一旦您需要该对象,您将从池中“借用”它
  3. 一旦不再需要对象,您将把它返回到对象池(例如当精灵在摄像机视图外时
  4. 将它全部烘焙到一个纹理不是最好的做法。你需要大量的RAM才能做到这一点。考虑上面的步骤,这是非常常见的做法

    这里的好例子:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System;
    using System.Linq;
    
    public class BackgroundPool : MonoBehaviour 
    {
        public static BackgroundPool instance;
        public List<BackgroundSection> sectionsLibrary = new List<BackgroundSection>();
        public int poolSize = 4;
        public List<BackgroundSection> pool = new List<BackgroundSection>();
    
    
        void Awake()
        {
            instance = this;
    
            DateTime startGenTime = DateTime.Now;
    
            //generateSectionsPool
            for (int i=0; i<sectionsLibrary.Count; i++)
            {
                for (int j=0; j<poolSize; j++)
                {
                    if (j == 0) 
                    {
                        sectionsLibrary[i].positionInPool = sectionsLibrary[i].transform.position;
                        pool.Add(sectionsLibrary[i]);
                    }
                    else
                    {
                        BackgroundSection section = (BackgroundSection)Instantiate(sectionsLibrary[i]);
    
                        section.transform.parent = this.transform;
                        section.transform.position = new Vector3((-(ExtensionMethods.GetBounds(sectionsLibrary[i].gameObject).extents.x * 2) * j) + sectionsLibrary[i].transform.position.x,
                                                             sectionsLibrary[i].transform.position.y);
                        section.transform.localEulerAngles = Vector3.zero;
    
                        section.gameObject.name = sectionsLibrary[i].gameObject.name + ":" + j.ToString();
                        section.positionInPool = section.transform.position;
                        pool.Add(section);  
                    }
               }
            }
            Debug.Log("Background Pool generated in: " + (DateTime.Now - startGenTime).TotalSeconds.ToString() + " s");
        }
    
    
        public BackgroundSection GetPiece(Scenery scenery, SceneryLayer _layer)
        {
            List<BackgroundSection> allScenery = new List<BackgroundSection>();
            foreach (BackgroundSection section in pool) { if (section.scenery == scenery) allScenery.Add(section); }
    
            List<BackgroundSection> matchingPieces = new List<BackgroundSection>();
            foreach (BackgroundSection section in allScenery)  { if (section.sceneryLayer == _layer) matchingPieces.Add(section); }
    
            if (matchingPieces.Count > 0) 
            {
                BackgroundSection pickedSection = matchingPieces[UnityEngine.Random.Range(0,matchingPieces.Count-1)];
                pool.Remove(pickedSection);
                return pickedSection;
            }
            else
            {
                Debug.LogError("Cann't get background piece matching criteria, scenery: " + scenery + ", layer" + _layer);
                return null;
            }
        }
    
    
        public void ReturnPiece(BackgroundSection section)
        {
            pool.Add(section);
            section.transform.parent = this.transform;
            section.transform.position = section.positionInPool;
        }
    }