我正在尝试优化以下代码,因为多次循环以获得纹理的每个像素非常耗时!
我有3个纹理,在别处生成需要合并然后保存到磁盘。
我尝试过使用SetPixels和GetPixels,但这并不是特别有用,因为多次使用它只是替换整个纹理而不是仅替换非透明像素。以下是我到目前为止的功能:
public void savePNG()
{
stationWidth = PlayerPrefs.GetInt("Station Width");
stationHeight = PlayerPrefs.GetInt("Station Height");
Debug.Log(stationWidth + ", " + stationHeight);
Texture2D spaceStation = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
spaceStation = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
Color Test;
floorTex = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
wallTex = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
roomTex = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
floorTex.LoadImage(File.ReadAllBytes(Application.dataPath + "/../floorTexture.png"), false);
wallTex.LoadImage(File.ReadAllBytes(Application.dataPath + "/../wallTexture.png"), false);
roomTex.LoadImage(File.ReadAllBytes(Application.dataPath + "/../roomTexture.png"), false);
for(int row = 0; row < stationWidth*256; row ++)
{
for(int col = 0; col < stationHeight*256; col ++)
{
Test = floorTex.GetPixel(row,col);
if(Test.a != 0.0f)
{
spaceStation.SetPixel(row, col, floorTex.GetPixel(row,col));
}
else
{
spaceStation.SetPixel(row, col, Color.white);
}
Test = wallTex.GetPixel(row,col);
if(Test.a != 0.0f)
{
spaceStation.SetPixel(row, col, wallTex.GetPixel(row,col));
}
Test = roomTex.GetPixel(row,col);
if(Test.a != 0.0f)
{
spaceStation.SetPixel(row, col, roomTex.GetPixel(row,col));
}
}
}
spaceStation.Apply();
byte[] bytes = spaceStation.EncodeToPNG();
File.WriteAllBytes(Application.dataPath + "/../SpaceStation.png", bytes);
}
我不确定从哪里开始,任何想法或建议都将不胜感激!
其他
我尝试的GetPixels和SetPixels代码看起来像这样:
spaceStation.SetPixels(floorTex.GetPixels(0, 0, stationWidth*256, stationHeight*256));
spaceStation.SetPixels(wallTex.GetPixels(0 ,0, stationWidth*256, stationHeight*256));
spaceStation.SetPixels(roomTex.GetPixels(0, 0, stationWidth*256, stationHeight*256));
每个SetPixels完全覆盖了之前的那些,我希望透明像素根本不会覆盖任何像素,所以细节会通过
显示答案 0 :(得分:1)
我使用的是颜色数组,而不是单独设置每个像素,只需调用GetPixels 3次,SetPixels调用一次。功能现在快了大约80%,这是相当不错的全面。我被告知使用Graphics.Blit
和着色器可以获得更好的结果,但我真的对着色器一无所知,所以我现在不打算采用这种方法。以下是代码现在的样子:
public void savePNG()
{
stationWidth = PlayerPrefs.GetInt("Station Width");
stationHeight = PlayerPrefs.GetInt("Station Height");
Texture2D spaceStation = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
spaceStation = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
Color[] mainArray = new Color[(stationWidth*256)*(stationHeight*256)];
Color[] wallArray = new Color[(stationWidth*256)*(stationHeight*256)];
Color[] roomArray = new Color[(stationWidth*256)*(stationHeight*256)];
floorTex = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
wallTex = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
roomTex = new Texture2D(stationWidth*256, stationHeight*256, TextureFormat.ARGB32, false);
floorTex.LoadImage(File.ReadAllBytes(Application.dataPath + "/../floorTexture.png"), false);
wallTex.LoadImage(File.ReadAllBytes(Application.dataPath + "/../wallTexture.png"), false);
roomTex.LoadImage(File.ReadAllBytes(Application.dataPath + "/../roomTexture.png"), false);
mainArray = floorTex.GetPixels(0,0,stationWidth*256, stationHeight*256);
wallArray = wallTex.GetPixels(0,0,stationWidth*256, stationHeight*256);
roomArray = roomTex.GetPixels(0,0,stationWidth*256, stationHeight*256);
for(int i = 0; i < mainArray.Length; i++)
{
if(wallArray[i].a != 0.0f)
{
mainArray[i] = wallArray[i];
}
if(roomArray[i].a != 0.0f)
{
mainArray[i] = roomArray[i];
}
}
spaceStation.SetPixels(mainArray);
spaceStation.Apply();
byte[] bytes = spaceStation.EncodeToPNG();
File.WriteAllBytes(Application.dataPath + "/../SpaceStation.png", bytes);
}
答案 1 :(得分:-1)
我真的不知道Texture2D对象的(get / set)Pixel方法的性能。但在.NET世界中,我们更喜欢System.Drawing.Bitmap对象和System.Drawing.Imaging.BitmapData类以及BitmapData的Scan0属性来快速访问像素值。
在SO中已经有一个漂亮的answer来证明其用法。