This is a problem for you math wizards that I have been stumped on for a while even though I feel like I should be able to solve it.
What I am doing : I am taking an image, or rather, float[,] values from an image and putting them into an array. From that array I am “upressing” the values so that the range of values turns into a larger pool. From there I am dividing it up into chunks. This is for terrain generation.
So for this example.
- N = 512 (the original input
dimensions. 512*512) - Up = 5 (the upres amount)
- Cs = 512 (The chunk dimensions.
512*512) - Ms = N * Up (The total dimensions of
the upresed array. 2560*2560) - Gs = Ms/Cs (The grid dimensions. 5*5
chunks)
Currently I am upresing the entire thing all at once. What I want to be able to do is upress only the necessary areas. As you can imagine, upressing a 512512 image 50 times (2560025600) would take a while to process a lot of unnecessary data…especially when its going to be representing terrain that the player wont be near.
Where I fail: I need to be able to access the specific values that are getting upresed into the chunk dimensions (512x512) from the original input (N) and upres only those. I cant have float values and I cant be rounding. The values exist and are being upressed, I just cant think of a way to reverse this process.
Conclusion: I want to collect only the necessary values from the original input and pass those to be upresed instead of unpresing the entire original input array.
Here is the code I am currently working with.
float[,] originalInput; // an array containing the original values, im using 512*512 (N)
int upres = 5; // how many times the original values are upres (Up)
originalInput = UpresHeights(originalInput, upres); //upres the input
int mapsize = originalInput.GetLength(0); // (Ms)
int chunkSize = 512; //(Cs)
int gridSize = (int)Mathf.Round((mapsize / (float)chunkSize)); //Grid size (Gs)
float[,] UpresHeights(float[,] oldHeights, int upres)
{
//Duplicate the array input array
int originalHeight = oldHeights.GetLength(0);
float[,] heights = new float[originalHeight, originalHeight];
for (int y = 0; y < originalHeight; y++)
{
for (int x = 0; x < originalHeight; x++)
{
float val = oldHeights[x, y];
heights[x, y] = val;
}
}
//Upres the new array
int heightsLength = originalHeight;
int resolution = (heightsLength * upres);
float[,] newHeights = new float[resolution, resolution];
for (int y = 0; y < originalHeight; y++)
{
for (int x = 0; x < originalHeight; x++)
{
//The original input is tileable, so the following
//just makes sure to sample from the opposite side
//of the array if at the border
float right = 0.0f;
if (x == originalHeight - 1)
{
right = heights[0, y];
}
else {
right = heights[x + 1, y];
}
float top = 0.0f;
if (y == originalHeight - 1)
{
top = heights[x, 0];
}
else {
top = heights[x, y + 1];
}
for (int xx = 0; xx < upres; xx++)
{
for (int yy = 0; yy < upres; yy++)
{
//smooth the values (could use vector2.distance,
//but this isnt important right now)
//not that important since blur is applied later
float a = Mathf.Lerp(heights[x, y], right, (xx / (float)upres));
float b = Mathf.Lerp(heights[x, y], top, (yy / (float)upres));
newHeights[x * upres + xx, y * upres + yy] = (a + b) / 2f;
}
}
}
}
return newHeights;
}