C# 嵌入用于降水贴图的循环,Unity3d游戏引擎中的柏林噪波问题
我正在为柏林噪声实验制作一张降水图,在那里我还创建了生物群落 我用温度和降水量来确定某个像素的生物群落,我有降水量的程序,但是程序中的多个循环使得Unity3d在很长一段时间内没有反应 有人知道如何加快速度吗?我在网上到处找了找,但找不到答案 这是我的密码:C# 嵌入用于降水贴图的循环,Unity3d游戏引擎中的柏林噪波问题,c#,unity3d,game-development,C#,Unity3d,Game Development,我正在为柏林噪声实验制作一张降水图,在那里我还创建了生物群落 我用温度和降水量来确定某个像素的生物群落,我有降水量的程序,但是程序中的多个循环使得Unity3d在很长一段时间内没有反应 有人知道如何加快速度吗?我在网上到处找了找,但找不到答案 这是我的密码: public float[,] PrecipMap (float[,] noise,int mapWidth,int mapHeight) { float[,] precipMap = new float[mapWidth, map
public float[,] PrecipMap (float[,] noise,int mapWidth,int mapHeight)
{
float[,] precipMap = new float[mapWidth, mapHeight];//array that it to be used for precipitation
float[,] waterTiles = WaterTiles(mapHeight, mapWidth, noise);//array with all values that are water
for (int y = 0; y < mapHeight; y++)
{
for(int x = 0; x < mapWidth; x++)
{
float[] distance = new float[count];//distance between pixel and water tile
for(int wy = 0; wy < mapHeight; wy++)
{
for(int wx = 0; wx < mapWidth; wx++)
{
if (waterTiles[x, y] == 1) { // if the selected tile in water tiles has water
for(int i = 0; i < count; i++)// distance makes an array of all possible distances.
{
distance[i] = Mathf.Sqrt(((x + -wx) * (x + -wx)) + ((y +-wy) * (y +-wy)));// finds distance between pixel and water tile
}
}
}
Array.Sort(distance); /// sorts distance from least to greatest
precipMap[x, y] = distance[count-1];//enters in distance
}
}
}
return precipMap;
}
public float[,]PrecipMap(float[,]noise,int-mapWidth,int-mapHeight)
{
float[,]precipMap=new float[mapWidth,mapHeight];//用于降水的数组
float[,]waterTiles=waterTiles(贴图高度、贴图宽度、噪波);//包含所有为水的值的数组
对于(int y=0;y
如果有人能帮忙,我将不胜感激。我非常感谢您的帮助/批评。如前所述,您的循环经常运行,默认情况下unity中的所有内容都在主线程上运行。因此,在Unity渲染下一帧之前,必须完成该方法 此外,您还可以运行
Array.Sort
,这非常昂贵,并为每次迭代分配新的数组,这也会让您的GC保持忙碌
那么我看不出你的距离数组有什么好处。变量i
从未在yoir计算中使用,因此您只需使用相同的值填充所有1500个条目,对其进行排序并读取最后一个。。。他们都是平等的,所以这是完全多余的
你也会重复检查
if (waterTiles[x, y] == 1)
只要你有x
和y
就可以检查一次,并且在嵌套循环中不必要地进一步检查,如果条件为false,你可以完全跳过这些循环
实际上,您可以将整个方法移动到一个线程,并使用(另请参阅)等待结果。不幸的是,我不是asyncwait
专家,但这应该可以做到
public async void CalculatePrecipMap(float[,] noise, int mapWidth, int mapHeight, Action<float[,]> callback)
{
var result = await PrecipMap(noise, mapWidth, mapHeight);
callback?.Invoke(result);
}
private async Task<float[,]> PrecipMap (float[,] noise,int mapWidth,int mapHeight)
{
//array that it to be used for precipitation
float[,] precipMap = new float[mapWidth, mapHeight];
//array with all values that are water
float[,] waterTiles = WaterTiles(mapHeight, mapWidth, noise);
for (var y = 0; y < mapHeight; y++)
{
for(var x = 0; x < mapWidth; x++)
{
// Skip as soon as possible
// Completely unnecessary to run your loop at all if this is already false
if (waterTiles[x, y] != 1) continue;
// if the selected tile in water tiles has water
for(var wy = 0; wy < mapHeight; wy++)
{
for(var wx = 0; wx < mapWidth; wx++)
{
// i is nowhere used in below calculation!
// I don't see any reason to use an distance array here at all !!!
precipMap[x, y] = Mathf.Sqrt(((x + -wx) * (x + -wx)) + ((y +-wy) * (y +-wy)));
}
}
}
}
return precipMap;
}
或者使用类似的方法
CalculatePrecipMap(someNoise, someWidth, someHeight, OnResultReady);
private void OnResultReady (float[,] result)
{
// Do something with the result
}
注意:在智能手机上输入,但我希望想法变得清晰你的地图有多大?例如,mapWidth
和mapHeight
中插入了哪些值?目前,宽度和高度都是75,嵌套循环加起来非常快,特别是当您超出单个嵌套循环时。为了更全面地了解情况,在本例中,当您要求程序循环75^3*count
次时,请运行PrecipMap
函数一次,这可能是数百万次,具体取决于count-421875*count
的值。考虑大幅减少输入的大小和/或采取另一种方法,需要更少的嵌套循环。您要重新计算和覆盖<代码> ReXPMAP[X,y] 每一个代码> Wy 迭代,并且同时排序<代码>距离< /代码>。这是不必要的。考虑将其移动到包含循环中。除非绝对必要,否则不要在嵌套循环中分配新数组。(在本例中,它不是。)垃圾收集进入overdrive并杀死perf.Woah我不知道Unity必须在一个帧中完成这一切。我也不知道我能有这样的方法。非常感谢。
CalculatePrecipMap(someNoise, someWidth, someHeight, OnResultReady);
private void OnResultReady (float[,] result)
{
// Do something with the result
}